在 RHEL7 上,systemd-journald
接管了许多曾经由rsyslogd
.无论是由于错误还是这两个守护进程之间的冲突,有时/dev/log
都会丢失。因此,依赖该syslog(3)
调用的程序将无法正常运行,包括logger
.如何恢复/dev/log
套接字?
答案1
提出并回答我自己的问题,因为谷歌在这个问题上没有多大帮助。
通常,使用 时rsyslogd
,模块将自行imuxsock
创建套接字,在创建之前取消先前条目的链接。/dev/log
当rsyslogd
停止时(可能是因为配置错误而重新启动失败),rsyslogd 删除 /dev/log
。
然而,提供的 rsyslogRHEL7
预计与 一起使用systemd
,并且该imuxsock
模块将实际打开和删除/run/systemd/journal/syslog
套接字。同时,该设备由触发的/dev/log
系统服务文件创建。systemd-journald.socket
journald
显然,无论是否$imjournal
使用模块,以下内容都有效。
总而言之,如果/dev/log
消失:
重新启动 systemd-journald.socket:
systemctl restart systemd-journald.socket
然后重新启动rsyslogd
systemctl start rsyslogd
更新:我相信如果套接字已经在运行,systemctl restart rsyslogd
可能会重新删除套接字。rsyslogd
答案2
该systemctl restart systemd-journald.socket && systemctl restart rsyslog
解决方案在 Ubuntu 16.04 上对我不起作用。
相反,我必须重新创建/dev/log
以下符号链接/run/systemd/journal/dev-log
:
ln -s /run/systemd/journal/dev-log /dev/log
答案3
我不确定 systemd 和 rsyslog 的具体工作原理,但我修补了一段时间,发现了/dev/log
消失的原因以及如何恢复它。
正如前面的答案中提到的,如果在 中设置了 imuxsock 模块,Rsyslog 将/dev/log
在服务启动时自行生成套接字/etc/rsyslog.conf
,并在服务停止后删除该套接字。根据imuxsock 文档,如果套接字不是通过 systemd 传入的,则 rsyslog 只会删除该套接字。在这种情况下,/dev/log
套接字是通过 rsyslog 而不是 systemd 传入的,因此,如果服务停止,它将删除套接字。
默认情况下(我使用的是 Fedora 36),rsyslog 使用 imuxsock 模块,但带有“SysSock.Use=off”参数。这样,rsyslog 将不会使用系统日志套接字 ( /dev/log
) 作为其套接字,因此不会生成/dev/log
.在 中使用此配置 ( module(load="imuxsock" SysSock.use="off")
) 将/etc/rsyslog.conf
导致 rsyslog 不记录任何内容。
不过,还有一个默认加载的模块,那就是 imjournal 模块。这将获得 rsyslog 对 systemd 日志的访问权限。据我了解, rsyslog 不会生成套接字/dev/log
,而是 systemd-journal-dev-log.socket 会生成套接字。该/dev/log
套接字将被符号链接到/run/systemd/journal/dev-log
.即使 module(load="imuxsock" SysSock.use="off")
使用了,rsyslog 仍然会记录活动,因为它从 systemd 日志中提取数据。现在/dev/log -> /run/systemd/journal/dev-log
已创建,rsyslog 不会删除它,因为套接字是通过 systemd 传入的。
根据我的尝试,/dev/log
可能会消失,因为稍后添加或取消注释“SysSock.use=off”参数/etc/rsyslog.conf
(即使加载了 imjournal 模块)。这告诉 rsyslog 不要生成/dev/log
.
可以说,重新添加imjournal模块并重启服务就可以解决这个问题;然而,令人困惑的部分是这不起作用并且/dev/log -> /run/systemd/journal/dev-log
找不到。这是因为 systemd-journald-dev-log.socket 服务不知道套接字/dev/log
丢失。因此,重新启动此服务会触发套接字丢失,然后重新启动 systemd-journald.socket 将解决此问题。虽然我不确定重新启动 systemd-journald-dev-log.socket 服务是否可以,但这会使套接字/dev/log
恢复。
总之,执行以下操作来恢复套接字/dev/log
:
- 确保您有这些
/etc/rsyslog.conf
:module(load="imuxsock" SysSock.use="off")
module(load="imjournal" StateFile="imjournal.state")
- 重新启动rsyslog
# systemctl restart rsyslog
- 重新启动 systemd-journald-dev-log.socket (您可能会看到“作业失败。请参阅“journalctl -xe”了解详细信息。”警告,但我认为没关系,因为它立即停止并启动)
# systemctl restart systemd-journald-dev-log.socket
- 重新启动 systemd-journald.socket
# systemctl restart systemd-journald.socket
注 1:据我了解,这只适用于 RHEL 系统。 Debian或基于Ubuntu的系统可能没有这个问题,或者有不同的解决方法
注2:对于这个冗长且令人困惑的答案,我深表歉意。这是我第一次来这里,我还是个新手:D
答案4
对我来说,这最终成为 rsyslog 中使用的 imuxsock 模块如何与 systemd 一起工作的问题。
在里面imuxsock 文档他们介绍了该模块如何为 systemd 工作。第 1 步是我发现问题的地方:
第 1 步:选择系统套接字名称
如果用户没有明确选择设置 SysSock.Use="off",则默认侦听器套接字(也称为“系统日志套接字”或简称为“系统套接字”)名称将设置为 /dev/log。否则,如果用户已显式设置 SysSock.Use="off",则 rsyslog 将不会侦听 /dev/log 或由 SysSock.Name 参数定义的任何套接字,并且本节的其余部分不适用。
如果用户已指定 sysSock.Name="/path/to/custom/socket" (并且未显式设置 SysSock.Use="off"),则默认侦听器套接字名称将被 /path/to/custom/socket 覆盖。
否则,如果 rsyslog 在 systemd 下运行且 /run/systemd/journal/syslog 存在(并且用户未显式设置 SysSock.Use="off"),则默认侦听器套接字名称将被 /run/systemd/journal 覆盖/系统日志。
系统应该已经进入步骤 3,并将默认路径更改为“/run/systemd/journal/syslog”,但它仍然保留“/var/log”。这意味着 imuxsock 模块会尝试(有时会成功)在 /dev/log 处创建一个套接字,其中应该有由 systemd-journald-dev-log.socket 创建的符号链接。如果无法创建真正的套接字,符号链接仍然会被删除。
该文档的结果是这个问题报告在 rsyslog github 上。如果您想跳过讨论并直接跳至更改,请参阅公关#1和公关#2分别。
我的解决方案是仅配置 imuxsock 模块以使用 /etc/rsyslog.conf 中的 systemd 路径:
module(load="imuxsock"
SysSock.Name="/run/systemd/journal/syslog")
这似乎解决了我的问题,并且听起来像是一个很好的解决方案,因为它可以解释为什么符号链接在您手动创建后可能会再次消失。
如果您查看系统并且“/run/systemd/journal/syslog”不存在,请查看“syslog.socket”以查看它是否成功启动,因为这是负责创建套接字的。
systemctl status syslog.socket
可能是您的 rsyslog.service 版本没有将 syslog.service 定义为 syslog.socket 尝试激活该服务时需要的别名。多个日志记录服务也可能尝试为 syslog.service 建立别名,在这种情况下,最后启用的服务获胜。