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:
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.