unit icon indicating copy to clipboard operation
unit copied to clipboard

containerized Django logging best practices

Open sebastian-philipp opened this issue 2 years ago • 5 comments

Hi folks,

I was looking into getting logging of my Django app to work in a containerized unit, but not sure how to get it right.

General best practice for containers is to log to stdout and that's what I tried to do like so:

# settings.py
LOGGING = {
    ...,
    'handlers': {
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'stream': sys.stdout,
            'formatter': 'verbose',
        },
    },
    ...,
}

But this doesn't work, as AFAICS nginx-unit is spawning a new process for the app. An alternative would be to write the log to the main process as in 'stream': open('/proc/1/fd/1', 'a') but that fails with a permission denied error.

My main idea was to avoid deploying an extra sidecar container just for printing the Django log to stdout.

What is the best practice for setting up Django logging in a container?

Thank you!

sebastian-philipp avatar May 05 '22 12:05 sebastian-philipp

fyi, I ended up with creating an intermediate ENTRYPOINT like so:

$ cat my-entrypoint.sh
#/bin/bash

set -e

touch /tmp/django.log
chmod a+w /tmp/django.log
nohup tail -f /tmp/django.log &

exec /usr/local/bin/docker-entrypoint.sh "unitd" "--no-daemon" "--control" "unix:/var/run/control.unit.sock"

sebastian-philipp avatar May 12 '22 15:05 sebastian-philipp

Hi @sebastian-philipp . I was literally working on the same approach but was looking for something more elegant but couldn't find anything, yet.

So for now I believe this is the best way doing it. Maybe you can keep the default docker-entrypoint.sh script and use a shell script in the docker-entrypoint.d directory. More information here: https://unit.nginx.org/installation/#docker-images

Given the Unit state directory is empty, Unit would execute the script. We could try using this script so you could use the default Docker Image without overwriting the entrypoint.

tippexs avatar May 12 '22 19:05 tippexs

Hi @sebastian-philipp . I was literally working on the same approach but was looking for something more elegant but couldn't find anything, yet.

So for now I believe this is the best way doing it. Maybe you can keep the default docker-entrypoint.sh script and use a shell script in the docker-entrypoint.d directory. More information here: https://unit.nginx.org/installation/#docker-images

Given the Unit state directory is empty, Unit would execute the script. We could try using this script so you could use the default Docker Image without overwriting the entrypoint.

Would that also work for container restarts?

sebastian-philipp avatar May 13 '22 07:05 sebastian-philipp

Other app servers tend to have an option to forward stdout/stderr from child processes to the parent process. Would be nice if Unit could handle this automatically.

jalaziz avatar May 14 '22 21:05 jalaziz

Hi @sebastian-philipp . I was literally working on the same approach but was looking for something more elegant but couldn't find anything, yet. So for now I believe this is the best way doing it. Maybe you can keep the default docker-entrypoint.sh script and use a shell script in the docker-entrypoint.d directory. More information here: https://unit.nginx.org/installation/#docker-images Given the Unit state directory is empty, Unit would execute the script. We could try using this script so you could use the default Docker Image without overwriting the entrypoint.

Would that also work for container restarts?

No - That is the issue in this case. The script will be executed if and only the NGINX Unit state dir is empty. In this case using our pre-build Image as a base image and override the entrypoint would be the best option.

tippexs avatar May 16 '22 07:05 tippexs