Ten*_*ken 4 linux logs shell-script systemd systemd-journald
我有一个作为 systemd 服务运行的 shell 脚本,我想将具有粒度优先级的消息记录到该服务的 systemd 日志中。
当我使用 时logger(1)
,journald 仅记录一些消息并丢弃其余消息。哪条消息最终被记录到服务日志中似乎是完全随机的;有时只记录一两条消息,有时根本不记录任何消息。
起初我以为这是启动顺序/依赖性问题,但情况似乎并非如此,因为所有消息确实出现在系统日志(即)中,journalctl --system
但不是服务日志(即journalctl -u SERVICE.service
)中。我也尝试过systemd-cat
,但不幸的是它的行为很相似。
基于脚本的服务将具有优先级的消息记录到其自己的 systemd 日志中的正确方法是什么?
systemd 所面临的问题logger
与其自己的工具所面临的问题相同systemd-notify
。\n该协议是基于数据报的异步协议,工具只完成一项工作。\n调用者分叉一个进程来运行该工具;它发出一个数据报并忘记它;并且进程退出。
systemd
日志记录和就绪通知协议的服务器进程想要知道发送者属于哪个服务,前者是为了将正确的服务名称字段添加到日志条目,后者是为了知道正在谈论什么服务。\n它们从Linux获取数据报发送者的进程ID,然后他们去进程表查找该进程属于哪个控制组,从而确定它属于什么服务。
如果发送进程已完成其工作并立即退出,则此操作不起作用(受竞争条件影响)。\n该进程不再位于进程表中。\nsystemd-notify
通知失败;logger
信息不会被标记为属于相关服务。\n切换到流协议(例如使用logger
\'s--tcp
选项)不会解决此问题,除非日志记录协议本身也发生了更改,以便客户端等待服务器的响应在关闭流并退出之前,它不会。\nRFC 5426 没有发送回客户端的服务器确认。
因此,尽管日志信息位于日志中,但它并未用服务名称进行标记,并且当您按服务名称查询时也不会被提取出来。\n(这些并不是您所认为的单独的日志,由方式。\njournalctl
只是将过滤器应用于一个大日志。\n-u
是一个过滤器。)
这是一个长期存在且广为人知的错误。
\n人们systemd
将此描述为 Linux 的缺陷。 \n它没有可用于封装和跟踪进程集的适当作业对象;它的数据报套接字机制也不AF_LOCAL
传输此类信息。\n如果这样做,则systemd
可以将所有服务进程放入一个作业中,并且其日志记录和就绪通知服务器可以在收到数据报时提取客户端作业信息,即使客户端进程已退出。
有一个特定于 的特殊协议system-journald
,某些版本logger
甚至会使用该协议。\n不,_SYSTEMD_UNIT
是在服务器端设置的“可信字段”,客户端设置它的尝试将被忽略;这也是一个基于数据报的异步协议,无需确认。\n它也有完全相同的问题。
要可靠地用正确的服务标记日志条目,请写入标准错误。\n这将是长期存在的,并且可以更可靠地连接到服务器端的服务单元名称。\n是的,您不能指定旧的设施和优先级;这就是你必须做出的权衡。
\n