是否可以将内核消息从特定进程传递到文件

时间:2012-09-19 17:56:04

标签: linux logging linux-kernel pipe

由于这是一个Linux问题,我会注意到我正在使用OpenSUSE 12.1

我正在运行内核模块,基本上它是一个CAN总线模拟器,只要“总线”上有活动,它就会通过printk()打印消息。

我正在使用sudo cat /proc/kmsg跟踪消息,但是当我开始在“总线”上放置其他“设备”时,kmsg流量受到很大影响,很难找到我的消息。

是否有将“printk”消息从一个特定进程传输到文件?

修改 我现在看到如果我在调试消息中添加特定标签有可能,还有其他方法吗?

2 个答案:

答案 0 :(得分:6)

是的,你可以。所有内核消息都可以包含syslog-ng守护进程。对于此守护程序,您可以编写自定义规则并将模块中的所有消息放入特定文件。首先看一下/etc/syslog-ng/syslog-ng.conf

<强>更新

默认情况下,所有内核print和printk函数都将消息放入内核环缓冲区。用户空间程序可以访问此环缓冲区think / proc / kmsg文件。

Syslog-ng将从/ proc / kmsg读取数据,然后通过过滤器(过滤器只是特殊模式)grep输出并将数据放入不同的输出(在本例中它将只是文本文件)。如果在输出缓冲区中我们将找到内核模块“hello”的输出,syslog-ng将把消息放到/ var / log / hello,所有其他消息将转到/ var / log / messages

模块来源

#include <linux/module.h>       
#include <linux/kernel.h>       

#define MODNAME "[hello]"

int init_module(void)
{
        printk(KERN_WARNING MODNAME "Hello world 1.\n");    
        return 1;
}

void cleanup_module(void)
{
        printk(KERN_ALERT "Goodbye world 1.\n");
}

insmod后

  

insmod hello-1.ko

你可以在/ var / log / messages中找到

  

Sep 20 17:46:20 ns1内核:[96643.968650] [你好] Hello world 1。

好的,让我们配置syslog-ng来捕获grep日志消息(使用pattern [hello])

$ cat /etc/syslog-ng/syslog-ng.conf

@version: 3.2
# $Header: /var/cvsroot/gentoo-x86/app-admin/syslog-ng/files/syslog-ng.conf.gentoo.3.2,v 1.1 2011/01/18 17:44:14 mr_bones_ Exp $
#
# Syslog-ng default configuration file for Gentoo Linux

options {
        chain_hostnames(no);    
        stats_freq(43200);
        mark_freq(3600);
};

source src {
    unix-stream("/dev/log" max-connections(256));
    internal();
    file("/proc/kmsg");
};

destination messages { file("/var/log/messages"); };
# output file for ower module
destination hello_messages { file("/var/log/hello"); };   

# grep patterns for ower module
filter f_hello { match("hello" value("MESSAGE")); };
filter f_kernel { facility(kern); };

log { source(src); destination(messages); };
log { source(src); destination(console_all); };

# target for logging    
log { source(src); filter(f_hello); filter(f_kernel); destination(hello_messages); };

答案 1 :(得分:2)

还有另一种方法可以实现这一点:使用任何最新内核的内置“ftrace”支持。

a)对于非常大量的printk流量,printk可能会导致系统瓶颈甚至崩溃 - 然后你应该切换到使用trace_printk();它的开销几乎是微不足道的(特别是与printk相比) b)ftrace能够为特定进程过滤ftrace环形缓冲区。

这里读取详细信息(在任何最新的内核源代码树中): 文档/跟踪/ ftrace.txt

添加资源: “使用Ftrace调试内核 - 第1部分” http://lwn.net/Articles/365835/ (见第2部分)。