February 22, 2019

Why supervisord does not log my PHP CLI fwrite(STDOUT, "message")?

Albert’s Question:

I have a PHP command line application ( zconsole awswebhookrunner ) run by supervisord.

Supervisord does not log on the files fwrite(STDOUT, "message") but it does log echo "message".

Supervisord config

[program:aws_webhook]
command=/home/(username)/bin/zconsole awswebhookrunner
process_name=%(program_name)s_%(process_num)02d
numprocs=1
directory=/tmp
priority=999
autostart=true
autorestart=true
startretries=100
stopwaitsecs=10
user=(username)
stdout_logfile=/home/(username)/logs/aws_webhook_runner.out.log
stderr_logfile=/home/(username)/logs/aws_webhook_runner.err.log
stdout_logfile_maxbytes=10MB

PHP Code

private function log($message, $type="info")
{
    $output=STDIN;
    switch ($type) {
        case "error":
            $output=STDERR;
            break;
        default:
            $output=STDIN;
    }
    $to_log=date("Y-m-d H:i:s")." ".$message;
    fwrite($output,$to_log.PHP_EOL) ;
    //echo $to_log.PHP_EOL;
    fflush($output);
    unset($to_log);
}

Software version

PHP version: 5.3.3
OS: CentOS 6.10
supervisord: 3.3.5

Questions

  1. Is my supervisord setup correct?
  2. Do I have a misunderstood the behavior of fwrite(STDOUT|STDERR, $message);?
  3. Why echo $message; works if it is sent to STDOUT?
  1. Configuration wise, I think it is fine. Command-wise, it’s a different question really.
  2. You are trying to STDIN rather than STDOUT. STDIN is used for input supervisord does not deal with STDIN I think.
  3. echo would print to STDOUT because it is its default behavior.
December 28, 2018

Your second implementation

$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);

Should work if you have the extension installed and properly configured. I would look into that if I were you.

You can check your PHP’s configuration using phpinfo() to check if the sodium is enabled.

And, If you haven’t installed, install using:

sudo pecl install -f libsodium
September 25, 2018

No matter how the data table is rendered, it still is a markup that is added dynamically to the DOM.

So, a delegated event listener like the following will work.

$("table").on('click', 'tr', function() {
    // Get the id somehow
    let id = 1;
    showDetails(id);
});
August 24, 2018

I encountered the same problem as well. I was installing a fixed version using chef and the problem was exactly as the OP has.

To solve it, I searched for the available packages

apt-cache madison docker-ce

It gave me an output like this

docker-ce | 18.06.1~ce~3-0~ubuntu | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
docker-ce | 18.06.0~ce~3-0~ubuntu | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
docker-ce | 18.03.1~ce~3-0~ubuntu | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
W: Target Packages (stable/binary-amd64/Packages) is configured multiple times in /etc/apt/sources.list.d/Docker.list:1 and /etc/apt/sources.list.d/docker-stable.list:1

And I picked most up-to-date version from the list and it worked.

August 20, 2018

On the new version of Vagrant, answer by @Amos Shapira gets stuck in an infinite loop. The reason for that is each call to vagrant plugin install also processes the Vagrantfile and when processed executes the code relating to installing the plugin again and again and so on.

Here is my solution which avoids the loop.

# Plugins
#
# Check if the first argument to the vagrant
# command is plugin or not to avoid the loop
if ARGV[0] != 'plugin'

  # Define the plugins in an array format
  required_plugins = [
    'vagrant-vbguest', 'vagrant-hostmanager', 
    'vagrant-disksize'
  ]         
  plugins_to_install = required_plugins.select { |plugin| not Vagrant.has_plugin? plugin }
  if not plugins_to_install.empty?

    puts "Installing plugins: #{plugins_to_install.join(' ')}"
    if system "vagrant plugin install #{plugins_to_install.join(' ')}"
      exec "vagrant #{ARGV.join(' ')}"
    else
      abort "Installation of one or more plugins has failed. Aborting."
    end

  end
end
February 28, 2018

You can stop the build at a certain stage and tag them as you want.

docker build --target test -t starx/test:latest .
docker build --target staging -t starx/staging:latest .
docker build --target prod -t starx/prod:latest .

This way, you have different images and you can push each image individually.

February 27, 2018

You can split the string, like

String[] splits = stringToList.split(",");

And cast them to integer using something like Integer.parseInt(splits[0]); and store them in an ArrayList

December 30, 2017

Ok, I manage to figure the problem out. The sass requires a home directory to operate correctly. If you are executing PHP as a system user, which in my case it was, it does not have a home directory, that is why it failed.

On Linux, you can use mkhomedir_helper [user] to create a home directory. Once you have created a home directory, sass will start to work.

December 6, 2017

How to export video from motion photo in Samsung S7/S8 using a bash script?

Samsung Galaxy S7 and S8 phones have a new way to capture pictures called Motion Photo. When shot in this mode, with each picture, it also records a short video before the picture was captured.

You can view this short video when you view your pictures using the Gallery app of the phone, but when you backup these pictures to your computer, you lose access to them. Below, I will explain a solution which you can use to extract these videos. You basically need a terminal from which you can run grep, cut and tail.

Logic

Logic is quite simple. The video and the photo are stitched on the same file. If you open the picture using a hex editor, towards the end of the file, you will see a portion of binary data that starts with text MotionPhoto_Data which contains the video.

Picture showing MotionPhoto_Data text in a file

Step 1

So, step 1 is to locate the position of this text. You can find this as follows.

grep -abo "MotionPhoto_Data" ./path/to/picture.jpg | cut -d: -f1

The flags specified in the grep mean the following:

  • -a process the binary of the file as text
  • -b prints the byte offset
  • -o prints out matching text

It’s trying to extract the byte offset of the file where MotionPhoto_Data can be found. Then, cut is used to remove other extra bits from the matched text so we can have only the number of offset.

Step 2

Next step is to extract all the data from the file after the position found in step 1. Let’s assume it was 8000. Then, the position we want to extract from is after the text MotionPhoto_Data which is 16 characters long, so from 8017. Then, in our terminal, we can do the following to extract the video

tail -c +8017 ./path/to/picture.jpg > ./path/to/picture.mp4

And, that’s it. Now, you can open your video.

Tool

I have wrapped all this logic into a small script, which can be downloaded and used instantly.

Repository: https://github.com/starx/SamsungMotionPhotoVideoExtractor

Install the script, with the following command

# curl -o /usr/local/bin/extractVideo_SamsungMotionPhoto.sh https://raw.githubusercontent.com/starx/SamsungMotionPhotoVideoExtractor/master/extractVideo_SamsungMotionPhoto.sh
# chmod +x /usr/local/bin/extractVideo_SamsungMotionPhoto.sh

And extract all the videos in a path, using the following command.

extractVideo_SamsungMotionPhoto.sh /path/to/pictures
July 25, 2017

In MySQL 5.7, if you execute the query from Tom Mac’s answer, you will get the following error:

ERROR 3167 (HY000): The ‘INFORMATION_SCHEMA.SESSION_VARIABLES’ feature is disabled; see the documentation for ‘show_compatibility_56’

You should query performance_schema instead. Run the following:

SELECT variable_value FROM performance_schema.session_variables WHERE upper(variable_name) = 'BINLOG_FORMAT';
...

Please fill the form - I will response as fast as I can!