Linux journalctl命令详解

journalctl 是 systemd 日志系统(journald)的查询工具,用于查看和分析系统日志。它提供了强大的过滤、筛选和格式化功能,是现代Linux系统中查看日志的首选工具。

一、命令简介

journalctl 命令用于查询和显示由 systemd 日志系统(journald)收集的日志。与传统的 syslog 不同,journald 以二进制格式存储日志,并支持结构化日志记录、日志旋转、实时查看等功能。journalctl 提供了统一的接口来访问这些日志。

特点: 结构化日志、实时查看、强大的过滤功能、支持按时间、单元、优先级查询、二进制日志存储。

二、安装journalctl

journalctl 是 systemd 的一部分,在现代 Linux 发行版中默认已安装:

检查是否安装

which journalctl

如果未安装,说明你的系统可能没有使用 systemd。在大多数现代 Linux 发行版中,systemd 是默认的初始化系统,journalctl 也会随之安装。

验证安装和版本

journalctl --version

三、基本语法

journalctl [选项] [匹配模式...]

四、常用选项

选项 说明
-h--help 显示帮助信息
--version 显示版本信息
-b--boot[=ID] 显示指定引导的日志
-k--dmesg 显示内核消息
-u--unit=UNIT 显示指定systemd单元的日志
-p--priority=PRIORITY 按优先级过滤日志
-f--follow 实时查看最新日志
--since=DATE 显示指定时间之后的日志
--until=DATE 显示指定时间之前的日志
-n--lines=LINES 显示指定行数的日志
--no-pager 不将输出通过分页器显示
--no-full 不显示完整的字段值
-o--output=FORMAT 指定输出格式
-x--catalog 添加消息目录的解释
--list-boots 列出可用的引导记录
-F--field=FIELD 显示指定字段的所有值
--disk-usage 显示日志磁盘使用情况
--vacuum-size=SIZE 清理日志至指定大小
--vacuum-time=TIME 清理早于指定时间的日志
--verify 检查日志文件完整性

五、日志优先级(Priority)

journalctl 支持按优先级过滤日志,优先级从 0(最高)到 7(最低):

优先级 名称 说明
0emerg 紧急(Emergency) 系统不可用
1alert 警报(Alert) 必须立即采取措施
2crit 严重(Critical) 严重错误
3err 错误(Error) 一般错误
4warning 警告(Warning) 警告信息
5notice 通知(Notice) 正常但重要信息
6info 信息(Info) 一般信息
7debug 调试(Debug) 调试信息

六、输出格式(Output Format)

journalctl 支持多种输出格式:

格式 说明
short 默认格式,类似传统syslog
short-iso ISO 8601时间戳格式
short-precise 高精度时间戳
short-monotonic 单调时间戳
verbose 完整结构化条目
export 适合备份或传输的二进制格式
json JSON格式,每行一条记录
json-pretty 格式化JSON,便于阅读
json-sse JSON格式,适合服务器发送事件
cat 仅显示消息字段
with-unit 类似short,但包含单元名称

七、使用示例

示例1:基本日志查看

# 查看所有日志(从最早到最新)
journalctl

# 查看最新日志(倒序)
journalctl -r

# 实时查看最新日志
journalctl -f

# 查看指定行数的日志
journalctl -n 50

示例2:按引导(Boot)查看日志

# 查看当前引导的日志
journalctl -b

# 查看上一次引导的日志
journalctl -b -1

# 查看特定引导的日志(先列出引导记录)
journalctl --list-boots
# 输出示例:
# -2 1234abc... Mon 2024-01-01 10:00:00 → Mon 2024-01-01 18:00:00
# -1 5678def... Tue 2024-01-02 09:00:00 → Tue 2024-01-02 17:00:00
#  0 9012ghi... Wed 2024-01-03 08:00:00 → Wed 2024-01-03 16:00:00

# 查看指定引导ID的日志
journalctl -b 1234abc...

示例3:按服务(Unit)查看日志

# 查看特定systemd单元的日志
journalctl -u nginx.service

# 查看多个单元的日志
journalctl -u nginx.service -u mysql.service

# 查看特定单元的最新日志
journalctl -u sshd.service -f

# 查看单元的错误日志
journalctl -u nginx.service -p err

示例4:按时间过滤

# 查看最近1小时的日志
journalctl --since "1 hour ago"

# 查看今天的日志
journalctl --since today

# 查看指定时间范围的日志
journalctl --since "2024-01-01 00:00:00" --until "2024-01-01 23:59:59"

# 查看昨天到现在的日志
journalctl --since yesterday --until now

# 使用相对时间
journalctl --since "2 days ago"
journalctl --since "30 min ago"

示例5:按优先级过滤

# 查看错误及以上优先级的日志
journalctl -p err

# 查看警告及以上优先级的日志
journalctl -p warning

# 查看特定优先级的日志
journalctl -p info

# 查看调试日志
journalctl -p debug

# 查看紧急和警报日志
journalctl -p 0..1

示例6:内核日志

# 查看内核日志
journalctl -k

# 查看内核日志(实时)
journalctl -k -f

# 查看特定时间的内核日志
journalctl -k --since "1 hour ago"

示例7:字段查询和过滤

# 显示特定字段的所有值
journalctl -F _PID
journalctl -F _UID
journalctl -F _HOSTNAME

# 按字段过滤
journalctl _PID=1234
journalctl _UID=1000
journalctl _HOSTNAME=server1

# 组合过滤
journalctl _UID=1000 _PID=1234
journalctl _COMM=sshd + _PID=1234

示例8:不同输出格式

# JSON格式输出
journalctl -u nginx -o json

# 格式化JSON输出
journalctl -u nginx -o json-pretty

# 仅显示消息内容
journalctl -u nginx -o cat

# 详细输出(显示所有字段)
journalctl -u nginx -o verbose

# 带单元名称的输出
journalctl -u nginx -o with-unit

八、实用技巧

1. 查找特定错误

# 查找包含"error"的日志
journalctl -x | grep -i error

# 查找特定进程的错误
journalctl -x -p err _COMM=nginx

# 查找特定时间段的错误
journalctl -x -p err --since "1 hour ago"

2. 日志分析脚本

#!/bin/bash
# 分析系统日志中的错误
ERROR_LOG="/var/log/journal_errors.log"
echo "=== 系统错误日志分析 ===" > "$ERROR_LOG"
echo "分析时间: $(date)" >> "$ERROR_LOG"
echo "" >> "$ERROR_LOG"

# 获取最近24小时的所有错误
journalctl -p err --since "24 hours ago" --no-pager >> "$ERROR_LOG"

# 统计错误数量
ERROR_COUNT=$(journalctl -p err --since "24 hours ago" --no-pager | wc -l)
echo "最近24小时错误数量: $ERROR_COUNT" >> "$ERROR_LOG"

# 按服务统计错误
echo "" >> "$ERROR_LOG"
echo "=== 按服务统计 ===" >> "$ERROR_LOG"
journalctl -p err --since "24 hours ago" -o short --no-pager | \
    awk '{print $5}' | sort | uniq -c | sort -rn >> "$ERROR_LOG"

3. 监控服务启动问题

#!/bin/bash
# 监控服务启动失败
SERVICE="nginx.service"

# 检查服务是否启动失败
if journalctl -u "$SERVICE" --no-pager | grep -q "Failed with result"; then
    echo "服务 $SERVICE 启动失败"
    # 发送通知邮件或执行恢复操作
    journalctl -u "$SERVICE" --no-pager | tail -20 | mail -s "$SERVICE 启动失败" admin@example.com
fi

4. 日志清理和管理

# 查看日志磁盘使用情况
journalctl --disk-usage

# 清理日志,保留最近100MB
sudo journalctl --vacuum-size=100M

# 清理日志,保留最近7天
sudo journalctl --vacuum-time=7d

# 同时设置大小和时间限制
sudo journalctl --vacuum-size=200M --vacuum-time=14d

# 检查日志完整性
sudo journalctl --verify

5. 日志导出和备份

# 导出所有日志到文件
journalctl --output=export > journal_backup.bin

# 导出特定时间段的日志
journalctl --since "2024-01-01" --until "2024-01-31" --output=export > january_logs.bin

# 从备份文件恢复查看
journalctl --file=journal_backup.bin

# 导出为JSON格式
journalctl --since "1 week ago" --output=json-pretty > logs.json

6. 用户会话日志

# 查看当前用户的日志
journalctl --user

# 查看特定用户的日志
journalctl _UID=1000

# 查看用户登录相关的日志
journalctl /usr/bin/login
journalctl _COMM=sshd

九、journalctl字段详解

journald 记录的结构化日志包含许多字段,以下是一些常用字段:

字段 说明 示例
_PID 进程ID 1234
_UID 用户ID 1000
_GID 组ID 1000
_COMM 命令名 nginx
_EXE 可执行文件路径 /usr/sbin/nginx
_CMDLINE 完整命令行 nginx: worker process
_SYSTEMD_UNIT systemd单元 nginx.service
_BOOT_ID 引导ID 1234abcd...
_MACHINE_ID 机器ID 5678efgh...
_HOSTNAME 主机名 server1
_TRANSPORT 日志传输方式 stdout, syslog, journal
PRIORITY 优先级 6 (info)
SYSLOG_FACILITY syslog设施 3 (daemon)
SYSLOG_IDENTIFIER syslog标识符 nginx
MESSAGE 日志消息 Server started on port 80

十、常见问题

Q: journalctl显示"No journal files were found"

A: 可能原因和解决方法:

  1. journald服务未运行:sudo systemctl start systemd-journald
  2. 以非root用户运行,且没有权限:使用sudo
  3. 日志存储被禁用:检查/etc/systemd/journald.conf中的Storage=设置
  4. 系统使用内存日志(volatile):重启后日志丢失是正常的
Q: 如何让journalctl显示时间戳?

A: journalctl默认显示时间戳。如果需要特定格式:

# ISO 8601格式时间戳
journalctl -o short-iso

# 本地时间格式
journalctl --utc  # UTC时间(默认)
journalctl --no-utc  # 本地时间

# 自定义时间格式
journalctl --output=json-pretty | jq '.__REALTIME_TIMESTAMP'
Q: journalctl日志太多,如何过滤?

A: 使用过滤选项:

# 按时间过滤
journalctl --since "1 hour ago"

# 按服务过滤
journalctl -u nginx.service

# 按优先级过滤
journalctl -p err

# 按进程ID过滤
journalctl _PID=1234

# 组合过滤
journalctl -u nginx -p err --since "today"
Q: 如何查看特定用户的日志?

A: 使用UID或用户名过滤:

# 通过UID过滤
journalctl _UID=1000

# 通过用户名获取UID再过滤
id -u username  # 获取UID
journalctl _UID=$(id -u username)

# 查看用户登录相关的日志
journalctl _COMM=login
journalctl _COMM=sshd
Q: 如何清理journal日志以释放磁盘空间?

A: 使用vacuum选项:

# 查看当前磁盘使用
journalctl --disk-usage

# 清理到指定大小
sudo journalctl --vacuum-size=500M

# 清理指定时间之前的日志
sudo journalctl --vacuum-time=2weeks

# 同时指定大小和时间
sudo journalctl --vacuum-size=200M --vacuum-time=1month

# 立即清理所有归档日志
sudo journalctl --vacuum-files=0
注意事项:
  • journal日志默认存储在/var/log/journal/,确保该分区有足够空间
  • 生产环境中应合理配置日志轮转和清理策略
  • 敏感信息可能被记录在日志中,注意日志安全
  • 使用--verify定期检查日志完整性
  • 在系统救援模式下,可能需要挂载/var/log/journal/才能查看日志
最佳实践:
  • 使用结构化字段进行高级查询和过滤
  • 定期清理旧日志,避免磁盘空间不足
  • 重要日志应导出备份或转发到中央日志服务器
  • 为关键服务设置日志监控和告警
  • 在脚本中使用JSON格式输出,便于自动化处理