我开发了我自己的日志处理程序。 处理源自printk()的日志,我从内核环形缓冲区中读取,如下所示:
#define _PATH_KLOG "/proc/kmsg" CGR_INT kernelRingBufferFileDescriptor = open(_PATH_KLOG, O_RDONLY|O_NONBLOCK); CGR_CHAR kernelLogMessage[MAX_KERNEL_RING_BUFFER + 1] = {'\0'}; while (1) { ... read(kernelRingBufferFileDescriptor, kernelLogMessage + residueSize, MAX_KERNEL_RING_BUFFER); ... }
我的程序在用户空间。 我记得有人用read()读取环形缓冲区中的数据(就像我上面所做的那样),读取的部分将从环形缓冲区中清除。 是这样,还是不是?
我对此感到困惑,因为环形缓冲区中总是有一些东西,所以我的程序非常忙于处理所有这些日志。 所以我不确定是因为某些模块正在向我发送日志,或者是因为我一次又一次读取相同的日志,因为日志没有被清除。
要弄清楚,我使用klogctl()来检查环形缓冲区:
CGR_CHAR buf[MAX_KERNEL_RING_BUFFER] = {0}; int byteCount = klogctl(4, buf, MAX_KERNEL_RING_BUFFER - 1); /* 4 -- Read and clear all messages remaining in the ring buffer */ printf("%s %d: data read from kernel ring buffer = \"%s\"\n",__FILE__, __LINE__, buf);
我一直在收集数据。 由于带有参数4的klogctl()读取并清除环形缓冲区,所以我相信有些模块会一直向我发送日志。
谁能告诉我 – 读取()清除环形缓冲区?
成为root并运行这个cat /proc/kmsg >> File1.txt
和cat /proc/kmsg >> File2.txt
。 比较File2.txt
和File2.txt
您将立即知道在read()
上环形缓冲区是否被清除。cos cat
内部调用read()
!
还请阅读关于环形缓冲区以及它们如何在内核文档中的行为 – http://www.mjmwired.net/kernel/Documentation/trace/ring-buffer-design.txt
编辑 :我发现了一些有趣的书籍 Linux Device Drivers
由乔纳森科贝特 –
printk函数将消息写入__LOG_BUF_LEN字节长的循环缓冲区:配置内核时选择的值为4 KB至1 MB 。 然后该函数唤醒正在等待消息的任何进程,即在syslog系统调用中正在休眠或正在读取/ proc / kmsg的进程。 这两个接口与日志记录引擎几乎是等价的,但是请注意, 从/ proc / kmsg中读取消耗了日志缓冲区中的数据 ,而syslog系统调用可以选择性地返回日志数据,而将其留给其他进程使用。 通常,读取/ proc文件比较容易,而且是klogd的默认行为。 dmesg命令可以用来查看缓冲区的内容而不用清除它; 实际上,该命令返回标准输出缓冲区的全部内容,不管它是否已被读取
所以在你的特殊情况下,如果你正在使用一个简单的read()
,我认为缓冲区确实已经被清除了,并且新的数据被不断的写入,所以你总是可以找到一些数据! 内核专家可以在这里纠正我!
从阅读do_syslog
函数看来,消息在读取时被清除。
通过你的描述,你会得到与klogctl(4)
相同的行为,这也清除了缓冲区,所以它是有道理的。
所以也许确实有人不断写信息。
你可以通过文本找到它是哪个printk
,禁用它,看看你得到了什么。 或者你可以把jiffies
值添加到消息中,所以你会知道你是否继续收到新消息,或者这些消息是相同的。