3. dmesg与系统日志的关系:dmesg vs /var/log/messages vs journalctl,如何协同使用进行故障排查

在Linux系统故障排查中,dmesg、/var/log/messages(或secure、cron等传统日志)以及journalctl(systemd-journald)是三大核心日志来源。它们各自聚焦不同的数据维度,理解其差异与协同方式,是高效定位内核级与用户态问题的关键。

3.1 三大日志源的核心定位

日志源 数据来源 主要记录内容 存储方式 典型保留周期
dmesg 内核环形缓冲区(kmsg) 内核启动信息、驱动加载、硬件错误、OOM、panic 内存环形缓冲区 + 可导出至文件 仅保留最近(受缓冲区大小限制)
/var/log/messages syslog/rsyslog 守护进程 用户态服务日志、部分内核日志(经syslog转发) 文本文件(轮转归档) 通常数周至数月(由logrotate控制)
journalctl systemd-journald 守护进程 所有systemd单元日志、内核日志、用户态服务日志 二进制日志(结构化、带元数据) 默认数天至数周(受磁盘配额限制)
关键认知: dmesg 是内核的“原始现场”,messages 是“归档副本”,journalctl 是“结构化全集”。故障排查时,应优先从 dmesg 获取内核态第一手信息,再结合 journalctl 和 messages 补充用户态上下文。

3.2 数据流与协同关系

下图展示了内核日志从产生到被不同日志系统消费的完整路径:

dmesg、messages、journalctl 数据流协同关系图 内核日志数据流与三大日志源协同关系 内核环形缓冲区 (kmsg) dmesg 命令读取 syslog/rsyslog 守护进程 systemd-journald /var/log/messages /var/log/journal/ journalctl 查询 说明: dmesg 直接读取内核环形缓冲区,不经过任何守护进程,因此最原始、最实时。 messages 和 journalctl 都依赖用户态守护进程转发,可能丢失极早期启动日志。

3.3 协同排查实战:三步定位法

当系统出现异常(如服务崩溃、硬件报错、性能抖动)时,推荐按以下顺序协同使用三种日志源:

  1. 第一步:dmesg 快速扫描内核态异常
    • 执行 dmesg -T | grep -iE "error|fail|panic|oom|hung|hardware" 过滤关键错误。
    • 关注 Call Trace、BUG、WARNING 等内核级事件。
    • 使用 dmesg -T --level=err,warn 按日志级别筛选。
  2. 第二步:journalctl 获取结构化上下文
    • 使用 journalctl -k -b -0 查看当前启动的内核日志(与 dmesg 同源但更结构化)。
    • 使用 journalctl -u <service> --since "5 min ago" 关联特定服务日志。
    • 利用 journalctl -p err -b 按优先级过滤错误级别日志。
  3. 第三步:messages 回溯历史趋势
    • 查看 /var/log/messages 或 /var/log/syslog 中的时间戳序列。
    • 使用 grep "kernel:" /var/log/messages | tail -100 提取内核相关条目。
    • 结合 logrotate 归档文件(如 messages.1.gz)分析历史模式。
实战案例: 某服务器出现周期性服务重启。dmesg 显示 Out of memory: Killed process,journalctl 确认 OOM Killer 触发了特定进程,messages 历史记录显示内存使用量在过去一周持续增长。最终定位为内存泄漏问题。

3.4 日志级别与过滤对照

三种日志源使用不同的级别体系,但内核日志级别是共通的。下表展示了如何在不同工具中实现等价过滤:

内核日志级别 dmesg 过滤 journalctl 过滤 messages 中关键字
KERN_EMERG (0) --level=emerg -p emerg emerg 或 panic
KERN_ALERT (1) --level=alert -p alert alert
KERN_CRIT (2) --level=crit -p crit critical
KERN_ERR (3) --level=err -p err error
KERN_WARNING (4) --level=warn -p warning warning
KERN_NOTICE (5) --level=notice -p notice notice
KERN_INFO (6) --level=info -p info info
KERN_DEBUG (7) --level=debug -p debug debug

3.5 协同排查决策流程

以下流程图帮助你在实际故障场景中快速选择正确的日志源组合:

dmesg、messages、journalctl 协同排查决策流程图 故障排查日志源选择决策流程 系统异常发生 硬件/内核 相关? dmesg -T --level=err,warn journalctl -p err -b 是 否 /var/log/messages 回溯 /var/log/messages 回溯 综合三源信息定位根因 最佳实践: 始终从 dmesg 开始排除内核级问题,再用 journalctl 获取结构化上下文,最后用 messages 回溯历史趋势。

3.6 常见误区与避坑指南

⚠️ 常见误区:
  • 误区1:认为 dmesg 和 journalctl -k 完全等价。实际上 dmesg 读取的是当前环形缓冲区,而 journalctl -k 读取的是 systemd-journald 持久化的内核日志副本,后者可能因配额限制被截断。
  • 误区2:只查看 messages 而忽略 dmesg。messages 中的内核日志经过 syslog 转发,可能丢失高并发场景下的部分日志行。
  • 误区3:忘记检查 dmesg 的时间戳。默认 dmesg 显示的是系统启动后的相对秒数,需使用 -T 参数转换为可读时间。

3.7 快速参考命令表

排查场景 推荐命令 说明
查看当前启动内核错误 dmesg -T --level=err 仅显示错误及以上级别
查看特定服务日志 journalctl -u nginx.service -b 当前启动的 nginx 日志
查看历史内核日志 journalctl -k -b -1 上一次启动的内核日志
搜索 messages 中内核相关 grep "kernel:" /var/log/messages 提取所有内核条目
实时监控内核日志 dmesg -w 类似 tail -f 效果
查看所有日志优先级排序 journalctl -p err --since "1 hour ago" 过去1小时错误日志