Skip to content

Instantly share code, notes, and snippets.

@afolarin
Last active March 16, 2023 13:02
Show Gist options
  • Star 70 You must be signed in to star a gist
  • Fork 15 You must be signed in to fork a gist
  • Save afolarin/a2ac14231d9079920864 to your computer and use it in GitHub Desktop.
Save afolarin/a2ac14231d9079920864 to your computer and use it in GitHub Desktop.
docker-logs

#Some discussions on logging from docker: Using logstash Using Papertrail

Issue Loging Drivers

Issue Enhanced Logging

A lot of this boils down to whether you want a single or multi-process (systemd, supervisord etc.) container...

#Getting at the container's merged logs Getting logs is still not something perfected in docker, and remains a little clunky.

Let's create a container named "foo"

me@host~$ docker run --name foo ubuntu /bin/bash -c 'while true; do echo "I am up.."; sleep 2; done' 

docker-logs CLI command merges both stdout and stderr into one stream:

me@host~$ docker logs foo

##Split the docker-logs You can then simply split the stdout & stderr of the container by piping the separate streams: and send them to files:

me@host~$ docker logs foo > stdout.log 2>stderr.log
me@host~$ cat stdout.log
me@host~$ cat stderr.log

or split stdout and error to host stdout:

me@host~$ docker logs foo > -
me@host~$ docker logs foo 2> -

#Pass a contained application's log There are a few ways to get at a given application's log files, they either involve either getting these specific log files to the containers stderr|stdout stream or to mount the log file's dir as a volume.

If we were running something in like a webserver

me@host~ docker run --name foo -d -p 80:80 dockerfile/nginx

##Method 1 while this is perhaps possible, I don't recommend it. This just tails the log file to stdout or stderr:

me@foo~# tail --pid $$ -F /var/log/nginx/access.log &

##Method 2 BETTER WAY This way involves creating links /dev/stdout|stderr as /app/log.file. The ngix can write to its logfile, as a file, but as a result the lines will go to stdout & stderr (but can be split see above).

e.g. ngix dockerfile https://github.com/nginxinc/docker-nginx/blob/master/Dockerfile

RUN ln -sf /dev/stdout /var/log/nginx/access.log 
RUN ln -sf /dev/stderr /var/log/nginx/error.log

##Access the logs on a host mounted directory The alternative would be to mount a host directory as the log folder and then access the log files directly on the host.

me@host~$ docker run -d -p 80:80 -v <sites-enabled-dir>:/etc/nginx/sites-enabled -v <certs-dir>:/etc/nginx/certs -v <log-dir>:/var/log/nginx dockerfile/nginx

me@host~$ ls <log-dir> 

#Inject a log monitor process with docker-exec While it is not generally considered a good idea to run multi-process containers, from of docker version 1.3, it is possible to insert a secondary process into a container, using docker-exec. So it is then possible to attach a process, to access arbitrary log files. Once a second process is inserted, you can see this with <ps aux> in the container.

interactively:

me@host~$ docker exec -it foo /bin/bash
me@foo~ # cat /some/log/file

or singularly:

me@host~$ docker exec -t foo cat /some/log/file

You can pretty much take your pick of how you now access the container. Though it might be best to exercise a bit of process hygiene.

#Dedicated syslog container One from Jerome. http://jpetazzo.github.io/2014/08/24/syslog-docker/ https://github.com/jpetazzo/syslogdocker

He uses 3 containers, but you can dispense with the inspection container if you are using docker v1.3 as you can simply inject a shell in to inspect the /var/log file.

  1. Build the syslog container:
FROM ubuntu:14.04
RUN apt-get update -q
RUN apt-get install rsyslog
CMD rsyslogd -n
VOLUME /dev
VOLUME /var/log
`docker build -t syslog .`
  1. syslog Container-- Run the syslog container, here all the logs will be gathered, when syslog starts it creates /dev/log which will now be in the mounted host dir /tmp/syslogdev:

    docker run --name syslog -d -v /tmp/syslogdev:/dev syslog

  2. Log generating container -- Start another container to send logs:

    docker run --name foo -v /tmp/syslogdev/log:/dev/log ubuntu logger -t "foo says" hello

  3. (a) Inspection Container -- Tail them logs:

    docker run --name seelog --volumes-from syslog ubuntu tail -f /var/log/syslog

  4. (b) Alternatively, as of docker v1.3 use the docker-exec command to inspect syslog container directly

    docker exec -t syslog tail -f /var/log/syslog

  5. See in the log message from "foo", show up in the "seelog" container.

#TODO...

  • basic log tutorial.
  • syslog
  • [] logrotate
  • [] aggregation services e.g. Fluentd, Papertrail, Logstash
  • [] discuss further|better ways to use docker-exec
@pebreo
Copy link

pebreo commented Sep 6, 2015

Thanks for posting. I ended using the dedicated syslog container approach. I wanted to redirect the stdout/stderr of my container to this listening container so I had to make a shell script that is run by docker command (CMD). This is what my shell script looked like just in case anyone needs to do it

#!/bin/bash -
# tee stdout and stderr to logger
exec > >(tee >("logger")) 2>&1
/usr/local/bin/gunicorn myproject.wsgi:application -w 2 -b :8000 -c gunicorn.conf

@rorysavage77
Copy link

I am looking to find a way to configure docker logs so they are stored in a particular directory. I am sure I will find it, but I just started looking.

@Pawan-Bishnoi
Copy link

@rcsavage did you find any?

@andyxning
Copy link

How to process if there are two instance of one single image and they both write the same log file, how can we separate them under shared volume schema.

@philicious
Copy link

whats worth mentioning, especially for application logs: sth like RUN ln -sf /dev/stdout /var/log/nginx/access.log doesnt work with all sorts of applications because of how they open the file. However the tail --pid $$ -F /var/log/nginx/access.log & approach works great in those cases

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment