dmesg

📅 2026/7/14 14:38:19
dmesg
dmesg 这个命令我敢说一半的人都只用了三成功力说真的每次有兄弟问我内核日志咋看我心里都会先嘀咕一句——你确定你真的会用 dmesg 吗不是说这命令有多难而是这玩意儿功能远比大多数人知道的要多。前阵子帮一个朋友排查一台服务器反复重启的故障折腾了大半天没搞定最后一句dmesg -T -l err直接把根因给扒出来了。当时他看我的表情跟看怪物似的。所以今天就打算把这些年用 dmesg 攒下的经验一股脑儿全倒出来。最基础的用法其实藏着不少坑打开终端输入dmesg回车哗啦一下全是日志。很多人看到这一堆东西头皮就发麻直接 CtrlC 完事儿。但我跟你讲耐心往下翻翻能看出不少门道。默认输出的时间戳是相对于系统启动的秒数什么[ 1234.567890] xxx这种格式。这种时间你让人怎么读上次一个实习生拿着这个时间戳来找我说这个进程怎么跑了快两千万秒了是不是要挂了我一看启动时间好家伙机器才刚开三天。dmesg -T这一步操作就能把这个时间转成人类能看懂的时间格式比如Wed May 15 14:23:01 2024。这玩意儿在排查某个时间点到底发生了啥的时候简直是救命的存在。权限这块也得提一嘴。CentOS 系列、Ubuntu 这些发行版默认普通用户能直接跑 dmesg。但如果你用的是 Debian 11 之后的版本或者一些做了安全加固的镜像会发现直接敲dmesg给你来一句dmesg: read kernel buffer failed: Operation not permitted。这时候sudo dmesg是最简单的解决办法不过我更建议你去看看/dev/kmsg的权限设置或者把用户加到相应的组里省得每次都要 sudo。实时监控救过我好几次命dmesg -w这个组合我经常用来干一件事——插拔硬件的时候实时看内核反馈。举个真实场景。之前给一台 Dell 的 R750 做扩容要新插一块 NVMe 盘。服务器在机柜最顶上笔记本搬上搬下也不方便我就直接在带外管理口 SSH 进去提前敲好dmesg -w然后让机房那边的兄弟把盘插上。日志里立马蹦出来nvme nvme0: pci function 0000:86:00.0后面跟着一堆初始化信息最后看到nvme0n1: p1 p2说明分区都识别出来了整个过程一气呵成没用 iDRAC 也没用 IPMI纯靠 dmesg 就把硬件层面的状态摸得一清二楚。还有个场景是排查 USB 设备。U盾、加密狗、4G 模块这些玩意儿经常抽风以前不知道-w的时候我都是插上设备然后反复dmesg去看日志时间窗口掐不准还容易漏。现在直接dmesg -w挂着设备一插所有插拔事件全都实时打出来比日志文件还及时。grep 过滤入门级的进阶操作dmesg | grep xxx这种用法应该是每个人都会的。但我想说的是过滤的关键不在于 grep 本身而在于你知道要过滤什么关键词。我一般排查问题的时候脑子里会有几个固定的关键词清单error、fail、failed——通用的错误信息usb、ata、nvme——存储和总线相关eth、link、nic——网卡相关oom——内存溢出这个一定要看segfault——段错误应用层挂的时候内核会记录hardware——硬件错误之前一台机器上的应用莫名其妙挂掉应用日志啥也没写。上了dmesg | grep -i -E error|kill|oom一看好家伙内核里全是Out of memory: Killed process xxx。原来是被 OOM Killer 干掉了应用自己都不知道自己怎么没的。后面调了 cgroup 内存限制加了监控告警再没出过类似问题。还有个技巧grep 的时候记得加上-i忽略大小写加上--colorauto高亮关键词。终端里花花绿绿的一眼就能定位。dmesg | grep -i --colorauto usb排查起来效率能高不少。日志级别过滤被严重低估的利器这个功能我真的要强烈安利一下。dmesg -l err这个命令只会显示错误级别的内核日志。很多人不知道 dmesg 的日志其实是分了级别的emerg、alert、crit、err、warn、notice、info、debug。日常排查的时候info 和 debug 级别的日志能把屏幕塞满关键的 err 反而被淹没在噪音里。这时候-l选项的价值就出来了。我常用的几个组合dmesg -l err,crit,alert,emerg——只看错误和更严重的dmesg -l warn,err——看警告和错误dmesg -l info——只看信息级别的之前有个故障机器间歇性丢包业务方反馈说网络有问题。我上去先dmesg -l err,crit -T看了一眼立马就发现是网卡驱动在报错ixgbe 0000:04:00.0: Error ICR 0x08000000。换了个驱动版本问题解决。如果当时用dmesg啥也不过滤地看估计得翻半天才能找到这条关键信息。dmesg 不是万能的这些坑你得知道前面说的都是 dmesg 的好但有些场景下 dmesg 真的无能为力。第一个缓冲区会满。内核日志是存在 ring buffer 里的默认大小有限。如果系统日志输出特别频繁旧的日志会被覆盖掉。所以排查那种昨天发生的问题的时候dmesg 可能已经查不到了。这时候就得靠journalctl -k或者/var/log/kern.log有些发行版来补救了。journalctl -k --since 1 hour ago这种用法我经常用来回溯最近一段时间的内核日志。第二个重启会丢。这个前面也提到了dmesg 读的是内存里的 buffer重启就没了。生产环境上我会建议把内核日志持久化到日志服务器或者直接推送到 ELK、Loki 这种日志系统里。临时用的话systemd 的 journald 默认就会持久化内核日志journalctl -k配合-p err过滤级别用起来比 dmesg 还顺手。第三个并发量大的时候输出会乱。dmesg默认是单次输出如果你在排查某个正在持续报错的问题输出会刷得很快根本看不清。这种情况下dmesg -w配合less也不太行-w模式下 less 不会用我一般是用dmesg -w | tee /tmp/dmesg.log一边实时看一边存到文件里回头慢慢分析。我自己常用的排查套路说几个我压箱底的套路遇到了直接套用。场景一服务器启动不起来或者启动慢。 直接进单用户模式或者 rescue 模式跑dmesg | grep -i -E fail|error|timeout|wait重点看驱动加载和磁盘挂载那部分。如果是云服务器的话可以通过 VNC 或者串口控制台看启动日志那个其实就是 dmesg 的输出。场景二应用性能突然下降。dmesg -T -l err,crit,alert,emerg先扫一遍有没有硬件层面的报错重点关注 CPU 相关的mceMachine Check Exception、内存相关的edac、磁盘相关的ata错误。然后dmesg | grep -i oom看看有没有被 OOM Killer 干掉。这些是应用层监控经常漏掉的地方。场景三新硬件不识别。dmesg -w挂着然后插硬件。日志里会告诉你内核有没有认到这个设备驱动加载是否成功。如果压根没动静那大概率是硬件问题或者没插紧。如果有错误信息但设备没起来那就是驱动或者固件版本不匹配。这种时候dmesg | grep -i firmware能看到固件加载失败的信息挺有用的。场景四网络抖动。dmesg | grep -i -E eth|link|nic|rx|tx重点看有没有link is down、rx errors、tx errors这类信息。云环境里虚机的话多看看virtio_net、vhost相关的日志宿主机层面的网络问题有时候会透到内核日志里。写在最后dmesg 这命令说简单也简单说复杂也复杂。简单在于输入就能看复杂在于真正用好需要你对内核、对硬件、对系统调用都得有点了解。我自己的感受是越往后用越觉得这个命令强大很多别人用一堆工具才能排查出来的问题一句 dmesg 就能搞定。但也别迷信 dmesg。它只是排查链路的起点不是终点。真正要解决问题还得结合业务日志、监控指标、链路追踪这些一起看。行了今天就啰嗦到这儿。这些经验全是我平时干活儿踩坑踩出来的你要是觉得有用转发给身边还在用dmesg | more一行行翻的兄弟让他们也少掉几根头发。下次遇到有意思的案例再来给你们拆解。