8

I'm using supervisor in docker images when I have to run multiple services in one image e.g. postfix and other mail services. When I redirect the stdout/stderr from all services to supervisor and supervisor does also log to stdout/stderr I would prefer to have a prefix/label infront of the actual log output on the console to know which log is coming from which service. I can't find any config setting for this but maybe you know a way.

Here is an example how it looks like with Foreman: Foreman log output

2

I was having the same problem recently, and could not figure out supervisor-stdout. Here is what I did:

In bash you can use I/O redirection and Process Substitution to pipe stdout, stderr through another process.

    #!/usr/bin/env bash
    # setup fd-3 to point to the original stdout
    exec 3>&1
    # setup fd-4 to point to the original stderr
    exec 4>&2

    # get the prefix from SUPERVISOR_PROCESS_NAME environement variable
    printf -v PREFIX "%-10.10s" ${SUPERVISOR_PROCESS_NAME}

    # reassign stdout and stderr to a preprocessed and redirected to the original stdout/stderr (3 and 4) we have create eralier
    exec 1> >( perl -ne '$| = 1; print "'"${PREFIX}"' | $_"' >&3)
    exec 2> >( perl -ne '$| = 1; print "'"${PREFIX}"' | $_"' >&4)
    # from here on everthing that outputs to stdout/stderr will be go through the perl script
    echo "I will be prefixed"
    # don't forget to use exec 

Now you can setup supervisor to use stdout and stderr for logging:

    stdout_logfile=/dev/stdout
    stdout_logfile_maxbytes=0
    stderr_logfile=/dev/stderr
    stderr_logfile_maxbytes=0

and as command use a bash script that setups the I/O redirection.

2

@flocki Thanks for your great answer! Below a slightly more complete example:

[program:nginx]
command=/usr/local/bin/prefix-log /usr/sbin/nginx -g "daemon off; error_log /dev/stderr info;"
autostart=true
autorestart=true
priority=10
stdout_events_enabled=true
stderr_events_enabled=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
stopsignal=QUIT

prefix-log:

#!/usr/bin/env bash
# setup fd-3 to point to the original stdout
exec 3>&1
# setup fd-4 to point to the original stderr
exec 4>&2

# get the prefix from SUPERVISOR_PROCESS_NAME environement variable
printf -v PREFIX "%-10.10s" ${SUPERVISOR_PROCESS_NAME}

# reassign stdout and stderr to a preprocessed and redirected to the original stdout/stderr (3 and 4) we have create eralier
exec 1> >( perl -ne '$| = 1; print "'"${PREFIX}"' | $_"' >&3)
exec 2> >( perl -ne '$| = 1; print "'"${PREFIX}"' | $_"' >&4)

# from here on everthing that outputs to stdout/stderr will be go through the perl script

exec "$@"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.