如何在 systemd+rsyslog 主机中恢复 `/dev/log`?

如何在 systemd+rsyslog 主机中恢复 `/dev/log`?

在 RHEL7 上,systemd-journald接管了许多曾经由rsyslogd.无论是由于错误还是这两个守护进程之间的冲突,有时/dev/log都会丢失。因此,依赖该syslog(3)调用的程序将无法正常运行,包括logger.如何恢复/dev/log套接字?

答案1

提出并回答我自己的问题,因为谷歌在这个问题上没有多大帮助。

通常,使用 时rsyslogd,模块将自行imuxsock创建套接字,在创建之前取消先前条目的链接。/dev/logrsyslogd停止时(可能是因为配置错误而重新启动失败),rsyslogd 删除 /dev/log

然而,提供的 rsyslogRHEL7预计与 一起使用systemd,并且该imuxsock模块将实际打开和删除/run/systemd/journal/syslog套接字。同时,该设备由触发的/dev/log系统服务文件创建。systemd-journald.socketjournald

显然,无论是否$imjournal使用模块,以下内容都有效。

总而言之,如果/dev/log消失:

  1. 重新启动 systemd-journald.socket:

    systemctl restart systemd-journald.socket
    
  2. 然后重新启动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

  1. 确保您有这些/etc/rsyslog.conf
    • module(load="imuxsock" SysSock.use="off")
    • module(load="imjournal" StateFile="imjournal.state")
  2. 重新启动rsyslog
    # systemctl restart rsyslog
    
  3. 重新启动 systemd-journald-dev-log.socket (您可能会看到“作业失败。请参阅“journalctl -xe”了解详细信息。”警告,但我认为没关系,因为它立即停止并启动)
    # systemctl restart systemd-journald-dev-log.socket
    
  4. 重新启动 systemd-journald.socket
    # systemctl restart systemd-journald.socket
    

注 1:据我了解,这只适用于 RHEL 系统。 Debian或基于Ubuntu的系统可能没有这个问题,或者有不同的解决方法

注2:对于这个冗长且令人困惑的答案,我深表歉意。这是我第一次来这里,我还是个新手:D

答案4

对我来说,这最终成为 rsyslog 中使用的 imuxsock 模块如何与 systemd 一起工作的问题。

在里面imuxsock 文档他们介绍了该模块如何为 systemd 工作。第 1 步是我发现问题的地方:

第 1 步:选择系统套接字名称

  1. 如果用户没有明确选择设置 SysSock.Use="off",则默认侦听器套接字(也称为“系统日志套接字”或简称为“系统套接字”)名称将设置为 /dev/log。否则,如果用户已显式设置 SysSock.Use="off",则 rsyslog 将不会侦听 /dev/log 或由 SysSock.Name 参数定义的任何套接字,并且本节的其余部分不适用。

  2. 如果用户已指定 sysSock.Name="/path/to/custom/socket" (并且未显式设置 SysSock.Use="off"),则默认侦听器套接字名称将被 /path/to/custom/socket 覆盖。

  3. 否则,如果 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 建立别名,在这种情况下,最后启用的服务获胜。

相关内容