前言

在 Linux 系统中,日志是系统管理和故障排除的重要工具。特别是与内核相关的日志,对于了解系统底层的运行情况至关重要。本文将探讨 /dev/kmsg, /proc/kmsg 和 dmesg 这三者的作用和使用。

/dev/kmsg

/dev/kmsg 是一个字符设备文件,用于访问内核消息缓冲区。它的主要作用是允许用户空间的进程直接向内核日志发送消息。这在调试和记录用户空间应用程序的日志时非常有用。

读取内核消息
可以使用 cat 或 tail 命令来读取内核消息。例如:

sudo cat /dev/kmsg

写入内核消息
可以使用 echo 命令将消息写入内核日志。例如:

echo "Custom log message from user space" | sudo tee /dev/kmsg
dmesg | tail -n 5

/proc/kmsg

/proc/kmsg 是一个虚拟文件,提供对内核日志缓冲区的只读访问。该文件显示了系统启动以来记录的内核消息。与 /dev/kmsg 不同,/proc/kmsg 主要用于读取内核日志,而不能写入。

读取内核消息
同样,可以使用 cat 或 tail 命令读取内核消息。例如:

sudo cat /proc/kmsg

避坑1:
在 ubuntu 20.04 下,执行 sudo cat /proc/kmsg 不会输出任何信息。
在 CentOS 7 下,可以。

/proc/kmsg 是专门输出内核信息的地方,为了能够方便的在 user space 读取 Kernel log,Kernel driver 里面将 ring buffer 映射到了 /proc 目录下的文件节点 /proc/kmsg。所以读取 /proc/kmsg 文件其实就是在访问 Kernel Log 的循环缓冲区。虽然 Log buffe 的大小是固定的,但是可以通过不断的访问 /proc/kmsg 将所有的 log 都备份下来。
使用限制:
由于 Kernel log buffer 循环缓冲区只有一个读指针,所以当一个程序在读 buffer 的时候会不断的移动 buffer 的读指针,这样当有多个程序读取 buffer 的时候每个程序得到的 log 都不是完整的。所以当访问 /proc/kmsg 的时候务必保证没有其它程序读取 Kernel Log Buffer。
/proc/kmsg 的 Owner 是 root,群组属于 System,所以在 user 版本上面是无法读取 Kernel Log Buffer 的。

避坑2:
与 dmesg 不同, 第一次执行 sudo cat /proc/kmsg 打印到目前位置的所有内核信息,再次执行 sudo cat /proc/kmsg,不打印之前打印过了的信息。

[root@VM-0-3-centos ~]# echo aaa > /dev/kmsg 
[root@VM-0-3-centos ~]# cat /proc/kmsg 
<12>[4994196.601077] aaa

dmesg

dmesg 是一个用户空间的命令,用于显示和控制内核环形缓冲区中的消息。它会读取并显示 /dev/kmsg 中的内容,因此也可以视为一种查看内核消息的方式。

可以直接运行 dmesg 命令来查看内核消息。例如:

dmesg

实时查看内核日志

dmesg -w

可以将内核消息保存到文件中,以便后续分析。例如:

dmesg > kernel_log.txt

清除 Kernel log buffer 的内容

dmesg -C

底层

ring buffer(‘log_buf’)

在 linux 中,所有的系统信息(包内核信息)都会传送到 ring buffer(‘log_buf’) 中。而内核产生的信息由 printk() 打印产生,系统启动时所看到的信息都是由该函数打印到屏幕中或者串口等其他地方。 printk() 打出的信息往往以 <0>…<2>… 这的数字表明消息的重要级别。高于一定的优先级别会打印到屏幕上,否则只会保留在系统的缓冲区中(ring buffer)。

查看系统信息放置的位置

linux 系统启动后,由 /etc/init.d/sysklogd 先后启动 klogd、syslogd 两个守护进程。其中 klogd 会通过 syslog() 系统调用或者读取 proc 文件系统来从系统缓冲区 (ring buffer) 中得到由内核 printk() 发出的信息。而 syslogd 是通过 klogd 来读取系统内核信息(klogd 将读到的东西发给 syslogd)。kogd 和 syslogd 都是用户空间进程。klogd 的输出结果会传送给 syslogd 进行处理,syslogd 会根据 /etc/syslog.conf(ubuntu 的 /etc/syslog.conf 不再有!而是 /etc/rsyslog.conf 代替!)的配置把 log 信息输出到 /var/log/ 下的不同文件中。
klogd 也不再有,它的功能已经被集成到其他日志处理系统中了,如 rsyslog 或 systemd-journald。

现代日志系统的演变

1、syslogd

syslogd 是传统的系统日志守护进程,用于收集和记录系统日志消息。

2、klogd

klogd 是一个守护进程,专门用于捕获内核日志消息,并将它们发送给 syslogd 或写入文件。在较旧的系统中,syslogd 和 klogd 通常一起运行。

rsyslogd 和 systemd-journald

1、rsyslogd

现代的 Ubuntu 系统默认使用 rsyslogd,它是一个更先进和灵活的系统日志工具,能够处理和路由内核日志消息(通过读取 /proc/kmsg 或 /dev/kmsg)以及其他系统日志消息。
rsyslogd 可以替代 syslogd 和 klogd,提供统一的日志处理功能。

2、systemd-journald

许多现代 Linux 发行版,包括 Ubuntu,也使用 systemd-journald,这是 systemd 提供的日志收集守护进程。
systemd-journald 收集内核日志、用户空间日志、启动消息以及审计信息,并将它们存储在二进制日志文件中。
当使用 systemd-journald 时,syslogd 和 klogd 的功能也被集成到这个单一的守护进程中。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐