查看 systemd 服务的 stdout/stderr

bea*_*mit 257 logs io-redirection systemd

我为自定义应用程序创建了一个简单的 systemd 服务文件。当我手动运行该应用程序时,它运行良好,但是当我使用 systemd 运行它时,我的 CPU 会达到极限。

我正在尝试追踪我的问题出在哪里,但我不知道在哪里可以找到输出(或如何配置 systemd 以将输出放在某处)。

这是我的服务文件:

[Unit]
Description=Syncs files with a server when they change
Wants=network.target
After=network.target

[Service]
ExecStart=/usr/local/bin/filesync-client --port 2500
WorkingDirectory=/usr/local/lib/node_modules/filesync-client
Restart=always

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

在整个应用程序中,我输出到 stdout 和 stderr。

如何读取守护进程的输出?

编辑:

我发现man systemd.exec,其中提到了该StandardOutput=选项,但我不确定如何使用它。从手册页

StandardOutput=

控制已执行进程的文件描述符 1 (STDOUT) 连接到的位置。采用inheritnullttysyslogkmsgkmsg+consolesyslog+consolesocket 之一

如果设置为继承标准输入的文件描述符,则为标准输出复制。如果设置为null标准输出将连接到/dev/null,即写入的所有内容都将丢失。如果设置为tty标准输出将连接到 tty(通过 配置TTYPath=,见下文)。如果仅使用TTY 输出,则执行的进程不会成为终端的控制进程,也不会失败或等待其他进程释放终端。 syslog将标准输出连接到 syslog(3) 系统记录器。 kmsg将其与可通过 dmesg(1) 访问的内核日志缓冲区连接。 syslog+consolekmsg+console工作类似,但也将输出复制到系统控制台。 socket将标准输出连接到来自套接字激活的套接字,语义类似于StandardInput=. 此设置默认为继承。

这是否意味着这些是我唯一的选择?例如,我想将输出放入/dev/shm或其他东西。我想我可以使用 Unix 域套接字并编写一个简单的侦听器,但这似乎有点不必要。

我只需要这个用于调试,我可能最终会删除大部分日志并将输出更改为 syslog。

Mat*_*att 258

更新

正如 mikemaccana 所指出的,systemd 日志现在是大多数发行版的标准日志记录设备。要查看systemd 单元的stdoutstderr,请使用该journalctl命令。

sudo journalctl -u [unit]
Run Code Online (Sandbox Code Playgroud)

原答案

默认情况下,stdoutstderr一个systemd单元的发送到syslog。

如果您使用的是完整的 systemd,则可以通过journalctl. 在 Fedora 上,它应该是,/var/log/messages但是 syslog 会把它放在你的规则说的地方。

由于帖子的日期,并且假设大多数接触 systemd 的人都是通过 Fedora,您可能被这里描述的错误击中:https : //bugzilla.redhat.com/show_bug.cgi?id=754938 它有也很好地解释了它是如何工作的 =)(这是 selinux-policy 中的一个错误,它导致错误消息未被记录,并已在 中修复selinux-policy-3.10.0-58.fc16

  • 请注意,默认情况下,使用这样的标准日志记录机制*不会*创建持久日志。为此,您需要创建 /var/log/journal,然后运行 ​​`sudo systemctl restart systemd-journald` (5认同)
  • 这让我发疯了......在标准的 Debian 拉伸 journalctl 上不会向我显示任何标准输出。我什至使用 `/usr/bin/stdbuf -oL <cmd>` 和一个显式的 `StandardOutput=journal`。依然没有。 (3认同)
  • 这对我有用:`StandardOutput=syslog+console` 和 `StandardError=syslog+console` 之后我的单元的所有输出都出现在 journalctl 中。默认设置显然是错误的。(比如/etc/systemd/system.conf中的DefaultStandardOutput) (2认同)
  • `-f` 对我很有帮助。在发生更改时跟踪日志(用例是跟踪作为守护程序运行的 minecraft 服务器) (2认同)

mik*_*ana 109

更短、更简单、非传统的答案:

sudo journalctl -u [unitfile]
Run Code Online (Sandbox Code Playgroud)

其中 [unitfile] 是 systemd.service名称。例如,要查看来自 的消息myapp.service

sudo journalctl --unit=myapp
Run Code Online (Sandbox Code Playgroud)

实时跟踪日志:

sudo journalctl -f -u myapp
Run Code Online (Sandbox Code Playgroud)

  • @JECompton 如果当前 Linux 发行版上的所有日志记录都使用 journald,并且 syslog 不是必需的并且仅用于兼容性,那么从逻辑上讲,syslog 是遗留的。 (11认同)
  • 系统日志不是遗留的...... (7认同)
  • 请注意,如果您收到“找不到日志文件”错误,则可能必须使用“sudo”。 (5认同)
  • 当然。它还使用系统日志。我的观点不是不使用 systemd,而是 syslog 不是遗留的。 (3认同)
  • 它在当前的 Linux 发行版中。您可能真的很喜欢 syslog,但这并不会改变它们随附的内容。 (2认同)
  • @mikemaccana 废话。Debian/Ubuntu/RedHat !=“所有登录当前 Linux”。syslogd 非常活跃,并且将在很长一段时间内继续保持相关性。举个例子:BusyBox 运行在全球数亿甚至*数十亿*的嵌入式设备上 - 远远超过流行的任何桌面发行版。它的系统日志功能?是的。也有许多桌面发行版设法避开了 SystemD 恶意软件感染,例如 Devuan、Alpine Linux、Artix Linux、Gentoo、Slackware 等——其中许多将使用 syslogd。 (2认同)