Technical Resources
Educational Resources
APM Integrated Experience
Connect with Us
Systemd can collect and store logs, but it doesn’t have a built-in method of logging to remote locations such as log management systems. Instead, it relies on the device’s syslog service to relay messages between journald and a remote syslog server. However, syslog is text-based and the journald uses a binary format, so your logs need to be converted before they can be transferred. You can do this by using either systemd’s ForwardToSyslog configuration setting, or by using rsyslog’s imjournal module.
Since syslog is still a part of most Linux distributions, journald contains a configuration setting to forward logs to syslog. This assumes you have a syslog server such as rsyslog running on the same machine as the systemd-journald service.
To enable ForwardToSyslog, open /etc/systemd/journald.conf and set the ForwardtoSyslog option to “yes”. In addition, set the MaxLevelSyslog parameter to “debug” to allow logs of any level to be forwarded to syslog.
$ sudo nano /etc/systemd/journald.conf ... [Journal] ForwardToSyslog=yes MaxLevelSyslog=debug ...
Rsyslog has an input module that can import data from journald into syslog. This module is called imjournal. There’s another import module called imuxsock that creates a Unix socket that journald can write logs to if the ForwardToSyslog configuration option is enabled. The difference between the two is that imjournal supports structured log data, while imuxsock doesn’t. However, imuxsocket is less performance-intensive than imjournal.
To enable imjournal in rsyslog 8 or later, add the following to your /etc/rsyslog.conf file. The mmjsonparse module lets ryslog parse journald messages:
# /etc/rsyslog.conf module(load="imjournal") module(load="mmjsonparse")
Restart syslog to start the module:
# systemctl restart rsyslog.service
More information about the module can be found here.
Now, let’s verify your journald events are appearing in syslog. We’ll run the following command to retrieve the latest error logs from journald.
$ journalctl -b -p err
This shows three error messages from the current boot.
-- Logs begin at Thu 2019-06-20 05:45:00 EDT, end at Mon 2019-06-24 17:16:02 EDT. – Jun 24 17:10:19 debian-ds liblogging-stdlog[3681]: module 'imfile' already in this config, cannot be added [v8.24.0 try https://www.rsyslog.co Jun 24 17:10:19 debian-ds liblogging-stdlog[3681]: error during parsing file /etc/rsyslog.d/java-gc.conf, on or before line 1: parameter 'Poll Jun 24 17:13:37 debian-ds etcd[3833]: forgot to set Type=notify in systemd service file?
To check if these messages also exist in syslog, the following command looks at the /var/log/syslog file for the last error (shown in bold in the output block above).
$ cat /var/log/syslog | grep "forgot to set Type=notify"
The output below shows the message does exist in syslog (with the same time stamp):
Jun 24 17:13:37 debian etcd[3833]: forgot to set Type=notify in systemd service file?
Note that the unit name related to the error comes after the date time stamp and the system name field. In this case, it’s the etcd service that encountered an error. The actual error message is then printed.
Although auto redirection of systemd journal messages to syslog seems like a cool feature at first, there are no one-to-one relationships between the fields captured by two. As a result, certain fields from a journal event will be found in its corresponding syslog message, while others won’t be there. One way to work around this is by outputting journald logs as JSON, which we’ll explain in the next section.
Journals have rich structured data stored in different fields. For sending journal events to external data consumers that don’t understand its native binary format, the data can first be exported to JSON and then transmitted. This is advantageous because JSON format has much wider support from common analysis tools.
Let’s consider the command journalctl -b -p err we ran in our test Ubuntu system.
One of the output lines was:
Jul 07 19:17:01 test-ubuntu1504 CRON[797]: Authentication token is no longer valid; new one required
Looking at the same error message when we use the –output=json-pretty switch, we have the following output.
{ "__CURSOR" : "s=06ed88764fb443ef940994ff9f77fc8f;i=4c8;b=2d171eeb6505401db1802a62ba43190b;m=1a82272e;t=51a51383bc6dc;x=44114702d932b028", "__REALTIME_TIMESTAMP" : "1436311021668060", "__MONOTONIC_TIMESTAMP" : "444737326", "_BOOT_ID" : "2d171eeb6505401db1802a62ba43190b", "_UID" : "0", "_GID" : "0", "_SYSTEMD_SLICE" : "system.slice", "_MACHINE_ID" : "6312944ca8d9f189228c76ab557a9109", "PRIORITY" : "3", "_CAP_EFFECTIVE" : "3fffffffff", "_TRANSPORT" : "syslog", "SYSLOG_FACILITY" : "9", "_COMM" : "cron", "_SYSTEMD_CGROUP" : "/system.slice/cron.service", "_SYSTEMD_UNIT" : "cron.service", "_HOSTNAME" : "test-ubuntu1504", "SYSLOG_IDENTIFIER" : "CRON", "SYSLOG_PID" : "797", "_PID" : "797", "MESSAGE" : "Authentication token is no longer valid; new one required", "_SOURCE_REALTIME_TIMESTAMP" : "1436311021667315" }
The complete list of journal event fields can be found in this main page, but looking at this JSON output we see that only some of the fields map to the syslog message format:
And then there are journal fields that do not map to syslog. These include:
For those who want to bypass syslog altogether, they can have a look at works already done by talented developers around the world.
For example, several people have written services that forward journals to a log management solution called SolarWinds® Loggly®. The GitHub project loggly.service from Jose-Luis Rivas creates a custom systemd service that continuously exports events from the journal and sends them to Loggly.
Another GitHub project is journald-forwarder from uswitch.com which uses a slightly more involved method.