Your central log server in Docker

Containerization, and Docker in particular, changed the way we distribute and run applications. I used containers – FreeBSD jails – for nearly twenty years, but Docker brought us the ease of use necessary for wide adoption. Containers provide isolated environments, which make it possible to run applications with conflicting dependencies on the same host. There are even dedicated container hosts, like Atomic Host, which do not allow you to install any applications on the host directly, only in containers.

This is the first blog post in a three-part series on logging in Docker using syslog-ng. You’ll find a link to the next part in the series at the end of this post. You can also read the whole Docker series in a single white paper.

The syslog-ng Docker image

Your central log server can also run in a Docker container. If you wish to deploy your log server running syslog-ng in a Docker container, it is available as a ready-to-use image from the Docker Hub, already passing 500K pulls. The image is based on the latest Debian and the latest stable version of syslog-ng. It has all modules, including Java modules and experimental modules from the incubator.

You can issue a single command to download the image and run it in a container on your host machine. In addition to, of course, sharing that command with you, my goal in this post is to explain how it is made up and what it does.

So before showing you that nice, long command line, first let’s start with some background information.

As a central log server, the syslog-ng image exposes three different ports, where it can receive log messages:

  • Syslog UDP: 514
  • Syslog TCP: 601
  • Syslog TLS: 6514


To be able to use them, you need to enable these ports both in the syslog-ng configuration (syslog-ng.conf) and in the command line starting the Docker container.

Starting for the first time

If you do not have a configuration file at hand for testing, create one. Here is a simple syslog-ng.conf, which listens to the legacy syslog protocol on UDP port 514, the new syslog protocol on TCP port 601, and stores any incoming log messages in a file called /var/log/syslog.

@version: 3.9
 
source s_net {
   udp(
     ip("0.0.0.0")
   );
   syslog(
     ip("0.0.0.0")
   );
 };
 destination d_file {
   file("/var/log/syslog");
 };
 log {source(s_net); destination(d_file); };

You can map files or directories from your host into the container. In the case of syslog-ng.conf, you have a simple configuration file with all the settings in a single file and you do not have any encryption keys, so mapping the configuration file is the easiest. In any other scenario, you should map a complete directory for the configuration.

If you store all your log messages in a database, there is not much need for persistent storage for your container. If your central log server also stores data, there is a good chance that you will want to have access to those logs even if you switch to another syslog-ng image. In this case, you should map a directory from the host machine, so your log storage is independent from your Docker containers.

If you have your syslog-ng.conf under /data/syslog-ng/conf and plan to store your logs in the /data/syslog-ng/logs directory, you can use the following command line to get started. It 1) starts the container in interactive mode, 2) maps two network ports from the host to the container, 3) maps the configuration file and log directory, and 4) adds some debug options to syslog-ng. The name of the container will be “syslog-ng” and Docker will use the latest available syslog-ng image from the Docker Hub.

docker run -it -v /data/syslog-ng/conf/syslog-ng.conf:/etc/syslog-ng/syslog-ng.conf -v /data/syslog-ng/logs:/var/log -p 514:514 -p 601:601 –name syslog-ng balabit/syslog-ng:latest -edv

When you first execute this command, it can take a few minutes until syslog-ng is up and running, as the image is downloaded over the Internet. On subsequent executions, Docker will use the local copy and start immediately.

Testing

Using the “docker ps” command from an other terminal you can check, that your container is up and running. You can see many information about the image, including the opened network ports.

linux-pzl9:~ # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b947a3411c1a balabit/syslog-ng:latest “/usr/sbin/syslog-ng ” 18 seconds ago Up 17 seconds 0.0.0.0:514->514/tcp, 514/udp, 0.0.0.0:601->601/tcp, 6514/tcp syslog-ng

The “loggen” command can generate you a few sample logs. If you used the above configuration and directories, you should see a flood of messages on the screen where you started the container and also new messages in the file /data/syslog-ng/logs/syslog

linux-pzl9:~ # loggen -i -S -P localhost 601
average rate = 1006.53 msg/sec, count=10066, time=10.000, (average) msg size=260, bandwidth=255.42 kB/sec

What is next?

Use the above “docker run” command to get you started and enable you to debug your syslog-ng setup. Once you have a working configuration though, you should start the container in “detached” mode in the background by replacing the “-it” option with “-d”, and removing the “-edv” option from the end of the command line.

It is certainly not our goal to teach you Docker or syslog-ng in depth here, in this blog post. If you’re interested and would like to know more, check out these resources:

 

In my next Docker blog, I cover how you can collect Docker infrastructure logs using the journal and syslog-ng.

Read the entire series about logging in Docker using syslog-ng in a single white paper.

Related Content