内核日志dmesg和journalctl
2026-02-14
运维
00
请注意,本文编写于 49 天前,最后修改于 5 天前,其中某些信息可能已经过时。

目录

一、内核日志的存储机制:环形缓冲区
1.1 什么是环形缓冲区(Ring Buffer)?
1.2 内核日志的生成流程
二、dmesg:传统的内核日志查看器
2.1 dmesg 基础用法
2.2 高级过滤与格式化
按日志级别过滤(0-7级)
人性化输出(交互式浏览)
实时监控新日志
2.3 实用排查案例
案例 1:USB 设备无法识别
案例 2:硬盘 I/O 故障诊断
案例 3:内存故障与 OOM 诊断
案例 4:网卡与网络故障
2.4 日志导出与持久化
三、journalctl:systemd 时代的日志中心
3.1 journalctl 与 dmesg 的关系
3.2 journalctl 基础用法
查看启动日志
时间范围过滤
按服务/单元过滤
3.3 高级过滤技巧
按优先级过滤
按字段过滤(结构化查询)
组合查询
3.4 输出格式控制
四、日志持久化配置(生产必备)
4.1 默认行为的局限
4.2 启用持久化日志
4.3 高级配置(/etc/systemd/journald.conf)
4.4 日志清理与维护
五、综合排查实战
场景:系统启动缓慢
场景:服务崩溃无日志
六、工具对比速查表

一、内核日志的存储机制:环形缓冲区

1.1 什么是环形缓冲区(Ring Buffer)?

Linux 内核在启动时,会预先分配一块固定大小的物理内存作为日志存储区域,采用**环形(循环覆盖)**的数据结构管理:

展开代码
┌─────────────────────────────────────────┐ │ 内核环形缓冲区(Ring Buffer) │ │ 典型大小:256KB ~ 4MB(可配置) │ ├─────────────────────────────────────────┤ │ [消息1] [消息2] [消息3] ... [消息N] │ │ ▲ ▼ │ │ └──────── 新消息覆盖旧消息 ─────────┘ │ └─────────────────────────────────────────┘

核心特性

特性说明影响
固定大小不随日志量增长高负载系统可能丢失早期日志
循环覆盖满时新消息覆盖最旧消息需及时导出或持久化重要日志
内核态存储不依赖文件系统文件系统损坏时仍可查看
无锁设计多 CPU 并发写入高性能,极低开销

查看缓冲区大小

展开代码
# 查看当前环形缓冲区大小(字节) cat /sys/kernel/debug/printk/buffer_size_kb # 或 dmesg | wc -c

1.2 内核日志的生成流程

展开代码
硬件事件/驱动调用 │ ▼ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ printk() │───►│ 环形缓冲区 │◄───│ dmesg/journalctl │ │ 内核函数 │ │ (内存中) │ │ 用户态读取工具 │ └─────────────┘ └─────────────┘ └─────────────┘ │ ▼ ┌─────────────┐ │ /dev/kmsg │ │ 设备节点 │ └─────────────┘

二、dmesg:传统的内核日志查看器

2.1 dmesg 基础用法

展开代码
# 基本输出(纯文本,无时间戳) dmesg # 显示可读时间戳(推荐) dmesg -T # [Mon Oct 27 17:15:23 2023] usb 1-1: new high-speed USB device number 2 using xhci_hcd # 显示时间间隔(距上一条日志的秒数) dmesg -d # [ 0.000000] Linux version 5.15.0-76-generic ← 启动 # [ 0.004567] Command line: BOOT_IMAGE=/vmlinuz... ← 4.5ms后

2.2 高级过滤与格式化

按日志级别过滤(0-7级)

级别名称含义使用场景
0emerg系统不可用内核崩溃、panic
1alert必须立即处理严重硬件故障
2crit严重错误关键服务失败
3err错误驱动加载失败
4warn警告配置异常、降级运行
5notice正常但重要安全事件、状态变更
6info信息性常规操作日志
7debug调试信息开发诊断
展开代码
# 仅显示错误和警告(生产排查首选) dmesg -l err,warn # 或完整写法 dmesg --level=err,warn # 显示所有严重级别 dmesg -l emerg,alert,crit,err,warn,notice,info,debug

人性化输出(交互式浏览)

展开代码
# 自动分页 + 颜色高亮(类似 less) dmesg -H # 操作:↑/↓ 滚动,/ 搜索,q 退出 # 彩色输出(不自动分页) dmesg -L

实时监控新日志

展开代码
# 仅监控新产生的日志(不显示历史) dmesg --follow-new # 或简写 dmesg -w # 与传统 tail -f 的区别: # tail -f /var/log/kern.log ← 依赖 rsyslog,可能有延迟 # dmesg --follow-new ← 直接读取 /dev/kmsg,实时性更高

2.3 实用排查案例

案例 1:USB 设备无法识别

展开代码
# 搜索 USB 相关日志 dmesg | grep -i "usb" | tail -20 # 典型错误与解决方案: # ───────────────────────────────────────────────────────── # usb 1-1: device descriptor read/64, error -110 # → 原因:USB 设备响应超时(物理连接问题) # → 解决:更换 USB 端口、线缆,或检查设备供电 # # usb 1-1: device not accepting address 2, error -71 # → 原因:USB 协议错误(设备或控制器故障) # → 解决:尝试其他端口,更新 xhci_hcd 驱动 # # usbhid: probe of 1-1:1.0 failed with error -32 # → 原因:HID 驱动不兼容 # → 解决:卸载重载驱动:sudo modprobe -r usbhid && sudo modprobe usbhid

案例 2:硬盘 I/O 故障诊断

展开代码
# 查看磁盘错误(以 sda 为例) dmesg -l err | grep "sda" # 关键错误模式: # ───────────────────────────────────────────────────────── # Buffer I/O error on dev sda, logical block 12345678 # → 物理坏块,立即备份数据,更换硬盘 # # EXT4-fs error (device sda1): ext4_lookup: deleted inode referenced # → 文件系统损坏,尝试 fsck 修复 # # ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x40000000 action 0x6 frozen # → SATA 链路错误,检查数据线和电源

案例 3:内存故障与 OOM 诊断

展开代码
# 内存相关日志 dmesg | grep -iE "memory|oom|hardware.error" | tail -30 # 典型场景: # ───────────────────────────────────────────────────────── # Out of memory: Kill process 1234 (python) score 912 or sacrifice child # → OOM Killer 触发,进程被强制终止 # → 解决:增加物理内存、添加 Swap、优化应用内存使用 # # Hardware Error: Corrected error, no action required. # → ECC 内存自动纠正错误(可接受) # → 监控:若频繁出现,预示内存条老化 # # Hardware Error: Machine check events logged # → 不可纠正的硬件错误 # → 立即检查:mcelog --client 或 edac-util -v

案例 4:网卡与网络故障

展开代码
# 网卡驱动日志 dmesg | grep -iE "eth|ens|wlan|network" | tail -20 # 典型问题: # ───────────────────────────────────────────────────────── # eth0: Link is Down # → 物理链路断开,检查网线、交换机端口 # # ixgbe 0000:01:00.0: NIC Link is Up 10 Gbps, Flow Control: RX/TX # → 网卡正常工作,10Gbps 链路已建立

2.4 日志导出与持久化

展开代码
# 导出完整日志到文件 dmesg > /var/log/dmesg-$(date +%F-%H%M).log # 导出带时间戳的日志 dmesg -T > /var/log/dmesg-readable.log # 定期归档(cron 任务) # /etc/cron.d/dmesg-backup 0 */6 * * * root /bin/dmesg -T > /var/log/dmesg-archive-$(date +\%F-\%H).log

三、journalctl:systemd 时代的日志中心

3.1 journalctl 与 dmesg 的关系

特性dmesgjournalctl
数据来源内核环形缓冲区systemd-journald(内核+用户态)
存储位置内存(/dev/kmsg)内存(/run/log)或磁盘(/var/log)
日志范围仅内核日志内核 + 所有 systemd 服务
持久化需手动导出原生支持持久化配置
查询能力简单过滤强大的结构化查询
性能极高(直接内存访问)高(二进制索引)

关键认知:journalctl 包含 dmesg 的内容,但 dmesg 不包含 journalctl 的用户态日志。

3.2 journalctl 基础用法

查看启动日志

展开代码
# 查看当前启动的所有日志(内核+服务) journalctl # 查看上一次启动 journalctl -b -1 # 查看特定启动(需启用持久化) journalctl --list-boots # -1 ... Mon 2023-10-23 09:15:23 CST—Mon 2023-10-23 18:30:45 CST # 0 ... Tue 2023-10-24 08:00:12 CST—Tue 2023-10-24 17:45:30 CST journalctl -b -2 # 查看上上次启动

时间范围过滤

展开代码
# 绝对时间 journalctl --since "2023-10-27 17:15:00" --until "2023-10-27 18:00:00" # 相对时间 journalctl --since "1 hour ago" journalctl --since "yesterday" --until "today" journalctl --since "2023-10-01" --until "2 days ago" # 仅今天 journalctl --since today

按服务/单元过滤

展开代码
# 查看特定服务 journalctl -u nginx.service journalctl -u sshd.service -f # 实时跟踪 # 查看多个服务 journalctl -u nginx.service -u php-fpm.service # 查看系统初始化(无服务单元) journalctl -p err -b # 启动错误

3.3 高级过滤技巧

按优先级过滤

展开代码
# 仅错误及以上(与 dmesg -l err 类似,但包含用户态) journalctl -p err # 优先级名称或数字 journalctl -p 3 # err journalctl -p warning # 4 journalctl -p 0..3 # emerg 到 err

按字段过滤(结构化查询)

展开代码
# 按进程名 journalctl _COMM=nginx # 按可执行文件路径 journalctl _EXE=/usr/bin/python3 # 按 PID journalctl _PID=1234 # 按命令行参数(查找特定脚本) journalctl _CMDLINE="/usr/bin/python3 /app/server.py" # 按 syslog 标识 journalctl SYSLOG_IDENTIFIER=kernel # 等价于 dmesg

组合查询

展开代码
# 复杂条件:nginx 服务,昨天,错误级别 journalctl -u nginx.service --since yesterday -p err # 特定时间段 + 特定服务 + 实时跟踪 journalctl -u myapp.service --since "10 minutes ago" -f

3.4 输出格式控制

展开代码
# 详细输出(含所有元数据) journalctl -o verbose # JSON 格式(程序化解析) journalctl -u myapp -o json | jq '.MESSAGE' # 短格式(类似传统 syslog) journalctl -o short # 仅消息内容(无时间戳等) journalctl -o cat

四、日志持久化配置(生产必备)

4.1 默认行为的局限

默认情况下,systemd-journald 将日志存储在 内存中/run/log/journal),重启后丢失。对于服务器故障排查,必须启用持久化存储

4.2 启用持久化日志

展开代码
# 步骤 1:创建持久化目录 sudo mkdir -p /var/log/journal # 步骤 2:重启服务(自动检测并迁移) sudo systemctl restart systemd-journald # 验证 ls -la /var/log/journal/ # 应出现类似:systemd-journald-a1b2c3d4e5f67890.journal

4.3 高级配置(/etc/systemd/journald.conf)

展开代码
[Journal] # 存储模式:volatile(内存)、persistent(磁盘)、auto(自动检测) Storage=persistent # 磁盘空间限制(持久存储) SystemMaxUse=5G # 最大占用 5GB SystemKeepFree=10G # 保留 10GB 空闲空间 SystemMaxFileSize=100M # 单个日志文件最大 100MB # 内存限制(运行时) RuntimeMaxUse=500M # 内存中最多 500MB RuntimeMaxFileSize=50M # 运行时单个文件 50MB # 保留策略 MaxRetentionSec=1month # 保留 1 个月 MaxFileSec=1week # 单个文件最长 1 周 # 压缩 Compress=yes # 启用压缩,节省空间 # 转发到传统 syslog(兼容旧系统) ForwardToSyslog=yes

应用配置:

展开代码
sudo systemctl restart systemd-journald

4.4 日志清理与维护

展开代码
# 查看当前磁盘占用 journalctl --disk-usage # Archived and active journals take up 2.8G in the file system. # 按大小清理(保留最近 1GB) sudo journalctl --vacuum-size=1G # 按时间清理(保留最近 1 年) sudo journalctl --vacuum-time=1years # 按文件数清理(保留最近 10 个启动) sudo journalctl --vacuum-files=10

五、综合排查实战

场景:系统启动缓慢

展开代码
# 步骤 1:分析启动耗时 systemd-analyze blame # 3.456s NetworkManager-wait-online.service # 2.123s docker.service # 1.987s postgresql.service # 步骤 2:查看启动过程中的错误 journalctl -b -p err # 步骤 3:查看特定服务的详细启动日志 journalctl -u NetworkManager-wait-online.service -b # 步骤 4:结合 dmesg 查看硬件初始化 dmesg -l warn,err | grep -E "eth|wlan|nvme"

场景:服务崩溃无日志

展开代码
# 步骤 1:扩大日志范围(可能崩溃前已有异常) journalctl -u myapp.service --since "10 minutes ago" -p debug # 步骤 2:查看内核是否记录异常(OOM、段错误) dmesg -T | grep -E "killed|segfault|oom" # 步骤 3:查看 audit 日志(SELinux/AppArmor 拦截) sudo ausearch -ts recent -m avc

六、工具对比速查表

任务推荐工具命令
快速查看内核错误dmesgdmesg -l err,warn -T
实时跟踪内核日志dmesgdmesg --follow-new
查看服务完整生命周期journalctljournalctl -u nginx.service
分析启动问题journalctljournalctl -b -p err
跨重启追溯问题journalctljournalctl -b -1 --since "10:00"
导出结构化日志journalctljournalctl -o json > logs.json
高性能实时监控dmesgdmesg -w(比 journalctl -k -f 更快)

本文作者:zzz

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!