Minimalistic logging from Docker containers


Reading logs from Docker container can be done using docker logs container_id. This simply fetches logs present at the time of execution from container’s STDOUT and STDERR streams. If you want to, however, transform those logs, and send them to a central repository using e.g. logstash, there are a number of options to choose from. Here I’ll be describing the simplest case of writing logs to /dev/log socket.

Writers will write

Minimalistic scenario for collecting logs expects that your software, running inside the Docker container, writes to a syslog using the Unix domain socket /dev/log. With a Ruby app running inside the Docker container you can use Syslog::Logger class like this:

log = Syslog::Logger.new('my-awesome-app')
log.info('say something nice')

With a nodejs app and some help of ain package you might end up with:

var SysLogger = require('ain2')
var log = new SysLogger({tag: 'my-cool-app', path: '/dev/log'});
log.setTransport('unix_dgram');
log.info('say something sweet');

If you have a properly configured and running (r)syslog daemon, you will get to both accounts something like this in /var/log/messages:

Apr 10 18:31:25 ip-123-21-31-41 my-awesome-app[1101]: say something nice
Apr 10 18:31:25 ip-123-21-31-41 my-cool-app[1105]: say something sweet

The same effect can be achieved by using the logger tool. Both previously mentioned libraries, as well as the logger, use syslog(3) API call and write directly to /dev/log socket (if available).

And readers will read

Now comes the fun part. I promised to explain how this logging stuff and syslog plays with Docker. To be able to send logs to an IPC socket, somebody has to create it first. Let that somebody be an rsyslog daemon running on a Docker host. For this to work we need to have the following line in /etc/rsyslog.conf uncommented:

$ModLoad imuxsock

Last thing yet to do is to bind mount /dev/log socket on Docker run using something like:

docker run -v /dev/log:/dev/log my-image

One important thing to notice is that once we restart rsyslog daemon, for whatever reason, all apps running inside the Docker containers won’t be able to write to syslog anymore. Reason for that is dead simple - the socket to which all apps were bound is now gone and replaced by another one. If we want to write logs to that new socket, we should probably restart our apps.


comments powered by Disqus