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
匹配项的组合。显示与 value1 或 value2 匹配的条目。
另外,您可以指定多个字段值对来进一步减少输出集:
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