我从事基于 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 重定向到日志。