Linux日志系统整体架构
1 为什么需要Kernel日志系统
为什么需要?因为用户空间都是需要通过系统调用(System Call)才能进入内核使用内核服务,内核也只能通过日志暴露问题,比如我们之前提到SPI,驱动probe失败时,用户只知道设备不能工作,不知懂哪里出了问题。
我们可以注入类似
1 | |
在内核启动时将问题暴露出来。
所以Kernel日志系统是Linux内核调试、故障定位和运行状态观察的重要基础设施。
2 Linux日志体系整体架构
整个日志可以分为三层,其结构如下

- 第一层是日志生产者,比如我们之前SPI调用的dev_info。这里用户程序主要会调用内核提供的接口函数
- 第二层是printk日志核心,内核提供的printk 子系统,源码位于kernel/printk/,会把日志记录到环形缓冲区ring buffer
- 第三层是日志消费者,写入内核的日志我们还需要读出来
3 一条Kernel日志生命周期
一条内核日志是怎么走到日志消费者阶段的?
比如我们调用
1 | |
pr_info()是一个宏,不是独立的底层日志系统,就是对printk的封装,其中KERN_INFO表示日志等级。
在printk子系统对日志进行格式化并添加等级、时间戳、序号等信息,然后存入ring buffer。
先对整个流程大致了解,接下来我们会对每一部分详细讲解。
4 printk是什么
用过C语言的都知道printf函数,而printk就是Kernel自己的printf。区别就是printk不会简单地写向 stdout,而是进入内核日志系统。
基本格式
1 | |
拆成两部分日志等级+正文。
日志等级主要有以下
1 | |
其具体含义如上,数字越小,优先级越高、问题越严重。
则上面的例子会被展开为
1 | |
pr_*()又是什么?就是用宏对printk的封装,省略了日志等级的参数:
1 | |
日志等级有什么用?主播目前的理解就是控制台筛选。
我们查看控制台等级
1 | |

第一个数字就是控制台的等级,比整个等级小的会显示到控制台,一样的要看具体配置,比其高的不会显示。
5 ring buffer
ring buffer被叫做内核日志环形缓冲区,是为了专门保存printk() 日志记录的一块内存区域。
它的作用是解决日志产生速度和输出速度的差异。
我们看一他的工作原理

当空间不足时,为新日志腾出空间,最旧日志被覆盖。
6 总结
Linux Kernel日志系统采用”日志产生、日志存储、日志读取”三层架构。内核代码通过printk系列接口产生日志,日志首先被保存到Kernel Log Buffer中,用户空间通过dmesg、/dev/kmsg或者Android logcat读取这些信息。这种设计避免了日志输出阻塞内核执行,同时提供了强大的调试能力。
7 互动
- Linux为什么需要日志系统?
- printk打印出来的日志存在哪里?
- dmesg为什么能看到kernel日志?
- Android中的logcat和kernel日志有什么关系?
- 一条日志完整生命周期是什么?