unit
unit copied to clipboard
containerized Django logging best practices
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!
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"
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.
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 thedocker-entrypoint.d
directory. More information here: https://unit.nginx.org/installation/#docker-imagesGiven 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?
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.
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 thedocker-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.