Linux内核log是操作系统记录硬件驱动、内存管理及内核异常的核心日志,通过ring buffer(环形缓冲区)机制实现,是排查系统崩溃(Kernel Panic)和驱动故障的唯一权威依据。
Linux内核日志的底层运行机制
Linux内核日志并非直接写入磁盘,因为在内核崩溃或磁盘驱动失效时,直接写磁盘会导致死锁或数据丢失。
环形缓冲区(Ring Buffer)
内核将日志存储在一段预分配的内存区域,即kmsg ring buffer,这段内存采用环形结构,当日志填满后,新日志会覆盖最旧的记录,这种设计保证了内核在极端压力下不会因为日志过多而耗尽系统内存。
printk 打印级别
内核使用 printk 函数输出信息,每个条目都关联一个日志级别(Log Level),业内专家指出,理解这些级别是过滤冗余信息的关键。
- KERN_EMERG (0):系统不可用。
- KERN_ALERT (1):必须立即采取行动。
- KERN_CRIT (2):临界状态。
- KERN_ERR (3):错误条件。
- KERN_WARNING (4):警告条件。
- KERN_NOTICE (5):正常但重要的条件。
- KERN_INFO (6):信息类消息。
- KERN_DEBUG (7):调试类消息。
从内核空间到用户空间的传递
内核日志在内存中产生后,可以通过以下路径被用户读取:
- dmesg 接口:直接读取 ring buffer。
- klogd/syslogd:用户态守护进程通过
/proc/kmsg读取日志并将其持久化到/var/log/kern.log或/var/log/messages。 - systemd-journald:现代发行版通过
journalctl统一管理。
linux内核log怎么查看
在实际运维和驱动开发中,根据场景选择不同的查看方式能极大提高排查效率。
使用 dmesg 命令实时分析
dmesg 是最直接的工具,它直接从内核环形缓冲区提取数据。
- 查看完整日志:
dmesg - 人性化时间戳:
dmesg -T(将秒数转换为可读的日期时间)。 - 实时滚动监控:
dmesg -w(类似tail -f,在驱动加载或硬件插拔时非常有用)。 - 过滤关键词:
dmesg | grep -i "error"(忽略大小写搜索错误信息)。
通过 journalctl 查看持久化日志
在 CentOS 7+ 或 Ubuntu 16.04+ 等使用 systemd 的系统中,journalctl 提供了更强大的索引能力。
- 仅查看内核日志:
journalctl -k - 查看本次启动后的内核日志:
journalctl -kb - 查看特定时间段的日志:
journalctl -k --since "2026-10-01" --until "2026-10-02"
直接读取 /proc/kmsg
对于嵌入式设备或没有安装标准工具链的环境,可以直接通过 shell 读取:cat /proc/kmsg
注意:读取此文件会消耗缓冲区内容,可能导致 dmesg 无法看到部分日志。
dmesg和syslog区别是什么
很多初学者容易混淆这两个工具,实际上它们在存储介质、生命周期和用途上有本质区别。
| 维度 | dmesg | syslog (kern.log) |
|---|---|---|
| 存储位置 | 内存 (Ring Buffer) | 磁盘文件 (/var/log/) |
| 持久性 | 重启后丢失 | 重启后保留 |
| 读取速度 | 极快 | 较慢 (涉及磁盘I/O) |
| 数据量 | 有限 (覆盖写) | 较大 (取决于磁盘空间和轮转策略) |
| 适用场景 |
实时调试、驱动加载分析 | 历史故障追溯、审计 |
行业共识认为,dmesg 用于“现在发生了什么”,而 syslog 用于“过去发生了什么”。
linux内核log打印级别怎么设置
如果控制台被大量的 INFO 或 DEBUG 信息刷屏,或者关键的 ERR 信息没有显示,需要调整内核打印级别。
动态修改控制台打印阈值
内核通过 /proc/sys/kernel/printk 维护四个数值。4 4 1 7:
- 第一个数字 (4):控制台日志级别,只有级别低于 4 的日志才会打印到物理控制台。
- 第二个数字 (4):默认消息日志级别。
- 第三个数字 (1):最小一致性级别。
- 第四个数字 (7):最高日志级别。
操作路径:
若要禁止控制台显示 WARNING 及以下级别的日志,仅保留 ERR 及以上,执行:echo "3 4 1 7" > /proc/sys/kernel/printk
通过启动参数永久修改
在 GRUB 配置文件中,可以在内核启动行添加 loglevel=X。
- 设置步骤:
- 编辑
/etc/default/grub。 - 在
GRUB_CMDLINE_LINUX_DEFAULT中加入loglevel=3。 - 执行
update-grub或grub2-mkconfig更新配置并重启。
- 编辑
深度分析:内核崩溃与 Oops 信息的解读
当内核遇到无法恢复的错误时,会触发 Kernel Oops 或 Kernel Panic,此时日志中会出现一段复杂的堆栈跟踪(Stack Trace)。
关键字段解析
- Unable to handle kernel paging request:通常意味着内核尝试访问无效的内存地址(空指针或越界)。
- RIP (Instruction Pointer):崩溃时执行的指令地址,这是定位代码行数的关键。
- Call Trace:函数调用栈,由下而上阅读,可以看到导致崩溃的调用链。
- Code:崩溃点附近的机器码。
实操分析路径
- 提取 Oops 信息:通过
dmesg或/var/log/messages复制完整的崩溃片段。 - 使用 addr2line 定位:
addr2line -e vmlinux [RIP地址]
这可以将内存地址转换为源代码的具体行号(前提是拥有带调试信息的vmlinux文件)。 - 利用 kdump 捕获 vmcore:
在生产环境中,业内通常配置 kdump,当内核崩溃时,kdump 会启动一个备用内核,将崩溃瞬间的内存镜像(vmcore)保存到磁盘。- 分析工具:使用
crash工具加载vmcore和vmlinux。 - 核心命令:
bt(backtrace) 查看崩溃线程的堆栈。
- 分析工具:使用
Linux内核log是系统底层状态的唯一映射,通过 dmesg 处理实时故障,利用 syslog 追溯历史,配合 /proc/sys/kernel/printk 优化输出,并结合 kdump 进行深度崩溃分析,可以构建起完整的内核调试链路。
linux内核log 相关常见问题 Q&A
如何清理 dmesg 中的旧日志?
使用命令 dmesg -C 可以清空内核环形缓冲区,该操作需要 root 权限,执行后 dmesg 将不再显示之前的记录,仅显示执行该命令后的新日志。
为什么 /var/log/kern.log 中没有看到 dmesg 的所有内容?
这是因为 syslogd 或 rsyslog 设有过滤规则,如果内核日志级别高于 /etc/rsyslog.conf 中定义的接收级别,或者 printk 的控制台级别设置过高,部分低级别的 INFO 或 DEBUG 信息将被丢弃,不会写入磁盘文件。
内核日志过多导致系统卡顿怎么处理?
这种情况通常是由于某个驱动程序在循环中不断调用 printk 导致 CPU 资源被日志 I/O 占用,应立即通过 echo "3 4 1 7" > /proc/sys/kernel/printk 提高控制台打印阈值以减轻压力,随后通过 dmesg 快速定位产生大量重复日志的模块并尝试卸载或修复该驱动。
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/490283.html



