程序退出时如何保证systemd和journald之间的stdout缓冲区被刷新?

时间:2018-05-17 20:36:46

标签: buffer stdout systemd systemd-journald

演示问题的简化示例是

#include <stdio.h>

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

(虽然它不是特定于编程语言 - 我发现问题的原始应用程序是在Go中。)

如果它已编译并由以下单位运行:

[Unit]
Description=description
After=network.target

[Service]
ExecStart=/path/to/binary

[Install]
WantedBy=multi-user.target

然后systemctl restart journald在大多数情况下不会获得foo\n输出,而syslog会成功将其写入/var/log/syslog

以下是服务的journald输出示例:

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

然后是/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

什么是保证记者获得stdout的方式,如果有的话?

1 个答案:

答案 0 :(得分:0)

tldr,这是一个众所周知的问题。

我在systemd-devel maillist处提出了同样的问题,得到了一个reply,其中提到了reported issue