systemd/Journal (日志)
systemd 拥有自己的日志系统,称为 journal;无需运行单独的日志守护进程。
systemd 日志根据 优先级 和 设施 对消息进行分类。日志分类符合经典的 Syslog 协议(RFC 5424)。
访问日志
日志通过 journalctl(1) 读取,通常有两种方式:检查历史日志,或实时查看新记录。对于前者,-e/--pager-end 选项通常很有用;后者则通过 -f/--follow 选项启用。
-n/--lines 行为,除非在命令行中其他地方指定了该选项。过滤输出
journalctl 允许通过多种方式过滤输出。这在日志过多导致 journalctl 难以实时显示时非常有用……
非选项参数支持按日志字段(例如 _PID=1,请参阅 systemd.journal-fields(7))、可执行文件路径或内核设备进行过滤,详见 journalctl(1) § DESCRIPTION。更多示例请参阅 Lennart Poettering 的博客文章。
其他选项的完整列表及上述命令的简写形式可参见 journalctl(1) § FILTERING OPTIONS,以下是最常见的选项:
- 显示所有匹配
PATTERN的消息# journalctl --grep=PATTERN
- 应优先使用此方法而非
journalctl | grep,因为它避免了 journalctl 进行额外的工作后又被丢弃。
- 包含来自消息目录的消息解释(如果可用)
# journalctl --catalog
请注意,在将日志附加到错误报告和支持帖子时,不应使用此功能,以限制不必要的输出。您可以通过运行journalctl --list-catalog来列出所有已知目录条目。 - 显示自指定时间以来的所有消息(systemd.time(7) § PARSING TIMESTAMPS)
# journalctl --since="2012-10-30 18:17:16"
# journalctl --since "20 min ago" - 显示当前引导的所有消息
# journalctl --boot
- 显示特定标识符的所有消息
# journalctl --identifier sudo
- 显示特定单元的所有消息:(可省略
.service后缀)# journalctl --unit man-db.service
- 请注意,用户服务 (user services) 需要使用
--user-unit代替$ journalctl --user-unit dbus
- 仅显示错误 (error)、严重 (critical) 和警报 (alert) 优先级 的消息
# journalctl --priority err..alert
您也可以使用数字日志级别,例如journalctl -p 3..1。如果使用单个数字/日志级别,例如journalctl -p 3,那么所有更高优先级的日志级别也将包含在内(即此情况下的 0 到 3)。 - 如果 journal 目录(默认位于
/var/log/journal下)包含大量日志数据,那么journalctl可能需要几分钟才能过滤输出。通过使用--file选项强制journalctl只查看最新的 journal,可以显著加快速度。# journalctl --file /var/log/journal/*/system.journal -f
指定另一个Journal进行查看
有时可能需要检查无法启动的系统的日志,例如从 Live 系统引导以恢复生产环境。在这种情况下,可以将磁盘挂载到例如 /mnt,并通过 -D/--directory 指定日志路径,如下所示:
# journalctl -D /mnt/var/log/journal -e
不使用 journalctl 查看日志
虽然日志以二进制格式存储,但存储的消息内容并未被修改。
这意味着可以使用 strings 查看,例如在未安装 systemd 的环境中进行恢复时,例如:
$ strings /mnt/arch/var/log/journal/af4967d77fba44c6b093d0e9862f6ddd/system.journal | grep -i message
日志级别
Syslog 严重性代码(在 systemd 中称为优先级)用于标记消息的重要性 RFC 5424 6.2.1。
| 值 | 严重程度 | 关键字 | 描述 | 示例 |
|---|---|---|---|---|
| 0 | Emergency | emerg | 系统不可用 | 严重的内核 BUG,systemd 已转储核心。 应用程序不应使用此级别。 |
| 1 | Alert | alert | 应立即纠正 | 关键子系统停止工作。数据丢失。kernel: BUG: unable to handle kernel paging request at ffffc90403238ffc.
|
| 2 | Critical | crit | 关键条件 | 崩溃,核心转储。如同熟悉的闪光systemd-coredump[25319]: Process 25310 (plugin-containe) of user 1000 dumped core系统主应用程序(如 X11)发生故障。 |
| 3 | Error | err | 错误条件 | 报告了非致命错误kernel: usb 1-3: 3:1: cannot get freq at ep 0x84,systemd[1]: Failed unmounting /var.,libvirtd[1720]: internal error: Failed to initialize a valid firewall backend
|
| 4 | 警告 | warning | 可能表明如果不采取行动将会发生错误 | 非根文件系统仅剩 1GB 空间。org.freedesktop.Notifications[1860]: (process:5999): Gtk-WARNING **: Locale not supported by C library. Using the fallback 'C' locale
|
| 5 | Notice | notice | 不寻常但并非错误状况的事件 | systemd[1]: var.mount: Directory /var to mount over is not empty, mounting anyway,gcr-prompter[4997]: Gtk: GtkDialog mapped without a transient parent. This is discouraged
|
| 6 | Informational | info | 不需要操作的正常运行消息 | lvm[585]: 7 logical volume(s) in volume group "archvg" now active
|
| 7 | Debug | debug | 可能需要先启用才能使用的消息,仅对调试有用 | kdeinit5[1900]: powerdevil: Scheduling inhibition from ":1.14" "firefox" with cookie 13 and reason "screen"
|
这些规则是建议,给定错误的优先级级别由应用程序开发人员自行决定。错误总是可能比预期的高或低的级别。
日志源
Syslog facility 代码用于指定记录消息的程序类型 RFC 5424 6.2.1。
| 日志源代码 | 关键字 | 描述 | 信息 |
|---|---|---|---|
| 0 | kern | 内核消息 | |
| 1 | user | 用户级别消息 | |
| 2 | 邮件系统 | 仍然支持并有时使用的古老 POSIX (有关更多 mail(1)) | |
| 3 | daemon | 系统守护进程 | 所有守护进程,包括 systemd 及其子系统 |
| 4 | auth | 安全/授权消息 | 同时关注不同的日志源 10 |
| 5 | syslog | syslogd 内部生成的消息 | 用于 syslogd 实现(systemd 不使用,请参见日志源 3) |
| 6 | lpr | 行式打印机子系统(古老子系统) | |
| 7 | news | 网络新闻子系统(古老子系统) | |
| 8 | uucp | UUCP 子系统(古老子系统) | |
| 9 | 时钟守护进程 | systemd-timesyncd | |
| 10 | authpriv | 安全/授权消息 | 同时关注不同的日志源 4 |
| 11 | ftp | FTP 守护进程 | |
| 12 | - | NTP 子系统 | |
| 13 | - | 日志审计 | |
| 14 | - | 日志警报 | |
| 15 | cron | 调度守护进程 | |
| 16 | local0 | 本地使用 0 (local0) | |
| 17 | local1 | 本地使用 1 (local1) | |
| 18 | local2 | 本地使用 2 (local2) | |
| 19 | local3 | 本地使用 3 (local3) | |
| 20 | local4 | 本地使用 4 (local4) | |
| 21 | local5 | 本地使用 5 (local5) | |
| 22 | local6 | 本地使用 6 (local6) | |
| 23 | local7 | 本地使用 7 (local7) |
要关注的有用日志源:0, 1, 3, 4, 9, 10, 15。
日志存储
在 Arch Linux 中,目录 /var/log/journal/ 是 systemd 软件包的一部分。由于日志的默认模式为 Storage=persistent,日志将写入 /var/log/journal/,如果目录不存在则会自动创建。如果手动配置为 Storage=auto,systemd 则会以非持久方式将日志写入 /run/log/journal/。
Journal大小限制
持久日志的默认大小限制(默认模式下)为底层文件系统大小的 10%,上限为 4 GiB。例如,如果 /var/log/journal/ 位于 20 GiB 的分区上,日志数据最多占用 2 GiB。在 50 GiB 的分区上,最多占用 4 GiB。要确认系统当前的限制,请查看 systemd-journald 的单元日志。
# journalctl -b -u systemd-journald
可以通过取消注释并更改以下内容来控制持久 journal 的最大大小:
/etc/systemd/journald.conf
SystemMaxUse=50M
SystemMaxUse 设置较大,仍可能受到默认 SystemKeepFree 参数的限制(设置为底层文件系统的 15%)。日志守护进程将遵循这两个参数,并使用两者中的较小值。也可以使用 drop-in snippets 配置覆盖机制,而不是编辑全局配置文件。在这种情况下,请将覆盖项放在 [Journal] 标题下:
/etc/systemd/journald.conf.d/00-journal-size.conf
[Journal] SystemMaxUse=50M
更改此设置后,请 重启 systemd-journald.service 以应用新的限制。
有关更多信息,请参阅 journald.conf(5)。
手动清理Journal文件
可以使用 e.g. rm 从 /var/log/journal/ 全局删除 Journal 文件,或者使用 journalctl 根据各种标准进行修剪。例如:
- 删除归档的 Journal 文件,直到它们占用的磁盘空间低于 100M
# journalctl --vacuum-size=100M
- 使所有 Journal 文件包含不早于 2 周前的数据。
# journalctl --vacuum-time=2weeks
Journal 文件必须已被轮换并变为非活动状态,然后才能被 vacuum 命令修剪。Journal 文件的轮换可以通过运行 journalctl --rotate 来完成。--rotate 参数也可以与一个或多个 vacuum 标准参数一起提供,以在单个命令中执行轮换然后修剪文件。
有关更多信息,请参阅 journalctl(1)。
技巧与提示
通过Journal命名空间按单元限制大小
编辑要配置的服务(例如 sshd)的单元文件,并在 [Service] 部分添加 LogNamespace=ssh。
然后通过复制 /etc/systemd/journald.conf 来创建 /etc/systemd/journald@ssh.conf。之后,编辑 journald@ssh.conf 并根据需要调整 SystemMaxUse。
重启该服务应该会自动启动新的 journal 服务 systemd-journald@ssh.service。可以使用 journalctl --namespace ssh 查看来自命名空间服务的日志。
有关 journal 命名空间的详细信息,请参阅 systemd-journald.service(8) § JOURNAL NAMESPACES。
Journald与Syslog的结合使用
通过让 systemd 通过套接字 /run/systemd/journal/syslog 转发所有消息,可以与经典的、不了解 journal 的 syslog 实现保持兼容。要使 syslog 守护进程与 journal 一起工作,它必须绑定到此套接字而不是 /dev/log (官方公告)。
转发到套接字的默认 journald.conf 设置是 ForwardToSyslog=no,以避免系统开销,因为 rsyslog 或 syslog-ng 会自己从 journal 拉取消息。
有关配置的详细信息,请参阅 Syslog-ng#Overview 和 Syslog-ng#syslog-ng and systemd journal,或 rsyslog。
将Journald转发到 /dev/tty12
创建一个 drop-in 目录 /etc/systemd/journald.conf.d 并在其中创建一个 fw-tty12.conf 文件:
/etc/systemd/journald.conf.d/fw-tty12.conf
[Journal] ForwardToConsole=yes TTYPath=/dev/tty12
然后 重启 systemd-journald.service。
- 按照设计,这不会转发内核环缓冲区 (kernel ring log) 消息。
- 这不一定要使用 TTY 12,但该 TTY 必须未被其他进程控制。特别是,如果您希望使用 TTY 1 到 6,请参阅 getty#Add additional virtual consoles。
以用户身份访问Journal
默认情况下,普通用户只能访问他们自己的每个用户 journal。要授予普通用户对系统 journal 的读取访问权限,您可以将该用户添加到 systemd-journal 用户组。adm 和 wheel 组的成员也具有读取访问权限。
有关更多信息,请参阅 journalctl(1) § DESCRIPTION 和 Users and groups#User groups。
桌面通知
桌面通知可以帮助您快速注意到错误消息,与手动检查日志或根本不注意到它们相比,可以提高意识。
journalctl-desktop-notificationAUR 包为任何进程记录的每条错误消息提供自动桌面通知。有关更多详细信息和配置选项,请访问 GitLab 项目页面。
隐藏主机名
默认情况下,journalctl(1) 会显示生成日志的机器的主机名,这在同时查看多台机器(可能在不同终端上)的日志时非常有用。但在其他情况下,使用 -W/--no-hostname 选项可以帮助缩短行长度。
自动换行而非截断日志行
默认情况下,journalctl 会截断超过屏幕宽度的行,但在某些情况下,启用换行可能比截断更好。这可以通过 SYSTEMD_LESS 环境变量 控制,该变量包含传递给 less(默认分页器)的选项,默认为 FRSXMK(有关详细信息,请参阅 less(1) 和 journalctl(1))。
通过省略 S 选项,输出将被换行而不是截断。例如,如下启动 journalctl:
$ SYSTEMD_LESS=FRXMK journalctl
要将此行为设置为默认值,请将其添加为 环境变量。
仅打印内核消息
journalctl 可以作为 dmesg(1) 的替代工具
# journalctl --dmesg