绕过journald仅将特定的systemd服务日志记录到syslog

绕过journald仅将特定的systemd服务日志记录到syslog

有一段时间寻找一个使用 systemd 工具的解决方案将使我有机会绕过日志并直接记录到 syslog。当然,也可以过滤,但只能在日志上过滤,而不是在系统日志上过滤。

到目前为止我还无法做出正确的选择。我的系统是 OL8,systemd 239-68。

已经尝试过的:

[Service]
...
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=my_service
...

这为日志和系统日志提供了双重日志记录。第二次尝试已设定StandardOutputStandardErrorappend

不想使用上面的方法,因为以这种方式发送的消息是原始的,没有标识符或时间戳,可能需要由发送者(应用程序)设置,这超出了我的管辖范围。

我知道我可以在单独的脚本中使用记录器来完成此操作,但实际上这是最后的手段,因为它是非正式的ExecStart2>&1

还看到了这两个话题:

https://github.com/systemd/systemd/issues/6432

https://github.com/systemd/systemd/pull/24058

但它们都没有专门解决上述问题。

你能指出我关于如何解决这个问题的任何其他想法吗?

答案1

一种可能性是将程序的标准输出连接到 Unix 域套接字。配置 rsyslogd 以读取此套接字,并在进行任何过滤并最终将其写入文件之前添加时间戳。例如,将这些行添加到/etc/rsyslog.conf

module(load="imptcp")
input(type="imptcp" path="/tmp/mysocket1" name="my1")
template(name="outfmt" type="string" string="%timegenerated:::date-rfc3339% %inputname% %rawmsg%\n")
if $inputname=="my1" then {
  action(type="omfile" file="myoutput" template="outfmt")
}

当 rsyslogd 重新启动时,它将创建一个套接字/tmp/mysocket1。在systemd服务文件中使用

StandardOutput=file:/tmp/mysocket1

默认情况下,StandardError继承与 相同的套接字StandardOutput

现在,程序写入的所有行都将由 rsyslogd 读取并进行处理,例如添加接收时间戳、我们为输入指定的名称“my1”以及 rawmsg。 (rsyslog 文档表明 systemd 实际上会忽略消息中的时间戳,并使用自己的内部时间,因此这并不罕见)。

如果您需要区分多个程序,则每个程序都需要有自己的命名套接字。与其测试inputname,不如将设置包含在规则集中。当然,您还可以使用自己的配置文件创建并运行单独的专用 rsyslogd 守护进程。

相关内容