Search code examples
bufferstdoutsystemdsystemd-journald

How to guarantee the stdout buffer between systemd and journald is flushed when program quits?


The simplified example that demonstrates a problem is

#include <stdio.h>

int main(void)
{
    printf("foo\n");
    fflush(stdout);
    getchar();
    return 0;
}

(it's not programming language specific though - the original application I discovered the problem with is in Go).

If it's compiled and is run by the following unit:

[Unit]
Description=description
After=network.target

[Service]
ExecStart=/path/to/binary

[Install]
WantedBy=multi-user.target

then on systemctl restart journald would in most cases not get the foo\n output, while syslog successfully writes it down to the /var/log/syslog.

Here is the example of the journald output for the service:

May 18 08:30:38 hostname systemd[1]: Stopped servicename
May 18 08:30:38 hostname systemd[1]: Started servicename
May 18 08:30:38 hostname systemd[1]: Stopped servicename
May 18 08:30:38 hostname systemd[1]: Started servicename
May 18 08:30:38 hostname servicename[7701]: foo
May 18 08:30:41 hostname systemd[1]: Stopped servicename
May 18 08:30:41 hostname systemd[1]: Started servicename
May 18 08:30:46 hostname systemd[1]: Stopped servicename
May 18 08:30:46 hostname systemd[1]: Started servicename

and then the corresponding part of the /var/log/syslog:

May 18 08:30:38 hostname systemd[1]: Stopped servicename.
May 18 08:30:38 hostname systemd[1]: Started servicename.
May 18 08:30:38 hostname servicename[7682]: foo
May 18 08:30:38 hostname systemd[1]: Stopped servicename.
May 18 08:30:38 hostname systemd[1]: Started servicename.
May 18 08:30:38 hostname servicename[7701]: foo
May 18 08:30:41 hostname systemd[1]: Stopped servicename.
May 18 08:30:41 hostname systemd[1]: Started servicename.
May 18 08:30:41 hostname servicename[7720]: foo
May 18 08:30:46 hostname systemd[1]: Stopped servicename.
May 18 08:30:46 hostname systemd[1]: Started servicename.
May 18 08:30:46 hostname servicename[7739]: foo

What would be a way to guarantee journald received the stdout, if any?


Solution

  • tldr, it's a known issue.

    I asked the same question at the systemd-devel maillist and got a reply with a reference to the reported issue.