一、简介:为什么“看内核日志”是 Linux 基本功?
内核是操作系统地基:驱动、文件系统、内存管理、SELinux、AppArmor 都在内核空间。
用户空间工具(ls、lspci)只能看到“结果”;dmesg 能看到“过程”:设备识别、驱动加载、硬件错误、内核崩溃。
典型场景
插入 U 盘无反应 → 用
dmesg看是否识别成sdb还是直接报错I/O error。升级内核后网卡消失 → 对比旧内核
dmesg日志,看驱动是否probe failed。服务器随机重启 → 通过
dmesg -T时间戳定位Hardware Error、OOM、soft lockup。
掌握dmesg= 给 Linux 装了一双“内核透视眼”。
二、核心概念:5 个关键词先搞懂
| 名词 | 一句话说明 | 本文出现形式 |
|---|---|---|
| ring buffer | 内核循环缓冲区,保存启动+运行日志,断电清空 | dmesg直接读取 |
| printk | 内核版printf,级别 0~7,数字越小越严重 | dmesg -l过滤 |
| facility | 功能域:kern、user、daemon 等 | dmesg --facility=kern |
| timestamp | 两种格式:开机秒数(默认)/ 绝对时间(-T) | dmesg -T |
| loglevel | 控制台显示阈值,/proc/sys/kernel/printk 控制 | echo 4 > /proc/sys/kernel/printk |
三、环境准备:3 分钟搞定实验沙箱
系统
Ubuntu 20.04+ / CentOS 8+ / Debian 11+(内核 ≥4.15 即可)
权限
普通用户可读;硬件插拔、错误注入需 root
安装(通常自带)
# 验证是否已安装 which dmesg # 若不存在 sudo apt install -y util-linux # Ubuntu/Debian sudo dnf install -y util-linux # CentOS实验目录
mkdir -p ~/dmesg-lab && cd ~/dmesg-lab touch dmesg-boot.log dmesg-current.log
四、实际案例与步骤:由浅入深 5 大关卡
每个脚本均可直接复制,保存后
chmod +x xxx.sh && ./xxx.sh跑通。
4.1 基础查看:启动日志、驱动加载一览
#!/usr/bin/env bash # file: 01-basic.sh echo "===== 1. 查看最近 20 行 =====" dmesg | tail -20 echo "===== 2. 人类可读时间 =====" dmesg -T | head -10 echo "===== 3. 只看 ERR/FAIL =====" dmesg -l err,crit,alert,emerg场景:新机上线,快速扫一眼有无严重错误。
4.2 硬件识别:USB/SATA/PCIe 设备瞬间定位
#!/usr/bin/env bash # file: 02-hardware.sh echo "===== 1. 查找 USB 插入记录 =====" dmesg | grep -i 'usb.*new device' | tail -5 echo "===== 2. 查看硬盘识别序列 =====" dmesg | grep -i 'attached scsi disk' | awk '{print $3,$4}' echo "===== 3. 网卡驱动是否加载 =====" driver=$(dmesg | grep -i 'eth0.*driver' | awk -F: '{print $3}') echo "eth0 驱动: $driver"实战:U 盘没反应?先dmesg | tail -f再插一次,立刻看到sdb: sdb1或I/O error。
4.3 实时监控:持续打印新日志(排错神器)
#!/usr/bin/env bash # file: 03-follow.sh echo "Ctrl+C 退出实时模式" dmesg -w | tee dmesg-current.log场景:
热插拔硬盘、网卡瞬间掉线、内核模块
insmod失败,都能秒级捕获。
4.4 级别过滤:只看 “错误” 和 “警告”
#!/usr/bin/env bash # file: 04-level.sh # 0=emerg 1=alert 2=crit 3=err 4=warn 5=notice 6=info 7=debug dmesg -l 3,4 -T > error-warn.log echo "已导出错误/警告到 error-warn.log"技巧:
配合
watch -n 1 'dmesg -l err'做实时大屏。
4.5 清空与保存:生产排错标准化流程
#!/usr/bin/env bash # file: 05-save.sh # 1. 保存当前 ring buffer(可选) dmesg > dmesg-boot.log # 2. 清空(需要 root) sudo dmesg -C echo "ring buffer 已清空,后续日志纯净" # 3. 触发测试事件(示例:加载模块) sudo modprobe br_netfilter dmesg | tail -10最佳实践:
复现前先
-C,避免旧日志干扰。把
dmesg-boot.log随工单上传,方便研发二次分析。
4.6 高级:结合 journalctl 跨用户空间关联
#!/usr/bin/env bash # file: 06-joint.sh # 内核日志 + 服务日志 时间对齐 journalctl -k -b -0 | tail -20 # -k = dmesg journalctl -u NetworkManager -b | tail -20场景:
网卡掉线时,内核报
link down,NetworkManager同时报device disconnected,两条日志时间对齐,定位根因。
五、常见问题与解答(FAQ)
| 问题 | 现象 | 解决 | ||
|---|---|---|---|---|
dmesg: read kernel buffer failed: Operation not permitted | 普通用户无权限 | 内核 5.10+ 限制非特权,用sudo dmesg或sysctl kernel.dmesg_restrict=0 | ||
时间戳全是[ 0.000000] | 默认相对秒数 | 加-T转为绝对时间 | ||
清空后dmesg仍不断刷屏 | 某驱动疯狂打印 | echo 0 > /proc/sys/kernel/printk提高控制台阈值 | ||
grep找不到刚插的 U 盘 | 信息被冲掉 | `dmesg | grep -i usb | less或提前dmesg -w` 实时看 |
| 想导出上次启动日志 | ring buffer 断电丢失 | 启用持久化见下节 |
六、实践建议与最佳实践
持久化 ring buffer(可选)
Ubuntu 18.04+ 默认启用:/etc/systemd/journald.confStorage=persistent重启后
journalctl -k -b -1可看上次启动内核日志。监控脚本模
#!/bin/bash # 发现关键字立即告警 tail -Fn0 /var/log/kern.log | \ while read line; do echo "$line" | grep -q "Hardware Error" && \ curl -X POST https://alert-api.example.com -d "msg=HardwareError" doneELK 采集
Filebeat 模块system.syslog已含kernel标签,直接索引dmesg内容。性能调优
高频打印驱动加pr_debug()编译,生产环境关闭dynamic_debug。安全第一
禁止非特权查看:echo 1 > /proc/sys/kernel/dmesg_restrict,防止信息泄露。
七、总结:一张脑图带走全部要点
dmesg 实战 ├─ 查看:dmesg | less / -T / -l err ├─ 硬件:grep -i usb/eth/sda ├─ 实时:dmesg -w ├─ 保存:> dmesg.log ; sudo -C ├─ 关联:journalctl -k └─ 监控:tail + grep + 告警掌握dmesg,等于给 Linux 装了“内核级 CCTV”:
开发阶段:驱动 probe 失败?秒级定位。
上线阶段:硬件兼容性一次看清,避免“生产翻车”。
运维阶段:随机重启、OOM、soft lockup 有迹可循。
立刻打开终端,输入dmesg -T | less,从头到尾浏览一次你的机器“人生日记”,你会发现——原来内核早已告诉你答案,只是你还没学会查看。