登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

Linux dmesg --level 怎样筛选内核日志级别

来源:17golang原创

时间:2026-11-01 10:19:34 146浏览 收藏

我在排查一台机器的网卡初始化问题时,第一次直接运行 dmesg,终端里很快被一大段启动消息淹没。真正有用的只是 error 和 warning 附近的几行。这个场景里,最小写法是:

# 只显示错误和警告级别,逗号表示选择多个级别
dmesg --level=err,warn

# 需要看到级别前缀时,再解码 facility 和 priority
dmesg --level=err,warn --decode
--level 只筛选这次 dmesg 输出的消息级别,不会修改内核环形缓冲区,也不会替代持久化日志系统。官方手册地址:https://man7.org/linux/man-pages/man1/dmesg.1.html

先把 dmesg、级别和输出筛选分开

dmesg 的对象是内核环形缓冲区。内核消息通常带有 facility 和 priority,priority 可以用 emerg、alert、crit、err、warn、notice、info、debug 表示。--level 根据 priority 选择要显示的记录,结果仍然来自同一个环形缓冲区。

这和 --console-level 是两件事。前者控制本次读取时显示哪些消息,后者设置哪些消息可以打印到控制台;调高控制台阈值,不等于把旧消息从环形缓冲区删除。排障时先用 --level 缩小输出,避免把两个阈值混为一谈。

dmesg 从内核环形缓冲区读取 priority 并按 --level 列表过滤输出的静态结构图
图1:dmesg 级别过滤结构图,说明消息从内核环形缓冲区进入级别列表筛选后形成可见输出。

最小配方:用逗号选择多个级别

只想看错误时用 err,同时看错误和警告时用逗号分隔。逗号列表是“明确选择”,适合先建立一个不容易误解的排障命令。

# 只看 error 消息,适合先确认是否存在内核错误
dmesg --level=err

# 同时看 warning 和 error,不改变其它级别消息
dmesg --level=err,warn

# 把输出交给分页器,避免长消息滚过屏幕
dmesg --level=err,warn --nopager | less -R

如果系统支持颜色,分页时保留颜色需要 less -R;如果你只关心纯文本,可以去掉这个参数。这里的管道只是整理当前输出,不会让筛选变成持久化规则。

需要看到级别名称时加上 --decode

默认输出未必直接把 facility 和 priority 展开成易读前缀。遇到“我筛到了什么”不够直观的情况,可以加 --decode,让每条消息旁边出现可读的设施和优先级信息。

# 先按级别筛选,再把数字字段解码为可读名称
dmesg --level=crit,err,warn --decode

# 需要同时定位时间范围时,叠加 since/until;它仍然读取 dmesg 的消息源
dmesg --since="10 minutes ago" --until=now --level=err,warn --decode

--since 和 --until 适合缩小本次查看的时间窗口,但 dmesg 的内核时间戳可能受到挂起与恢复影响。不要把这个时间窗口当成 journalctl 那种跨重启的持久化索引。

err+ 与 +warn:加号方向不要写反

逗号列表解决“指定哪些级别”,加号则解决“从一个级别向一侧扩展”。syslog 级别的数字顺序是 emerg 最严重、debug 最不严重。

写法包含的方向适合的场景
err+err、crit、alert、emerg只看 error 及更严重消息
+warnwarn、notice、info、debug从 warning 开始连同更低优先级消息观察
err,warn只选 err 与 warn需要精确控制输出集合
# err+ 向更严重的一侧扩展,不包含 warn、info、debug
dmesg --level=err+

# +warn 向更低优先级的一侧扩展,包含 notice、info、debug
dmesg --level=+warn

# 多个范围可以和普通级别一起写,但要先确认输出集合是否过宽
dmesg --level=err+,+warn

我更建议在故障初筛时优先用 err,warn,因为它表达的是明确集合;只有确实需要一整个方向的级别时,才用加号范围。这样回看命令时,不容易把“更严重”和“更低优先级”理解反。

emerg 到 debug 的级别层级以及 err+、+warn 和 --console-level 独立边界的静态结构图
图2:级别范围结构图,说明 err+ 向更严重级别扩展,+warn 向更低优先级扩展,控制台阈值与输出筛选各自独立。

把级别筛选放进排障命令

确定级别语义后,可以按任务叠加几个互不冲突的选项。下面的组合分别服务于“只看新消息”“持续观察”和“避免分页器打断脚本”。

# 只看最近五分钟的错误和警告,适合复现后立即回看
dmesg --since="5 minutes ago" --level=err,warn --decode

# 持续等待新的内核消息,适合插拔设备或重连网络时观察
dmesg --follow --level=err,warn --decode

# 脚本或采集器不需要交互分页时,显式关闭 pager
dmesg --nopager --level=err,warn --decode

这些参数改变的是读取和呈现方式,不会替你保存日志。如果任务要求跨重启检索、按服务筛选或长期审计,应转到系统实际使用的持久化日志方案,而不是只依赖 dmesg 当前还能保留的环形缓冲区内容。

三个容易误判的边界

为什么出现 permission denied?

部分系统启用了 dmesg_restrict,普通用户读取内核消息会被拒绝。这是权限边界,不是 --level 写错。应按主机安全策略使用有权限的运维身份,或让管理员提供经过授权的日志入口,不要为了绕过权限直接关闭安全限制。

为什么筛选后没有消息?

可能是当前环形缓冲区里没有该 priority,也可能是消息已经被覆盖,或者你把 err+、+warn 的方向理解反了。先用 dmesg --level=err,warn --decode 看明确集合,再扩大范围定位。

为什么重启后以前的 dmesg 不见了?

dmesg 面向内核环形缓冲区,容量有限,重启后也不保证保留上一轮启动的全部消息。需要跨启动查询时,应使用系统配置的日志持久化服务;dmesg 的 --since 只是对当前可读消息做时间筛选。

最后记住这张速查表

  • 精确选择:--level=err,warn。
  • error 及更严重:--level=err+。
  • warning 及更低优先级:--level=+warn。
  • 查看可读 facility 与 priority:增加 --decode。
  • 本次输出筛选:--level;控制台打印阈值:--console-level。
  • 权限、环形缓冲区容量和持久化策略决定“能不能看到”,不是级别列表本身决定全部结果。

我的使用习惯是先用明确的 err,warn 缩小范围,再根据现场需要改成 err+ 或加上 --decode。命令越能直接表达筛选集合,后续复盘就越不容易把 dmesg 的读取边界和系统日志保存边界混在一起。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>