printk的用法

来源:互联网 发布:dc大事件 知乎 编辑:程序博客网 时间:2024/05/17 23:16

内核通过 printk() 输出的信息具有日志级别,日志级别是通过在 printk() 输出的字符串前加一个带尖括号的整数来控制的,如 printk("<6>Hello, world!\n");。内核中共提供了八种不同的日志级别,在 linux/kernel.h 中有相应的宏对应。

#define KERN_EMERG   "<0>"   /* system is unusable */
#define KERN_ALERT   "<1>"   /* action must be taken immediately */
#define KERN_CRIT     "<2>"   /* critical conditions */
#define KERN_ERR      "<3>"   /* error conditions */
#define KERN_WARNING "<4>"   /* warning conditions */
#define KERN_NOTICE   "<5>"   /* normal but significant */
#define KERN_INFO     "<6>"   /* informational */
#define KERN_DEBUG    "<7>"   /* debug-level messages */

所以 printk() 可以这样用:printk(KERN_INFO "Hello, world!\n");

未指定日志级别的 printk() 采用的默认级别是 DEFAULT_MESSAGE_LOGLEVEL,这个宏在 kernel/printk.c 中被定义为整数 4,即对应KERN_WARNING。

在 /proc/sys/kernel/printk 会显示4个数值(可由 echo 修改),分别表示当前控制台日志级别未明确指定日志级别的默认消息日志级别最小(最高)允许设置的控制台日志级别、引导时默认的日志级别。当 printk() 中的消息日志级别小于当前控制台日志级别时,printk 的信息(要有\n符)就会在控制台上显示。但无论当前控制台日志级别是何值,通过 /proc/kmsg (或使用dmesg)总能查看。另外如果配置好并运行了 syslogd 或 klogd,没有在控制台上显示的 printk 的信息也会追加到 /var/log/messages.log 中。

char myname[] = "chinacodec\n";
printk(KERN_INFO "Hello, world %s!\n", myname);


printk 

4.2.1. printk函数


        我们在前面章节中简单地把printk当作printf函数来使用。现在是时候来介绍它的一些不同之处了。 

        其中一个不同点是,printk允许你按照相关的记录级或优先级将消息严格分类。通常你需要一个宏来指定记录等级。例如,KERN_INFO,我们在早先的的例子中看到过这个宏,它就是消息记录等级的一种。记录等级宏的作用是扩展为一个字符串,这个字符串会在编译期间与相应的消息文本相连接;这就解释了下面例子中为什么在优先级和格式化字符串之间没有逗号了。下面是两个printk函数的例子,一个是调试消息,一个是临界消息: 

printk(KERN_DEBUG "Here I am: %s:%i\n", _ _FILE_ _, _ _LINE_ _);



printk(KERN_CRIT "I'm trashed; giving up on %p\n", ptr);

        
        
在头文件<linux/kernel.h>中共定义了八个可用的记录级;我们下面按其严重性倒序列出: 
KERN_EMERG
Used for emergency messages, usually those that precede a crash. 
用于突发性事件的消息,通常在系统崩溃之前报告此类消息。 
KERN_ALERT
A situation requiring immediate action. 
在需要立即操作的情况下使用此消息。 
KERN_CRIT
Critical conditions, often related to serious hardware or software failures. 
用于临界条件下,通常遇到严重的硬软件错误时使用此消息。 
KERN_ERR
Used to report error conditions; device drivers often use KERN_ERR to report hardware difficulties. 
用于报告错误条件;设备驱动经常使用KERN_ERR报告硬件难题。 
KERN_WARNING
Warnings about problematic situations that do not, in themselves, create serious problems with the system. 
是关于问题状况的警告,一般这些状况不会引起系统的严重问题。 
KERN_NOTICE 
Situations that are normal, but still worthy of note. A number of security-related conditions are reported at this level. 
该级别较为普通,但仍然值得注意。许多与安全性相关的情况会在这个级别被报告。 
KERN_INFO
Informational messages. Many drivers print information about the hardware they find at startup time at this level. 
信息消息。许多驱动程序在启动时刻用它来输出获得的硬件信息。

KERN_DEBUG 

Used for debugging messages. 


用于输出调试信息 

        每一个字符串(由宏扩展而成)表示了尖括号内的一个整数。数值范围从0到7,数值越小,优先级越高。 

        一个printk的缺省优先级是DEFAULT_MESSAGE_LOGLEVEL,它是一个在kernel/printk.c文件中指定的整数。在 2.6.10内核中,DEFAULT_MESSAGE_LOGLEVEL相当于KERN_WARNING,但据说在早期版本中这是两个不同的优先级。 

        基于这些记录级,内核可以把消息输出到当前的控制台,也可以是一个文本模式的终端,一个串口,或是一个并口打印机。如果优先级小于整形变量 console_loglevel,那么一次将会只发送一行消息到控制台中(除非遇到一个换行符,否则将什么都不会发送)。如果系统中运行了klogd和syslogd进程,那么内核消息就会被完整地添加到/var/log/messages文件中(或者根据你的syslogd进程的配置状况进行发送)而忽略console_loglevel,如果klogd没有运行,那么消息将不会到达用户空间,除非你对/proc/kmsg文件读取(实际上这项工作已被较早的dmesg命令完成)。当使用klogd时,你应该记住它不会保留重复的消息行;对于它接收到的重复消息,它只会保留第一条。 

     
        被初始化为DEFAULT_CONSOLE_LOGLEVEL的console_loglevel变量可以通过sys_syslog系统调用修改。改变它内容的一个方法就是在调用klogd时使用-c选项,具体参考klogd的man帮助。请注意,为了改变当前的数值,你必须首先结束klogd进程,并且用-c选项重新启动它。另一种方法是,你可以写一个应用程序来改变控制台的记录等级。你可以在O'Reilly的FTP站点提供的源代码文件中找到/misc-progs/setlevel.c文件,其中就有一个这样的程序。新记录级为一个1到8的整数。如果设置为1,那么只有优先级为0(KERN_EMERG)的消息才可以到达控制台;如果等级设置为8,那么包括调试信息在内的所有消息都会被显示。 

        也可以通过文本文件/proc/sys/kernel/printk来获取和更改控制台的记录等级。这个文件中存储着四个整型数值:当前记录级,缺省记录级,最低记录级和启动时刻的缺省记录级。可以向该文件写入一个单一数值来改变当前记录级;例如,如果你可以想所有的内核消息都可以在控制台中显示,可以使用以下命令: 

# echo 8 > /proc/sys/kernel/printk 

        现在你应该明白在hello.c示例代码中为什么会有KERN_ALERT;标识了吧;这样做可以保证消息顺利地输出到控制台中 。

原创粉丝点击