解密 journalctl:Linux 系统日志指南

学习 journalctl 命令,用于查看、过滤、跟踪和清理 Linux systemd 日志。

解密 journalctl:Linux 系统日志指南

journalctl 工具是查看 systemd-journald 收集的日志的主要命令。当服务失败、启动挂起或内核消息快速滚动而过时,journalctl 通常是您找到详细信息的地方。

/var/log 中的纯文本日志文件不同,日志以结构化条目存储,包含单元名称、优先级、启动 ID 和时间戳等元数据。这使您可以精确过滤日志,而无需打开多个文件并猜测。


理解 Systemd 日志

在深入命令之前,了解 journalctl 管理的内容会有所帮助。systemd 日志收集来自内核、服务(单元)、应用程序甚至系统启动过程的日志。这些日志通常以结构化二进制文件存储,使其比传统平面文件搜索和过滤更快。

关键概念:

  • 持久性: 日志可以配置为跨重启永久存储(持久模式)或仅保存在内存中(易失模式)。
  • 结构化数据: 日志包含元数据(如单元名称、优先级、启动 ID),journalctl 利用这些元数据进行过滤。

基本查看命令

最常见的需求就是查看日志。以下是开始探索系统历史的基础命令。

1. 查看所有日志

要查看自系统开始记录日志以来日志收集的每个条目,请使用不带任何参数的命令:

journalctl

默认情况下,此输出使用 less 等工具分页显示,允许您使用箭头键或空格键上下导航。

2. 实时查看日志(跟踪)

类似于使用 tail -f,您可以监控正在写入日志的实时日志。这在启动或调试特定服务时非常有用:

journalctl -f

要退出实时视图,请按 Ctrl+C

3. 限制输出行数

如果您只需要最近的条目,请使用 -n 标志指定行数:

# 显示最后 20 条日志条目
journalctl -n 20

4. 查看特定时间以来的日志

按时间过滤是 journalctl 最强大的功能之一。您可以使用相对或绝对时间戳。

相对时间示例:

命令 描述
journalctl --since "1 hour ago" 过去一小时的日志。
journalctl --since "yesterday" 从上一个日历日开始以来的日志。
journalctl --since "2023-10-26 14:30:00" 特定日期和时间之后的日志。

提示: 您可以结合 --since--until 指定精确范围,例如:journalctl --since "2023-10-26" --until "2023-10-27 00:00:00"


按单元、服务或进程过滤日志

journalctl 最关键用途之一是隔离与特定 systemd 单元(服务)相关的消息。

按服务名称过滤

使用 -u(或 --unit)标志后跟服务名称(例如 sshd.servicenginx.service):

# 仅查看 Apache Web 服务器服务的日志
journalctl -u apache2.service

# 跟踪 Docker 服务的日志
journalctl -u docker.service -f

按启动 ID 过滤

Systemd 跟踪不同系统启动的日志。要查看之前启动的日志,首先列出可用的启动:

journalctl --list-boots

这会输出一个索引列表(例如 -1-20 表示当前启动)。然后您可以使用索引或完整的启动 ID:

# 显示上一次启动的日志
journalctl -b -1

# 显示特定启动 ID 的日志(使用上面列出的长 ID)
journalctl -b a1b2c3d4e5f6...

按内核消息过滤

要仅查看来自内核的消息(类似于使用 dmesg):

journalctl -k
# 或者,等效地:
journalctl -b -k

高级过滤和输出控制

有效的故障排除通常需要组合过滤器和控制输出格式。

1. 按优先级级别过滤

日志被分配优先级级别,从 0emerg)到 7debug)。您可以使用 -p--priority 标志查看所选严重性及更严重级别的消息:

优先级级别 数值
errerror 3
warning 4
notice 5
info 6
# 显示 SSH 服务的所有错误、严重和紧急消息
journalctl -u sshd.service -p err

2. 搜索特定文本

当标准过滤不够时,您可以将输出通过管道传递给 grep,或使用支持 --grepjournalctl 版本:

# 在所有日志中搜索包含单词 'failed' 的行
journalctl | grep failed

# 或者,使用 --grep 选项进行更简单的过滤(如果可用/首选)
journalctl --grep=failed

3. 更改输出格式

对于脚本编写或将日志移动到其他工具,更改输出格式至关重要。默认格式是 pretty(人类可读)。

  • --output=json:将条目输出为结构化 JSON 对象。
  • --output=short:类似于 pretty 但颜色较少。
  • --output=export:输出原始日志条目用于归档。
# 将最近的日志输出为 JSON
journalctl -n 5 --output=json

4. 组合过滤器

过滤器可以叠加使用。要查看过去 10 分钟内 Nginx 记录的所有错误:

journalctl -u nginx.service --since "10 minutes ago" -p err

管理日志大小和持久性

随着时间的推移,日志可能会占用大量磁盘空间,尤其是在配置为持久日志记录时。系统管理员必须管理其大小。

检查当前使用情况

要查看当前日志文件占用了多少磁盘空间:

journalctl --disk-usage

清理旧日志

您可以根据时间或总大小清除日志。

按时间清理:

# 仅保留过去 7 天的日志
journalctl --vacuum-time=7d

按大小清理:

# 将总日志大小减少到最大 500 兆字节
journalctl --vacuum-size=500M

警告: 删除日志时要小心,尤其是来自较早启动(-b)的日志。确保关键诊断信息不会过早被移除。

要点

对于日常故障排除,从 journalctl -u <service> -n 50 --no-pager 开始,需要实时输出时添加 -f,当问题与时间窗口或启动相关时使用 --since-b。在删除日志之前,检查 journalctl --disk-usage 并保留足够的历史记录用于回滚和事件审查。