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 数据流与协同关系
下图展示了内核日志从产生到被不同日志系统消费的完整路径:
3.3 协同排查实战:三步定位法
当系统出现异常(如服务崩溃、硬件报错、性能抖动)时,推荐按以下顺序协同使用三种日志源:
- 第一步:dmesg 快速扫描内核态异常
- 执行
dmesg -T | grep -iE "error|fail|panic|oom|hung|hardware"过滤关键错误。 - 关注
Call Trace、BUG、WARNING等内核级事件。 - 使用
dmesg -T --level=err,warn按日志级别筛选。
- 执行
- 第二步:journalctl 获取结构化上下文
- 使用
journalctl -k -b -0查看当前启动的内核日志(与 dmesg 同源但更结构化)。 - 使用
journalctl -u <service> --since "5 min ago"关联特定服务日志。 - 利用
journalctl -p err -b按优先级过滤错误级别日志。
- 使用
- 第三步: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 协同排查决策流程
以下流程图帮助你在实际故障场景中快速选择正确的日志源组合:
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小时错误日志 |