如何使用 journalctl 读取 Linux 系统日志

深入解析 Linux 系统日志:`journalctl` 命令详解

随着 systemd 的引入,Linux 系统日志管理方式发生了显著变化。本文将深入探讨如何利用 `journalctl` 命令来读取和过滤系统日志信息,助您更好地理解和管理您的 Linux 系统。

集中式日志管理

systemd 作为系统和服务管理器,对系统日志的收集方式进行了重大革新。过去,日志分散在文件系统的不同位置,依赖于生成日志的服务或守护进程。这些日志文件虽然位置各异,但都有一个共同的特点:它们都是纯文本格式。

而 systemd 将所有系统、启动以及内核日志文件集中到一个专用的日志解决方案中进行管理。这些日志以二进制格式存储,这使得数据提取更加灵活,例如可以方便地导出为 JSON 格式,后续我们将详细介绍。

这种集中式管理还使得交叉引用原本分散在不同日志文件中的信息变得更加容易。由于所有数据都存储在单一日志中,我们可以选择多个来源的数据,并将它们以交错的列表形式呈现。

`journalctl` 是与系统日志服务交互的关键工具,您可以参考 官方文档 获取更多信息。

`journalctl` 的基本使用

最简单的用法是直接在命令行中输入 `journalctl`,无需任何参数:

journalctl

这会显示整个日志,最旧的条目会出现在列表顶部。日志内容会通过 `less` 程序展示,您可以使用 `less` 的常用快捷键进行分页和搜索。您还可以使用左右箭头键横向滚动以阅读较宽的日志条目。

按下 `End` 键可以直接跳转到列表底部,查看最新的日志条目。

按下 `Ctrl+C` 可以退出 `journalctl`。

虽然可以直接调用 `journalctl` 而无需 `sudo`,但如果您希望查看所有细节,建议使用 `sudo`,以确保您能看到所有日志信息。

sudo journalctl

如果希望将输出直接发送到终端窗口,而不是通过 `less` 程序查看,可以使用 `–no-pager` 选项:

sudo journalctl --no-pager

此时,输出会在终端窗口中快速滚动,然后您会回到命令提示符。

如果想要限制 `journalctl` 返回的行数,可以使用 `-n` 选项,后面跟上需要的行数。 例如,以下命令会请求输出最近的十行日志:

sudo journalctl -n 10

实时追踪日志更新

要使 `journalctl` 在有新的日志条目到达时实时显示它们,可以使用 `-f`(跟随)选项:

sudo journalctl -f

最新的条目的时间戳是 07:09:07。随着新事件的发生,新的条目将自动添加到显示结果的底部。这是一个近乎实时的更新,非常方便!

在 07:09:59,一个名为 `geek-app` 的应用程序向日志中写入了一条消息 “来自 HTG 的新消息”。

改变输出格式

由于日志数据以二进制格式存储,我们需要对其进行解析或转换才能以文本形式展示。通过使用不同的解析器,我们可以从同一二进制源数据创建不同的输出格式。`journalctl` 支持多种不同的格式。

默认输出格式是 `short` 格式,它类似于传统的系统日志格式。 如果需要明确指定 `short` 格式,可以使用带有 `short` 修饰符的 `-o`(输出)选项:

sudo journalctl -n 10 -o short

从左到右,这些字段依次是:

  • 消息创建的时间(以本地时间表示)。
  • 主机名。
  • 进程名称(生成消息的进程)。
  • 日志消息内容。

要获得完整的日期和时间戳,可以使用 `short-full` 修饰符:

sudo journalctl -n 10 -o short-full

这种输出格式中的日期和时间格式,也正是我们在根据时间段选择日志消息时需要提供的格式,我们稍后会看到如何使用时间段来过滤日志。

要查看每条日志消息附带的所有元数据,可以使用 `verbose` 修饰符:

sudo journalctl -n 10 -o verbose

这里有很多可能的字段,但并非所有字段都会出现在每条消息中。

其中一个值得关注的字段是 “优先级”(priority)。在此示例中,它的值为 6。 该值表示消息的重要性:

  • 0:紧急。系统不可用。
  • 1:警报。已标记需要立即更正的情况。
  • 2:关键。包括主要应用程序中的崩溃、核心转储和重大故障。
  • 3:错误。报告的错误,但不被认为是严重的。
  • 4:警告。提醒您注意一个条件,如果忽略该条件,可能会成为错误。
  • 5:通知。用于报告异常事件,但不报告错误。
  • 6:信息。常规操作消息,这些不需要采取任何措施。
  • 7:调试。在应用程序中插入的消息,以便更容易调试它们。

如果您希望输出格式为标准的 JavaScript 对象表示法 (JSON) 对象,可以使用 `json` 修饰符:

sudo journalctl -n 10 -o json

每条消息都被正确地包装成格式良好的 JSON 对象,每一行输出显示一条消息。

如果需要 格式化输出 JSON,可以使用 `json-pretty` 修饰符:

sudo journalctl -n 10 -o json-pretty

每个 JSON 对象都被拆分为多行,每个名称-值对都显示在新的一行上。

如果您只想查看日志条目的消息内容,而不包含时间戳或其他元数据,可以使用 `cat` 修饰符:

sudo journalctl -n 10 -o cat

尽管一些消息确实包含一些线索,但这种显示格式可能很难确定是哪个进程触发了日志事件。

按时间段选择日志消息

要限制 `journalctl` 的输出,使其只显示您感兴趣的时间段内的日志,可以使用 `-S`(自)和 `-U`(直到)选项。

要查看自特定日期和时间以来的日志条目,可以使用以下命令:

sudo journalctl -S "2020-01-12 07:00:00"

这将只显示在命令中指定的时间和日期之后产生的消息。

要定义您想要报告的时间段,请同时使用 `-S`(自)和 `-U`(直到)选项。以下命令将查看 15 分钟时间段内的日志消息:

sudo journalctl -S "2020-01-12 07:00:00" -U "2020-01-12 07:15:00"

如果您知道系统上发生了一些异常,并且大致知道发生的时间,这是一个很有用的组合。

使用相对时间段

您可以使用相对时间寻址来选择时间段。这意味着您可以说“显示从一天前到现在的所有事件”。 这正是以下命令的含义。“d”代表“天”,“-1”代表过去的一天。

sudo journalctl -S -1d

这会列出从昨天 00:00:00 到当前时间的所有日志消息。

如果您想调查最近发生的事情,可以指定以小时为单位的相对时间段。在这里,我们将查看过去一小时的日志消息:

sudo journalctl -S -1h

这将显示上一小时的消息。 您还可以使用 “m” 设置以分钟为单位的相对时间段,并使用 “w” 设置以周为单位的时间段。

`journalctl` 也可以理解 today、yesterday 和 tomorrow 等相对时间修饰符。这些修饰符提供了一种方便的方式来指定常见的时间段。要查看昨天发生的所有事件,可以使用以下命令:

sudo journalctl -S yesterday

这将检索并显示昨天发生的所有日志事件,直到午夜 00:00:00。

要查看今天收到的所有日志消息,可以使用以下命令:

sudo journalctl -S today

这将显示从 00:00:00 到发出命令时的所有日志消息。

您可以混合使用不同的时间段修饰符。 要查看从两天前到今天开始的所有内容,可以使用以下命令:

sudo journalctl -S -2d -U today

这将检索并显示从前天到今天的所有日志消息。

按数据字段选择日志消息

您可以使用 多种日志字段来搜索日志消息。这些搜索会尝试在附加到每条消息的元数据中找到匹配项。建议您参考字段列表并选择对您最有用的字段。

请记住,是否填充每个字段完全取决于应用程序的作者,所以您不能保证每个字段都会被填充。

所有日志字段修饰符都以相同的方式使用。我们将在以下示例中使用一些修饰符。要查找来自特定应用程序的日志消息,可以使用 `_COMM`(命令)修饰符。如果您还使用了 `-f`(跟随)选项,`journalctl` 将在来自此应用程序的新消息到达时对其进行跟踪。

sudo journalctl -f _COMM=geek-app

您可以使用进程号来查找生成日志消息的进程。可以使用 `ps` 命令查找您想要搜索的守护程序或应用程序的进程 ID。

sudo journalctl _PID=751

在用于撰写本文的机器上,SSH 守护进程的进程 ID 为 751。

您也可以通过以下方式搜索 用户标识符。这指的是启动应用程序或命令的用户或拥有该进程的用户 ID。

sudo journalctl _UID=1000

与任何其他用户 ID 关联的所有消息都将被过滤掉。 只会显示与用户 1000 相关的消息:

另一种搜索与特定应用程序相关的日志消息的方法是提供可执行文件的路径。

sudo journalctl /usr/bin/anacron

这将检索并显示所有 `anacron` 调度程序的日志消息

为了使搜索更容易,我们可以让 `journalctl` 列出它保存的所有值,用于任何日志字段。

要查看 `journalctl` 为其记录日志消息的用户 ID,请使用 `-F`(字段)选项,并传递 `_UID` 字段标识符:

journalctl -F _UID

让我们再做一次,看看组 ID(GID):

journalctl -F _GID

您可以使用任何 日志字段标识符

列出内核消息

有一种内置方法可以快速隔离内核消息,无需手动搜索。使用 `-k`(内核)选项可以排除所有其他消息,并立即查看内核日志条目。

sudo journalctl -k

根据 `Priority` 字段中的值,系统会高亮显示来反映消息的重要性。

查看启动消息

如果您遇到与启动相关的问题需要调查,`journalctl` 可以提供帮助。例如,您添加了新的硬件,但它没有响应;或者在上次系统升级后,先前工作的硬件组件不再工作。

要查看与上次启动相关的日志条目,请使用 `-b`(启动)选项:

journalctl -b

这将显示上次启动时的日志条目。

当提到“最后一次启动”时,我们指的是当前登录会话中计算机的启动过程。要查看以前的启动,可以使用数字来指定你感兴趣的启动次数。要查看第三次之前的启动,可以使用以下命令:

journalctl -b 3

通常,如果您遇到问题并且必须重新启动计算机,那么您最感兴趣的往往是前一次启动的顺序。因此,这是一种常用的命令形式。

启动的顺序很容易混淆。 为了提供帮助,我们可以让 `journalctl` 使用 `–list-boots` 选项来列出它在其日志中记录的启动信息。

journalctl --list-boots

您可以从日期和时间戳中识别您希望查看消息的启动,然后使用左侧列中的数字来获取该启动序列的日志消息。您还可以选择 32 位启动标识符,并将其传递给 `journalctl`。

sudo journalctl -b 1f00248226ed4ab9a1abac86e0d540d7

这将检索并显示来自我们请求的启动序列的日志消息。

管理日志磁盘空间

日志及其所有日志消息都存储在您的硬盘上,这意味着它们会占用磁盘空间。要查看日志占用了多少空间,可以使用 `–disk-usage` 选项。

journalctl --disk-usage

对于现代硬盘来说,152MB 的空间并不算多,但出于演示目的,我们仍然会减少它。我们有两种方法可以做到这一点。第一种方法是设置您希望日志缩小到的限制大小。当然,它会再次增长,但是我们可以通过修剪为新的增长做好准备。

我们将使用 `–vacuum-size` 选项,并传递我们希望日志缩小到的大小。 我们将要求 100 MB。您可以理解为我们要求 `journalctl` “尽可能丢弃任何东西,但不要低于 100 MB”。

journalctl --vacuum-size=100M

另一种缩减日志大小的方法是使用 `–vacuum-time` 选项。此选项告诉 `journalctl` 丢弃早于您在命令行中提供的时间段的消息。您可以在时间段中使用天、周、月和年。

让我们清除所有超过一周的消息:

journalctl --vacuum-time=1weeks

数据转化为信息

除非能够获取并加以利用,否则数据是毫无价值的。只有被利用的数据才能转化为有用的信息。`journalctl` 命令是一个灵活而强大的工具,它允许您以多种方式获取您感兴趣的信息。

您几乎可以使用您必须掌握的任何信息片段来检索所需的日志消息。