为什么我的 C 程序的所有输出都定向到 stdout 并发送到 Journald?

为什么我的 C 程序的所有输出都定向到 stdout 并发送到 Journald?

我从事基于 yocto 的 Linux 发行版。我不是这方面的专家systemd,也不是systemd-journald
我的 C 程序my_c_program在启动时由脚本启动my_script.sh。下面是文件my_script.sh

my_c_program &
echo $! > /dev/shm/my_c_program.pid

前面的脚本是由服务启动的。服务的单元文件称为start_c_program.service.下面是单位服务:

[Unit]
Description=Start my_c_program
Requires=...
After=...
Before=...

[Service]
Type=forking
ExecStart=/usr/bin/my_script.sh
PIDFile=/dev/shm/my_c_program.pid

[Install]
WantedBy=multi-user.target

通过此配置,所有指令printf("message")都将my_c_program字符串添加"message"到 中systemd-journald。我知道如果我修改my_script.sh为:

my_c_program > /dev/null &
echo $! > /dev/shm/my_c_program.pid

上的消息journald被抑制,但问题是:
为什么我的 C 程序的所有输出都定向到 stdout 被发送到journald

谢谢


我认为要发送消息,journald我必须使用 C 指令syslog(),例如通过如下代码:

#include<syslog.h>
int main(int argc, char** argv) {
    syslog(LOG_INFO, "Start logging");
}

答案1

Systemd 将执行进程的标准输出连接到其日志。标准输出也由所有子进程继承,这就是 C 程序将内容打印到日志的原因。您可以使用标准输出=参数将程序的标准输出重定向到其他位置。

答案2

这是 systemd 的一个设计特点,实际上在现代软件中更为常见。

现代设计正在从软件自行决定将日志发送到何处,转向让运行程序(在本例中为 systemd)决定要做什么。软件本身只是写入 stdout 和 stderr。在 Docker 或 Kubernetes 中运行的容器化软件具有非常相似的模式。

许多程序不知道如何写入 syslog,并且它比仅写入 stdout/stderr 更复杂。 Syslog 从未完全普遍存在,此类程序以前可能将其 stdout/stderr 重定向到 var log 中的日志文件。

当 systemd 启动程序时,通过在运行程序之前替换进程的文件句柄,将 stdout 和 stderr 重定向到日志。

相关内容