15.04上的systemd无法记录单元的标准输出。

我目前正在尝试将一个systemd单元作为一个Web服务器。目前,我的foo.service文件如下所示:
[Unit]
Description=The Foo Web Server

[Service]
Type=simple
ExecStart=/opt/foo/.cabal-sandbox/bin/foo

[Install]
WantedBy=multi-user.target
foo 可执行文件会自动将所有的 HTTP 请求记录到标准输出(stdout) - 这已经经过充分测试。然而,当我使用 journalctl -u foo 查看日志时,我只能得到如下输出:
...
May 06 17:46:57 localhost systemd[1]: Stopping The Foo Web Server...
May 06 17:46:57 localhost systemd[1]: Started Foo Web Server.
May 06 17:46:57 localhost systemd[1]: Starting The Foo Web Server...
May 06 17:47:08 localhost systemd[1]: Stopping The Foo Web Server...
May 06 17:47:08 localhost systemd[1]: Started The Foo Web Server.
May 06 17:47:08 localhost systemd[1]: Starting The Foo Web Server...

能有人解释一下为什么它没有记录所有的stdout输出吗?我简单地看了一下this previous question,但是它没有帮助——不过它提到了一些类似于“……在不使用完整systemd的系统上可能不起作用”的内容。这对于Ubuntu 15.04也是如此吗?非常感谢您提前的帮助,对此的任何帮助将不胜感激!

1请确保您的进程不会缓冲输出。我之前遇到了类似的问题,并通过禁用我的Python脚本的输出缓冲来解决了这个问题。由于生成的日志记录数量不多,看起来就像没有进行日志记录,但实际上是因为所有内容仍在stdout输出缓冲区中等待。 - Jan Vlcinsky
1也在努力解决这个问题。我有一种印象,systemd会进行缓冲处理。在UNIX中,stdout是按行缓冲的,但systemd会做自己的事情并且进行更多的缓冲(可能是为了快速但没有用处)。 - Velkan
4我遇到了同样的问题,Python的print函数也有缓冲问题!由于我使用的是Python 3,我只需像这样使用print('Hello World!', flush=True),问题就解决了!输出开始出现在journalctl中。 - timbram
3对于 Python 的替代方案:可以尝试将 Environment=PYTHONUNBUFFERED=1 放入你的服务文件中,这是一个 @timbram 提到的建议的替代方法。你可以在 https://unix.stackexchange.com/a/608678/161268 找到更多相关信息。 - Brad Grissom
多么奇怪的行为。远非理想。甚至可以说不太纯洁... - Quelklef
2个回答

实际上,在UNIX中,缓冲取决于上下文:当stdout被重定向到像控制台这样的交互式设备时,通常是行缓冲,否则是完全缓冲。
可以使用setvbuf库调用在应用程序内部更改缓冲设置。
但也可以在启动时使用stdbuf命令进行设置。
ExecStart=/usr/bin/stdbuf -oL /opt/foo/.cabal-sandbox/bin/foo

(适用于行缓冲情况)

这真是救了我的一天!非常感谢你。但是我有点困惑,为什么在服务终止时,使用 ExecStart=/my/foo/program 时,标准输出日志没有被刷新,而是完全消失了。 - wlnirvana
很遗憾,日志消息被标记为stdbuf而不是实际的程序,但我可以确认命令行解决方法确实有效。我可能需要使用库函数来修复标记。 - campkeith

默认情况下,Ubuntu 15.04 上的 systemd 日志仅为临时性,并保存在 /run/systemd/journal 中,在每次重启时都会丢失。要使用持久性的 systemd 日志,您需要创建 /var/log/journal 目录(并重新启动 systemd-journald.service)。
因此,可能仅将 stdout 输出重定向到 syslog,而不保存在 systemd 日志中。为此,您可能需要使用上述解释中的持久性 systemd 日志。
您是否已经检查了 /var/log/syslog 中的 foo 日志?

我按照你提到的创建了/var/log/journal,但是无论如何我仍然看不到我的systemd服务的标准输出。在/var/log/syslog中我也没有看到。 - logoff