Linux 内核日志级别kern_levels与 dmesg 用法

1. 内核日志级别(Log Level)

Linux 内核定义了 8 个日志级别(定义在 include/linux/kern_levels.h):

级别 宏定义 含义 说明
0 KERN_EMERG 系统不可用 系统即将崩溃
1 KERN_ALERT 需要立即处理 必须立即采取行动
2 KERN_CRIT 严重错误 硬件/软件严重故障
3 KERN_ERR 错误 一般错误条件
4 KERN_WARNING 警告 可能出问题的情况
5 KERN_NOTICE 正常但重要 正常但值得注意的信息
6 KERN_INFO 信息 一般性信息
7 KERN_DEBUG 调试 调试级别的信息

数字越小,优先级越高。

2. 控制台日志级别

内核通过 /proc/sys/kernel/printk 控制哪些消息输出到控制台。该文件包含 4 个值:

bash 复制代码
cat /proc/sys/kernel/printk
# 输出示例: 4    4    1    7
#           |    |    |    |
#           |    |    |    +-- default_console_loglevel(新打开控制台的默认级别)
#           |    |    +------- minimum_console_loglevel(控制台最小允许级别)
#           |    +------------ default_message_loglevel(printk 默认消息级别)
#           +----------------- console_loglevel(当前控制台日志级别阈值)

只有级别值 < console_loglevel 的消息才会输出到控制台。

3. dmesg -n 命令

dmesg(display message)是用户空间读取内核 ring buffer 的工具。其 -n 选项可以在运行时动态修改上述 console_loglevel 的值,从而控制哪些级别的内核消息会输出到控制台,而无需重启系统或修改配置文件。

3.1 语法

bash 复制代码
sudo dmesg -n <level>

设置控制台日志级别阈值。只有严格小于 level 的消息才会打印到控制台。

3.2 常用场景

bash 复制代码
# 只显示 KERN_EMERG (级别0) 的消息,几乎屏蔽所有输出
sudo dmesg -n 1

# 显示 ERR 及以上 (级别 0-2)
sudo dmesg -n 3

# 显示 WARNING 及以上 (级别 0-3)
sudo dmesg -n 4

# 显示所有消息(包括 DEBUG)
sudo dmesg -n 8

# 恢复系统默认(通常是 4 或 7)
sudo dmesg -n 7

3.3 等效方法

bash 复制代码
# 方法1: 通过 /proc 接口
echo 1 | sudo tee /proc/sys/kernel/printk

# 方法2: 通过 sysctl
sudo sysctl -w kernel.printk="1 4 1 7"

4. 实际应用场景

场景1:内核死循环打印

当内核驱动(如 amdgpu)因 bug 持续打印日志刷屏时:

bash 复制代码
# 1. 立即止住控制台输出
sudo dmesg -n 1

# 2. 将日志重定向到文件分析
sudo dmesg > /tmp/kern_dump.log

# 3. 尝试恢复驱动状态
sudo modprobe -r amdgpu && sudo modprobe amdgpu

# 4. 如果模块卸载失败
sudo fuser -k /dev/kfd
sudo fuser -k /dev/dri/*
sudo modprobe -r amdgpu

# 5. 恢复日志级别
sudo dmesg -n 7

场景2:调试时开启详细日志

bash 复制代码
# 开启 amdgpu 驱动动态调试
echo 'module amdgpu +p' | sudo tee /sys/kernel/debug/dynamic_debug/control

# 同时确保控制台能看到 DEBUG 消息
sudo dmesg -n 8

场景3:只关注错误信息

bash 复制代码
# 只看 ERR 及以上级别
sudo dmesg -n 4

# 过滤 dmesg 中的错误
dmesg --level=err,crit,alert,emerg

dmesg 其他常用选项

bash 复制代码
# 持续监听内核消息(类似 tail -f)
sudo dmesg -w

# 带时间戳显示
dmesg -T

# 带级别标记显示
dmesg --decode

# 清空 ring buffer
sudo dmesg -C

# 只显示特定级别
dmesg --level=err
dmesg --level=warn,err

# 显示最后 N 行
dmesg | tail -50

5. Ring Buffer 机制与溢出处理

5.1 Ring Buffer 基本概念

内核日志存储在一个固定大小的环形缓冲区(ring buffer)中。当 buffer 满时,内核自动覆盖最旧的消息(FIFO 循环写入),这是设计行为,不需要手动干预。

5.2 查看 Ring Buffer 大小

bash 复制代码
# 查看当前 ring buffer 大小
dmesg | grep "log_buf_len"

# 或通过 sysfs(如果可用)
cat /sys/kernel/debug/tracing/buffer_size_kb

5.3 增大 Ring Buffer(防止日志丢失)

bash 复制代码
# 启动时通过 grub 参数设置(永久生效)
# 编辑 /etc/default/grub,在 GRUB_CMDLINE_LINUX 中添加:
log_buf_len=4M

# 然后更新 grub
sudo update-grub

5.4 日志持久化方案

Ring buffer 中的日志重启后丢失,且可能被覆盖。以下方法可持久化保存:

bash 复制代码
# 方法1: 通过 journald 持久化(systemd 系统)
# 确认配置: /etc/systemd/journald.conf
#   Storage=persistent
# 查看历史内核日志(包括之前的启动)
journalctl -k
journalctl -k -b -1    # 上一次启动的内核日志

# 方法2: 持续写入文件(实时捕获,不受 ring buffer 覆盖影响)
sudo cat /dev/kmsg > /tmp/kmsg_full.log &

# 方法3: 使用 dmesg -w 持续监听并保存
sudo dmesg -wT > /tmp/kern_continuous.log &

5.5 dmesg 与 /dev/kmsg 的区别

dmesg /dev/kmsg
数据来源 ring buffer 快照 实时流式读取
读取方式 一次性输出当前所有内容 持续读取新消息
旧消息 包含 ring buffer 中所有现存消息 只读取打开后的新消息
典型用法 dmesg > log.txt cat /dev/kmsg > log.txt &

5.6 关键结论

  • Ring buffer 溢出是正常行为,不需要也无法阻止
  • 关键调试日志应通过 /dev/kmsg 或 dmesg -w 实时持久化捕获
  • 不要依赖 ring buffer 保留完整历史,大量日志输出(如死循环打印)会快速覆盖有用信息

6. 注意事项

  1. dmesg -n 只影响控制台输出,不影响内核 ring buffer 中的日志记录

  2. 消息始终可通过 dmesg 命令或 /dev/kmsg 读取

  3. systemd 系统中,journalctl -k 也可查看内核日志

  4. 重启后日志级别恢复默认,如需持久化可修改 /etc/sysctl.conf:

    复制代码
    kernel.printk = 4 4 1 7
  5. Ring buffer 满时自动覆盖旧消息,调试时应提前用 /dev/kmsg 或 dmesg -w 持久化捕获

相关推荐
我是koten11 小时前
【运维杂谈】K8s遇到Terminating的名称空间删除不了怎么办?(解决方案亲测有效)
linux·运维·服务器·云原生·kubernetes·k8s·名称空间
2601_9679873718 小时前
安装 Redis 或 Redis Stack
linux·windows·redis·macos·安装
feng_you_ying_li18 小时前
linux之数据链路层
linux·网络·智能路由器
GeW20 小时前
高端化走到深处,是数据库和Linux的事
linux
程序员初一21 小时前
Linux 远程桌面有四种做法
linux·ssh
程序开发阿元21 小时前
1C1G 能跑什么:把留常驻服务和不留摆进一张内存表
linux·ssh
xbzb1 天前
自定义 yum 软件源:Linux 上 createrepo,Windows 上纯 Python 也能造
linux·运维·windows·python·yum·createrepo
Android系统攻城狮1 天前
Linux FFmpeg深度解析之avio_open调用流程与实战(三十八)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
独隅1 天前
WebStorm Linux 版安装实战与核心效能展示
linux·ide·webstorm
雪落漂泊1 天前
Linux进程(五):进程地址空间篇
linux·运维·服务器