Linux 内核日志级别与 dmesg 用法实战指南

 更新时间:2026年05月27日 09:35:02   作者:DeeplyMind  
这段文章详细介绍了Linux内核日志级别(LogLevel)及其控制台日志级别设置方法,并讨论了RingBuffer机制、溢出处理及日志持久化方案,文章还探讨了如何通过dmesg和/dev/kmsg进行调试和日志捕获,强调了在实际应用场景中的注意事项

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

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

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

数字越小,优先级越高。

2. 控制台日志级别

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

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 语法

sudo dmesg -n <level>

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

3.2 常用场景

# 只显示 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 等效方法

# 方法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 持续打印日志刷屏时:

# 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:调试时开启详细日志

# 开启 amdgpu 驱动动态调试
echo 'module amdgpu +p' | sudo tee /sys/kernel/debug/dynamic_debug/control
# 同时确保控制台能看到 DEBUG 消息
sudo dmesg -n 8

场景3:只关注错误信息

# 只看 ERR 及以上级别
sudo dmesg -n 4
# 过滤 dmesg 中的错误
dmesg --level=err,crit,alert,emerg

dmesg 其他常用选项

# 持续监听内核消息(类似 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 大小

# 查看当前 ring buffer 大小
dmesg | grep "log_buf_len"
# 或通过 sysfs(如果可用)
cat /sys/kernel/debug/tracing/buffer_size_kb

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

# 启动时通过 grub 参数设置(永久生效)
# 编辑 /etc/default/grub,在 GRUB_CMDLINE_LINUX 中添加:
log_buf_len=4M
# 然后更新 grub
sudo update-grub

5.4 日志持久化方案

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

# 方法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.5dmesg与/dev/kmsg的区别

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

5.6 关键结论

  • Ring buffer 溢出是正常行为,不需要也无法阻止
  • 关键调试日志应通过 /dev/kmsgdmesg -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/kmsgdmesg -w 持久化捕获

到此这篇关于Linux 内核日志级别与 dmesg 用法实战指南的文章就介绍到这了,更多相关Linux 内核日志级别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Shell实现猜数字游戏

    Shell实现猜数字游戏

    这篇文章主要为大家详细介绍了Shell实现猜数字游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • Shell获取文件的文件名和扩展名的例子

    Shell获取文件的文件名和扩展名的例子

    这篇文章主要介绍了Shell获取文件的文件名和扩展名的例子,简明版的代码实例,看了就懂,需要的朋友可以参考下
    2014-06-06
  • awk脚本统计一组单词中字母出现最多最少频率

    awk脚本统计一组单词中字母出现最多最少频率

    这篇文章主要介绍编写一个 awk 脚本来找到一组单词中出现次数最多(和最少)的单词频率,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-03-03
  • 执行Shell脚本的4种方法及区别介绍

    执行Shell脚本的4种方法及区别介绍

    这篇文章主要介绍了执行Shell脚本的4种方法及区别介绍,本文讲解了相对路径方式、绝对路径方式、bash命令调用、相对或绝对方式以及说下几种方式的区别,需要的朋友可以参考下
    2015-05-05
  • shell中如何批量注释和取消注释

    shell中如何批量注释和取消注释

    这篇文章主要介绍了shell中如何批量注释和取消注释,帮助大家更好的理解和学习shell脚本,感兴趣的朋友可以了解下
    2020-08-08
  • shell脚本4种执行方式

    shell脚本4种执行方式

    Linux中shell脚本的执行通常有4种方式,分别为工作目录执行,绝对路径执行,sh执行,shell环境执行。这篇文章主要介绍了shell脚本4种执行方式 ,需要的朋友可以参考下
    2019-05-05
  • 在Linux上列出磁盘信息的七个命令详解

    在Linux上列出磁盘信息的七个命令详解

    在 Linux 系统上,了解系统中的磁盘信息对于系统管理员和用户来说都是至关重要的,通过了解系统上的磁盘情况,可以有效管理存储空间、诊断问题并进行性能优化,本文给大家介绍了在Linux上列出磁盘信息的七个命令,需要的朋友可以参考下
    2024-05-05
  • Jenkinsfile 中如何在 `sh` 步骤中执行多行 Shell 命令(多行命令的方法)

    Jenkinsfile 中如何在 `sh` 步骤中执行多行 Shell 命令(多行命令的方法)

    在 Jenkinsfile 中,当你需要在 sh 步骤中执行多行 Shell 命令时,可以通过多种方式来实现,下面给大家分享实现多行命令的方法,感兴趣的朋友一起看看吧
    2024-02-02
  • Shell全局变量、局部变量与特殊变量的具体使用

    Shell全局变量、局部变量与特殊变量的具体使用

    本文主要介绍了Shell全局变量、局部变量与特殊变量的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • Shell脚本实现监控磁盘、CPU、内存占用情况

    Shell脚本实现监控磁盘、CPU、内存占用情况

    CPU、内存和磁盘是计算机中重要且相互依赖的组件,这篇文章主要为大家详细介绍了如何通过shell实现如何监控他们的使用情况,感兴趣的可以了解下
    2023-09-09

最新评论