printk根據日誌級別(loglevel)對消息進行分類。日誌級別用宏定義,日誌級別宏展開爲一個字符串,在編譯時由預處理器將它和消息文本拼接成一個字符串,因此printk 函數中日誌級別宏和格式字符串間不能有逗號。
下面是兩個printk的例子,一個用於打印調試信息,另一個用於打印臨界條件信息。
printk(KERN_DEBUG "Here I am: %s:%i/n", _ _FILE_ _, _ _LINE_ _); printk(KERN_CRIT "I'm trashed; giving up on %p/n", ptr);
printk的日誌級別定義如下(在linux26/includelinux/kernel.h中):
#defineKERN_EMERG"<0>" #defineKERN_ALERT"<1>" #defineKERN_CRIT"<2>" #defineKERN_ERR"<3>" #defineKERN_WARNING"<4>" #defineKERN_NOTICE"<5>" #defineKERN_INFO"<6>" #defineKERN_DEBUG"<7>" extern int console_printk[]; #define console_loglevel (console_printk[0]) #define default_message_loglevel (console_printk[1]) #define minimum_console_loglevel (console_printk[2]) #define default_console_loglevel (console_printk[3]) |
日誌級別的範圍是0~7,沒有指定日誌級別的printk語句默認採用的級別是 DEFAULT_ MESSAGE_LOGLEVEL,其定義列出如下(在linux26/kernel/printk.c中):
#define DEFAULT_MESSAGE_LOGLEVEL 4 |
內核可把消息打印到當前控制檯上,可以指定控制檯爲字符模式的終端或打印機等。默認情況下,“控制檯”就是當前的虛擬終端。
爲了更好地控制不同級別的信息顯示在控制檯上,內核設置了控制檯的日誌級別console_loglevel。printk日誌級別的作用是打印一定級別的消息,與之類似,控制檯只顯示一定級別的消息。
當printk的日誌級別小於console_loglevel時,消息才能顯示出來。控制檯相應的日誌級別定義如下:
#define MINIMUM_CONSOLE_LOGLEVEL 1 #define DEFAULT_CONSOLE_LOGLEVEL 7 int console_printk[4] = { DEFAULT_CONSOLE_LOGLEVEL, DEFAULT_MESSAGE_LOGLEVEL, MINIMUM_CONSOLE_LOGLEVEL, DEFAULT_CONSOLE_LOGLEVEL, }; |
如果系統運行了klogd和syslogd,則無論console_loglevel爲何值,內核消息都將追加到/var/log/messages中。如果klogd沒有運行,消息不會傳遞到用戶空間,只能查看/proc/kmsg。
變量console_loglevel的初始值是DEFAULT_CONSOLE_LOGLEVEL,可以通過sys_syslog系統調用進行修改。調用klogd時可以指定-c開關選項來修改這個變量。如果要修改它的當前值,必須先殺掉klogd,再加-c選項重新啓動它。
注:#ps -e 查看所有進程PID,然後KILL。
通過讀寫/proc/sys/kernel/printk文件可讀取和修改控制檯的日誌級別。查看這個文件的方法如下:
#cat /proc/sys/kernel/printk 6 4 1 7 |
上面顯示的4個數據分別對應控制檯日誌級別、默認的消息日誌級別、最低的控制檯日誌級別和默認的控制檯日誌級別。
可用下面的命令設置當前日誌級別:
# echo 8 > /proc/sys/kernel/printk