Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

23.10. 使用日志

Journal 是 systemd 的一个组件,负责查看和管理日志文件。它可以并行使用,也可以代替传统的 syslog 守护进程,如 rsyslogd。该杂志旨在解决与传统记录相关的问题。它与系统的其余部分紧密集成,支持各种日志记录技术和日志文件的访问管理。

日志记录数据由日志的 journald 服务收集、存储和处理。它基于从内核、用户进程、标准输出以及系统服务的标准错误输出或其原生 API 收到的日志信息来创建和维护名为日志的二进制文件。这些日志经过结构化和索引化,可提供相对较快的寻道时间。日志条目可以具有一个唯一标识符。journald 服务为每个日志消息收集大量元数据字段。实际日志文件是安全的,因此无法手动编辑。

23.10.1. 查看日志文件

若要访问日志,可使用 journalctl 工具。对于日志类型的基本视图,以 root 用户身份进行:

journalctl

此命令的输出是系统上生成的所有日志文件的列表,包括系统组件和用户生成的消息。这个输出的结构与 /var/log/messages/ 中使用的结构类似,但有一些改进:

  • 条目的优先级有视觉上的标记。错误优先级和更高的行使用红色颜色突出显示,对于具有 notice 和 warning 优先级的行使用粗体字体
  • 时间戳会转换为您系统的本地时区
  • 显示所有记录的数据,包括轮转的日志
  • 引导的开始带有特殊行的标记

例 23.18. journalctl 输出示例

以下是 journalctl 工具提供的示例输出:如果没有参数调用,列出的条目以时间戳开头,后面提到执行操作的主机名和应用,后面是实际消息。这个示例显示了日志日志中的前三个条目:

# journalctl
-- Logs begin at Thu 2013-08-01 15:42:12 CEST, end at Thu 2013-08-01 15:48:48 CEST. --
Aug 01 15:42:12 localhost systemd-journal[54]: Allowing runtime journal files to grow to 49.7M.
Aug 01 15:42:12 localhost kernel: Initializing cgroup subsys cpuset
Aug 01 15:42:12 localhost kernel: Initializing cgroup subsys cpu

[...]

在许多情形中,日志中只有最新的条目才相关。减少 journalctl 输出的最简单方法是使用 -n 选项,它只列出指定数量的最新日志条目:

journalctl -n Number

使用要显示的行数替换 Number。如果未指定数字,journalctl 将显示最新的十个条目。

journalctl 命令允许使用以下语法控制输出格式:

journalctl -o form

使用指定所需输出格式的关键字替换 form。有多个选项,如 verbose (返回包含所有字段的全结构条目项)、export( 创建 适合备份和网络传输的二进制流)和 json (将条目格式化为 JSON 数据结构)。有关关键字的完整列表,请查看 journalctl(1) 手册页。

例 23.19. 详细 journalctl Output

要查看所有条目的完整元数据,请输入:

# journalctl -o verbose
[...]

Fri 2013-08-02 14:41:22 CEST [s=e1021ca1b81e4fc688fad6a3ea21d35b;i=55c;b=78c81449c920439da57da7bd5c56a770;m=27cc
    _BOOT_ID=78c81449c920439da57da7bd5c56a770
    PRIORITY=5
    SYSLOG_FACILITY=3
    _TRANSPORT=syslog
    _MACHINE_ID=69d27b356a94476da859461d3a3bc6fd
    _HOSTNAME=localhost.localdomain
    _PID=562
    _COMM=dbus-daemon
    _EXE=/usr/bin/dbus-daemon
    _CMDLINE=/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
    _SYSTEMD_CGROUP=/system/dbus.service
    _SYSTEMD_UNIT=dbus.service
    SYSLOG_IDENTIFIER=dbus
    SYSLOG_PID=562
    _UID=81
    _GID=81
    _SELINUX_CONTEXT=system_u:system_r:system_dbusd_t:s0-s0:c0.c1023
    MESSAGE=[system] Successfully activated service 'net.reactivated.Fprint'
    _SOURCE_REALTIME_TIMESTAMP=1375447282839181

[...]

本例列出了标识单个日志条目的字段。这些元数据可用于信息过滤,如 “高级过滤”一节 所示。有关所有可能字段的完整描述请查看 systemd.journal-fields(7) 手册页。

23.10.2. 访问控制

默认情况下,没有 root 特权的 Journal 用户只能查看由他们生成的日志文件。系统管理员可以将选定的用户添加到 adm 组,授予他们完成日志文件的访问权限。要做到这一点,以 root 用户身份输入:

usermod -a -G adm username

此处,将 username 替换为要添加到 adm 组的用户名称。然后,此用户收到与 root 用户相同的 journalctl 命令输出。请注意,只有在为 Journal 启用了持久性存储时访问控制才有效。

23.10.3. 使用实时视图

如果没有参数调用,journalctl 将显示条目的完整列表,从收集的最早条目开始。通过实时视图,您可以在新条目出现时实时管理日志消息。要使用 live view 模式启动 journalctl,请输入:

journalctl -f

此命令返回最新十条日志行的列表。然后 journalctl 实用程序会保持运行并等待新更改立即显示。

23.10.4. 过滤消息

在不使用参数的情况下执行的 journalctl 命令的输出通常很广泛,因此您可以使用各种过滤方法提取信息以满足您的需求。

按优先级过滤

日志消息通常用于跟踪系统上的错误行为。要只查看所选或更高优先级的条目,请使用以下语法:

journalctl -p priority

此处,将 priority 替换为以下关键字之一(或使用编号):debug (7)info(6)、notice (5)、warning (4)、err (3)、crit (2)、警报 (1)和 emerg( 0)。

例 23.20. 按优先级过滤

要只查看优先级为 error 或更高的条目,请使用:

journalctl -p err
按时间过滤

要只从当前引导中查看日志条目,请键入:

journalctl -b

如果您偶尔重新启动系统,-b 不会显著减少 journalctl 的输出。在这种情况下,基于时间的过滤更有用:

journalctl --since=value --until=value

使用 --since--until 时,您只能查看在指定时间范围内创建的日志消息。您可以将值以日期和时间形式传递给这些选项,如下例中所示。

例 23.21. 按时间和优先级过滤

可以组合过滤选项,根据特定请求减少结果集。例如,要从特定时间点查看警告或更高优先级的信息,请输入:

journalctl -p warning --since="2013-3-16 23:59:59"
高级过滤

例 23.19 “详细 journalctl Output” 列出指定日志条目的一组字段,它们都可用于过滤。有关 systemd 可存储的元数据的完整描述,请参阅 systemd.journal-fields(7) 手册页。为每个日志消息收集此元数据,无需用户干预。值通常基于文本,但可以采用二进制和大值;字段可以分配多个值,但并不很常见。

要查看指定字段中出现的唯一值列表,请使用以下语法:

journalctl -F fieldname

使用您感兴趣的字段的名称替换 fieldname

要只显示适合特定条件的日志条目,请使用以下语法:

journalctl fieldname=value

使用字段名称替换 fieldname ,并将值替换为该字段中包含的特定值。因此,只会返回与这个条件匹配的行。

注意

由于 systemd 存储的元数据字段数量非常大,很容易忘记相关字段的确切名称。不确定时,键入:

journalctl

并按 Tab 键两次。这将显示可用字段名称的列表。基于上下文的 Tab 补全基于字段名称,因此您可以从字段名称中键入一组不同的字母,然后按 Tab 键自动填写名称。类似地,您可以从字段中列出唯一值。类型:

journalctl fieldname=

并按 Tab 键两次。这充当 journalctl -F fieldname 的替代选择。

您可以为一个字段指定多个值:

journalctl fieldname=value1 fieldname=value2 ...

为同一字段指定两个匹配项会导致逻辑 OR 匹配项的组合。显示与 value1value2 匹配的条目。

另外,您可以指定多个字段值对来进一步减少输出集:

journalctl fieldname1=value fieldname2=value ...

如果指定了不同字段名称的两个匹配项,则将与逻辑 AND 组合。条目必须与这两个条件匹配。

通过使用 + 符号,您可以为多个字段设置逻辑 OR 匹配项的组合:

journalctl fieldname1=value + fieldname2=value ...

此命令将返回至少匹配其中一个条件的条目,而不仅仅是与这两个条件匹配的条目。

例 23.22. 高级过滤

要显示 user 下由 avahi-daemon. service 或 crond.service 创建的条目,请使用以下命令:

journalctl _UID=70 _SYSTEMD_UNIT=avahi-daemon.service _SYSTEMD_UNIT=crond.service

由于为 _SYSTEMD_UNIT 字段设置了两个值,因此两个结果都将显示,但仅在匹配 _UID=70 条件时才显示。这可以简单地表达为:(UID=70 和(avahi 或 cron)。

您可以在 live-view 模式中应用上述过滤,以跟踪所选日志条目组中的最新更改:

journalctl -f fieldname=value ...

23.10.5. 启用持久性存储

默认情况下,日志仅将日志文件 存储在 内存中或 /run/log/journal/ 目录中的小型环缓冲器中。这足以显示带有 journalctl 的最近日志历史记录。此目录易失性,日志数据不会永久保存。使用默认配置时,syslog 会读取日志并将其存储在 /var/log/ 目录中。启用持久日志记录后,日志文件存储在 /var/log/journal 中,这意味着它们会在重启后保留。然后日志可以替换某些用户的 rsyslog (但请参见章节简介)。

启用的持久性存储有以下优点

  • 记录了更多数据用于在较长时间内进行故障排除
  • 为了立即进行故障排除,重启后可以获得更多数据
  • 服务器控制台当前从日志中读取数据,而不是日志文件

持久性存储也有一些缺点:

  • 即使使用持久性存储,存储的数据量取决于可用内存量,也无法保证覆盖特定的时间范围
  • 日志需要更多磁盘空间

要为 Journal 启用持久存储,请手动创建日志目录,如下例中所示:作为 root 类型:

mkdir -p /var/log/journal/

然后,重启 journald 以应用更改:

systemctl restart systemd-journald