【zz】printk()调试信息分级显示脚本的编写方法

printk()调试信息分级显示脚本的编写方法
   大家都知道,在编写内核程序时printk()在<linux/kernel.h>中定义了一些用于调试的宏,它们是:
   KERN_EMERG "<0>" 系统不可用
   KERN_ALERT "<1>" 必须采取措施
   KERN_CRIT "<2>" 严重状态
   KERN_ERR "<3>" 错误状态
   KERN_WARNING "<4>" 警告状态
   KERN_NOTICE "<5>" 正常但重要的情况
   KERN_INFO "<6>" 消息
   KERN_DEBUG "<7>" 调试级别信息
    输出的printk()调试信息默认情况是输出到/var/log/message这个日志文件中的。如果想把这些调试信息输出到一些指定的文件中,可以使用本文介绍的这个方法,当然这也就是本文产生的原因。
   (1)首先,要在/your_debug_message_path/目录下建立messages、messages-debug、messages- info、messages-notice、messages-warning、messages-err、messages-crit、 messages-alert等文件,用来存储调试信息。
   (2)然后,为了能分级显示printk()调试信息,要在/etc/syslog.conf文件中添加以下内容:
#+——————–+
#下面这个文件包含<0-7>的所有printk()调试信息
kern. /your_debug_message_path/messages#下面这个文件只包含KERN_DEBUG "<7>"的调试信息
kern.=debug /your_debug_message_path/messages-debug#下面这个文件只包含KERN_INFO "<6>"的调试信息
kern.=info /your_debug_message_path/messages-info#下面这个文件只包含KERN_NOTICE "<5>"的调试信息
kern.=notice /your_debug_message_path/messages-notice#下面这个文件只包含KERN_WARNING "<4>"的调试信息,但是要尽量少使用这个等级的调试
kern.=warning /your_debug_message_path/messages-warning#下面这个文件只包含KERN_ERR "<3>"的调试信息,但是要尽量少使用这个等级的调试
kern.=err /your_debug_message_path/messages-err#下面这个文件只包含KERN_CRIT "<2>"的调试信息
kern.=crit /your_debug_message_path/messages-crit#下面这个文件只包含KERN_ALERT "<1>"的调试信息
kern.=alert /your_debug_message_path/messages-alert
#+———————-+
   这样,就可以cat某个文件看到相应级别的调试信息了。当然,还要reboot一下,这个脚本才可以生效!
在长期使用中,调试信息一定会越来越多,并且文件肯定会越来越大。为了防止messages
系列文件过大,要限制她的大小,下面是相应的脚本。
   (3)要在/etc/rc.d/rc.local文件中加入以下内容:
+—————+
#这是一个用户添加的启动项
/your_debug_message_path/check_message_size/my_logsize_check_shell
+—————-+
   (4)建立/your_debug_message_path/checksize_back目录,并在该目录下建立同样的messages、 messages-debug、messages-info、messages-notice、messages-warning、messages- err、messages-crit、messages-alert等空文件,作为文件刷新时的样本文件。
   (5)编写/your_debug_message_path/check_message_size/my_logsize_check_shell脚本:
#!/bin/sh
#+——————————+
logdir="/your_debug_message_path"
backupdir="/your_debug_message_path/checksize_back"#这是文件的最大值,超过这个值就把/your_debug_message_path/checksize_back目录下的文件
#cat到/your_debug_message_path目录下,刷新过大的文件。
capacity=400000 size=wc ${logdir}/messages | awk &quot;{print }&quot;
if [ $size -gt $capacity ]
then
cat ${backupdir}/messages > ${logdir}/messages
fi size=wc ${logdir}/messages-alert | awk &quot;{print }&quot;
if [ $size -gt $capacity ]
then
cat ${backupdir}/messages-alert > ${logdir}/messages-alert
fi size=wc ${logdir}/messages-crit | awk &quot;{print }&quot;
if [ $size -gt $capacity ]
then
cat ${backupdir}/messages-crit > ${logdir}/messages-crit
fi size=wc ${logdir}/messages-err | awk &quot;{print }&quot;
if [ $size -gt $capacity ]
then
cat ${backupdir}/messages-err > ${logdir}/messages-err
fi size=wc ${logdir}/messages-info | awk &quot;{print }&quot;
if [ $size -gt $capacity ]
then
cat ${backupdir}/messages-info > ${logdir}/messages-info
fi size=wc ${logdir}/messages-notice | awk &quot;{print }&quot;
if [ $size -gt $capacity ]
then
cat ${backupdir}/messages-notice > ${logdir}/messages-notice
fi size=wc ${logdir}/messages-warning | awk &quot;{print }&quot;
if [ $size -gt $capacity ]
then
cat ${backupdir}/messages-warning > ${logdir}/messages-warning
fi size=wc ${logdir}/messages-debug | awk &quot;{print }&quot;
if [ $size -gt $capacity ]
then
cat ${backupdir}/messages-debug > ${logdir}/messages-debug
fi
#+——————————————+
   reboot系统,这个脚本就会生效。


//将info或更高级别的消息送到/var/log/messages,除了mail以外。
//其中是通配符,代表任何设备;none表示不对任何级别的信息进行记录。
.info;mail.none;authpriv.none          /var/log/messages

//将authpirv设备的任何级别的信息记录到/var/log/secure文件中,这主要是一些和认、权限使用相关的信息。
authpriv.      /var/log/secure

//将mail设备中的任何级别的信息记录到/var/log/maillog文件中,这主要是和电子邮件相关的信息。
mail.
      /var/log/maillog

//将cron设备中的任何级别的信息记录到/var/log/cron文件中,这主要是和系统中定期执行的任务相关的信息。
cron.      /var/log/cron

//将任何设备的emerg级别的信息发送给所有正在系统上的用户。
.emerg     

//将uucp和news设备的crit级别的信息记录到/var/log/spooler文件中。
uucp,news.crit      /var/log/spooler

//将和系统启动相关的信息记录到/var/log/boot.log文件中。
local7.
        /var/log/boot.log



消息是如何记录的
printk函数将消息写到一个长度为LOG_BUF_LEN个字节的循环缓冲区中。然后唤醒任何等待消息的进程,即那 些在调用syslog系统调用或读取/proc/kmesg过程中睡眠的进程。这两个访问记录引擎的接口是等价的。

如果循环缓冲区填满了,printk就绕到缓冲区的开始处 填写新数据,覆盖旧数据。于是记录进程就丢失了最旧的数据。这个问题与利用循环缓冲区所获得的好处相比可以忽略不计。例如,循环缓冲区可以使系统在没有记 录进程的情况下照样运行,同时又不浪费内存。Linux处理消息的方法的另一个特点是,可以在任何地方调用printk,甚至在中断处理函数里也可以调 用,而且对数据量的大小没有限制。这个方法的唯一缺点就是可能丢失某些数据。

如果klogd正在运行,它读取内核消息并将它们分派到 syslogd,它随后检查/etc/syslog.conf找到处理这些数据的方式。syslogd根据一个“设施”和“优先级”切分消息;可以使用的 值定义在<sys/syslog.h>中。内核消息根据相应printk中指定的优先级记录到LOG_KERN设施中。如果klogd没有运 行,数据将保存在循环缓冲区中直到有进程来读取数据或数据溢出。

可以给 klogd指定-f(文件)选项或修改/etc/syslog.conf将记录写到另一个文件中。另一种方法是一种强硬方法:杀掉klogd,将消息打印 到不用的虚终端上*,或者在一个不用的xterm上执行cat /proc/kmesg显示消息。

http://blog.csdn.net/cugxueyu/archive/2007/12/21/1957740.aspx





~~end~~