调试锁定 - systemd 丢失我的日志

调试锁定 - systemd 丢失我的日志

自从我在 Arch Linux 上“升级”到 systemd 以来,当意外锁定发生时,我不断丢失日志。我打同样的日志丢失问题一个月前,刚刚再次遇到这个问题。还有独立的其他确认书

情况:

  • 在使用 Java 和网络相关实用程序做一些事情时,我发现 KDE(时钟)被冻结了。 CPU风扇变得嘈杂,热量不断上升。但鼠标指针仍然可以移动。
  • 我尝试从另一台机器进行 ssh(由于“没有到主机的路由”而失败)
  • 我等了几分钟,也许 NMI 看门狗可以杀死这个有问题的任务。没有骰子。
  • Ctrl+ Alt+F1也不起作用,即使在SysRq+之后R
  • 由于上述步骤不起作用,我决定发出 SysRq 序列 REI。之后E,屏幕变黑,但也没有控制台。甚至在SysRq+之后也不行K
  • 所以,这个会话似乎丢失了,唯一能做的就是收集调试信息。看着维基百科,我决定按SysRq+ d(显示已锁定)等。
  • SysRq按+后,S我等了一秒钟,然后用SysRq+重新启动B
  • 重新启动并登录控制台后,我没有看到任何崩溃的痕迹。最近记录的条目来自使用 Wireshark,但仍有 45 分钟的时间间隔。

(顺便说一句,我正在运行 Linux v3.8-rc5-218-ga56e160)

那么,如何确保在因锁定而异常重启时保留我的日志呢?

答案1

于是我在 #systemd IRC 频道上询问,结果发现 journald(systemd 的日志守护进程)根本不会定期将日志刷新到磁盘。这意味着您的日志随时都处于危险之中。

发送SIGUSR2journald日志会导致日志写入磁盘,但如果多次执行此操作,将会创建许多文件。 (该选项实际上被描述为“日志旋转”)。

最后,我决定采用另一个建议:使用专用的 syslog 守护进程来收集内核日志。由于建议了 rsyslog(而且我已经有过使用它的经验),我进一步探索了该选项。我在 中写了更多详细信息拱门维基关于使用 rsyslog。

这个想法是运行 rsyslog,仅收集来自内核设施的数据。由于 rsyslog 读取/proc/kmsg(仅允许单个读取器)和 Journald 读取/dev/kmsg(允许多个读取器),守护进程不可能丢失日志(对我来说非常重要!)。配置 rsyslog 以将内核消息写入文件,并确保轮换该文件以防止占用磁盘空间。

这个解决方案并不完美:

  • 其他日志(例如来自 NetworkManager 的日志)会丢失。这可以通过以下方式解决将更多日志从 syslog 转发到 Journald(这意味着重复!)
  • 日志重复。内核消息被写入两个文件。这不是问题,一般来说,日志的数量很少,您宁愿拥有更多的日志副本,也不愿没有。您还可以使用快速工具,例如grep单个日志文件或更慢但更高级的工具journalctl

有一个待办事项用于更频繁地刷新日志,但这仍然不够可靠:

日志:时不时地发送标记消息,然后立即与 fdatasync() 同步,以便每小时保证同步。

现在,希望 systemd/journald 能够选择将日志写入磁盘,但同时我们可以结合工具来实现目标。

答案2

有两个更新:

  1. 现在,希望 systemd/journald 能够选择将日志写入磁盘,但同时我们可以结合工具来实现目标。

有一个选项--sync:

要求日志守护进程将所有未写入的日志数据写入支持文件系统并同步所有日志。在同步操作完成之前,此调用不会返回。此命令保证在调用之前写入的任何日志消息在返回时都安全地存储在磁盘上。

--sync可用自v228:

Journalctl 获得了一个新的“--sync”开关,该开关要求日志守护进程在返回之前将所有迄今为止未写入的日志消息写入磁盘并同步文件。

  1. 事实证明,journald(systemd 的日志守护进程)根本不会定期将日志刷新到磁盘。这意味着您的日志随时都面临风险。

man journald.conf(5)说:

同步间隔秒=

将日志文件同步到磁盘之前的超时时间。同步后,日志文件将处于 OFFLINE 状态。请注意,在记录优先级 CRIT、ALERT 或 EMERG 的日志消息后,同步将立即无条件完成。因此,此设置仅适用于 ERR、WARNING、NOTICE、INFO、DEBUG 级别的消息。默认超时为 5 分钟。

SyncIntervalSec=可用自v199:

现在,journald 将在每次写入后最晚 5 分钟将日志文件显式刷新到磁盘。然后,该文件也将被标记为脱机,直到下次写入。这应该会提高发生碰撞时的可靠性。同步延迟可以通过journald.conf中的SyncIntervalSec=进行配置。

也可以看看:

Journald:以低优先级发送 SIGTERM/SIGINT

让我们确保在退出之前处理所有排队的日志数据,这样我们就不会在关闭时丢失不必要的消息。

相关内容