Jorge Avante

Web development

How to save Docker logs in MongoDB with Fluentd

Sometimes it is needed to aggregate or simply save the logs of container applications somewhere outside the docker host machine. For example, when using a small device like a raspberry pi with limited storage.

In this guide we will setup fluentd (https://www.fluentd.org) in order to stream container logs to a remote mongoDB database.

Fluentd installation

Note: In case you are running a 64 bits Linux machine, there are already fluentd docker images and binaries, so you can take a look and skip this part.

In order to install fluentd on a raspberrypi, first we need to make sure we have some dependencies:

sudo apt-get update
sudo apt-get install build-essential autoconf libc6-dev automake libtool ruby-dev

Then we need to install fluentd as a ruby gem:

sudo gem install fluentd

And the fluentd plugins that we will use:

sudo fluent-gem install fluent-plugin-td
sudo fluent-gem install fluent-plugin-mongo

That's all, now fluentd is installed

Fluentd configuration

Fluentd needs a configuration file where we tell what are the inputs and outputs we want. Since docker can communicate with our fluentd process, the config is pretty simple. Create a fluent.conf file and configure the mongoDB info as shown in the fluent official documentation ( https://docs.fluentd.org/output/mongo ):

<source>
  @type forward
</source>
<match docker.*>
  # plugin type
  @type mongo
  # connection string can also be used: 
  # connection_string mongodb://<User>:<Pass>@localhost:27017/myDatabase?w=0
  # mongodb db + collection
  database myDatabase
  collection logs
  # mongodb host + port
  host localhost
  port 27017
  # authentication
  user michael
  password jordan
  # interval
  <buffer>
    flush_interval 10s
  </buffer>
  # make sure to include the time key
  <inject>
    time_key time
  </inject>
</match>

The important thing here is the match expression, we are saying that our logs will have a tag of the style “docker.” + other thing, for example the container name.

Now we can start fluentd with the command:

fluentd -c fluent.conf

Docker log output

When running docker containers, we need to tell them that we will use fluentd instead of the standard log mechanism. And we need to specify the correct tag so fluentd saves the logs. For example, lets run a simple alpine container:

sudo docker run --log-driver=fluentd --log-opt tag="docker.{{.ID}}" alpine echo 'Hello world!'

The tag option can include the container id like in the example, or other parameters, as documented in the official docker page ( https://docs.docker.com/config/containers/logging/log_tags/ ).

If everything went fine, you should see an entry in your mongoDB collection. Try other containers you own and you can see how they log in the database :)

Extra: Setting fluentd as service

If you want that fluentd starts automatically after starting the computer, you need to add the fluentd.service file into /etc/systemd/system:

Description=Fluentd
Documentation=http://www.fluentd.org/
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/bin/fluentd -d /run/fluentd.pid -c /path/to/fluent.conf
PIDFile=/run/fluentd.pid
Restart=on-failure

[Install]
WantedBy=multi-user.target