Posted on Leave a comment

2 Easy Steps To Configure Docker logging with rsyslog

If you have problem configure Docker logging with rsyslog, this post may provide a quick solution. I, by no mean, say that this is the ultimate guide for docker & rsyslog configuration. However, the following configurations helped me achieve my goal.

The desired goal

Based on a requirement from a client, they want to store all docker logging to a custom file location. That includes dockerd logging and containers’ logging.

So, after reading this tutorial, you can:

  • Configure docker to log to a custom location using rsyslog

If that’s your goal, read on.

Step 1: Configure docker logging

By default, docker containers’ log is written to a .json file inside the containers folder (default at /var/lib/docker/containers/<container_id>). We are going to change this default behavior by specifying a different log driver for docker, which is rsyslog.

So, create/edit your /etc/docker/daemon.json file and paste the following content:

{
    "log-driver": "syslog",
    "log-opts": {
        "tag" : "docker-container- {{.ImageName}} - {{.ID}}"
    }
}

Now, save the file and restart your docker service using systemctl restart docker.

What have we done?

As you can see in the log file, we specify the log driver to “syslog”. We also specify tag in “log-opts”. The tag option allows us to pass in custom data to the log message. The “docker-container” part is used to filter the log message in rsyslog settings so we can write it to a different file (other that /var/log/syslog).

{{.ImageName}} is the name of the Docker image. {{.ID}} is the ID of the container (short ID, 12 chars). These info are optional. You can see the list of parameters you can passed in here.

Now, let’s run a docker container and check the log message:

Configure Docker logging with rsyslog - log message in rsyslog

As you can see, we ran an nginx container and view the content of /var/log/syslog and sure enough, the new log format is there with image name and container’s ID.

The next step is to tell rsyslog to store messages like this at a different location.

Step 2: Configure rsyslog to filter docker log messages

In this step, we are going to create a dedicate log config for docker. Let’s say I want to store all docker-related messages in /var/log/docker/.

Create /etc/rsyslog.d/docker.conf with the following content:

$FileCreateMode 0644
template(name="DockerLogFileName" type="list") {
   constant(value="/var/log/docker/")
   property(name="syslogtag" securepath="replace" \
            regex.expression="docker/\\(.*\\)\\[" regex.submatch="1")
   constant(value="/docker.log")
}
if $programname == 'dockerd' then \
  /var/log/docker/combined.log

if $syslogtag contains 'docker-container' then \
  /var/log/docker/containers/docker.log
  &stop

$FileCreateMode 0644

Most of the code in this file I got from this answer on stackoverflow.

Here are the important parts:

We check if the log message has ‘docker-container’ (which we inserted when configuring /etc/docker/daemon.json), if it does, we save the log to /var/log/docker/containers/docker.log.

You can specify a different location that suits your preferences.

This file contains all logging message for your containers.

Next, if you don’t want to store the log message in /var/log/syslog file, include the ‘&stop’ line.

If you comment out the ‘&stop’ line (with #), log messages from docker containers will also be save to /var/log/syslog and /var/log/daemon.log

Now, restart syslog service with systemctl restart rsyslog.

Conclusion

There you have the working solution for storing docker containers’ log message at a specific location on disk with rsyslog. Make sure to use logrotate to split the file since it could be very large after some time, depends on your system.