printk是在核心中運作的向控制台輸出顯示的函數,根據優先級确定是否向控制台輸出。
用printk,核心會根據 日志級别,可能把消息列印到目前控制台上,這個控制台通常是一個字元模式的終端、一個序列槽列印機或是一個 并口列印機。這些消息正常輸出的前提是── 日志輸出級别小于console_loglevel(在 核心中數字越小優先級越高)。 沒有指定日志級别的printk語句預設采用的級别是 DEFAULT_ MESSAGE_LOGLEVEL(這個預設級别一般為<4>,即與KERN_WARNING在一個級别上),其定義在linux26/kernel/printk.c中可以找到 、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 其實printk始終是能輸出資訊的,隻不過不一定是到了終端上。我們可以去 /var/log/messages這個檔案裡面去檢視。 如果klogd沒有運作,消息不會傳遞到 使用者空間,隻能檢視/proc/kmsg 通過讀寫/proc/sys/kernel/printk檔案可讀取和修改控制台的 日志級别。檢視這個檔案的方法如下: #cat /proc/sys/kernel/printk 6 4 1 7 上面顯示的4個資料分别對應控制台 日志級别、預設的消息日志級别、最低的控制台日志級别和預設的控制台日志級别。 可用下面的指令設定目前日志級别: # echo 8 > /proc/sys/kernel/printk 這樣所有級别<8,(0-7)的消息都可以顯示在控制台上.
首先,printk有8個loglevel,定義在<linux/kernel.h>中,其中數值範圍從0到7,數值越小,優先級越高。
#define KERN_EMERG "<0>" 系統崩潰
#define KERN_ALERT "<1>"必須緊急處理
#define KERN_CRIT "<2>" 臨界條件,嚴重的硬軟體錯誤
#define KERN_ERR "<3>" 報告錯誤
#define KERN_WARNING "<4>" 警告
#define KERN_NOTICE "<5>" 普通但還是須注意
#define KERN_INFO "<6>" 資訊
#define KERN_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])
未指定優先級的預設級别定義在/kernel/printk.c中:
#define DEFAULT_MESSAGE_LOGLEVEL 4
#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, 預設終端級别
};
當優先級的值小于console_loglevel這個整數變量的值,資訊才能顯示出來。而console_loglevel的初始值DEFAULT_CONSOLE_LOGLEVEL也定義在/kernel/printk.c中:
cat /proc/sys/kernel/printk
4 4 1 7
這個預設值是在sysctl.conf中寫的,在系統啟動時就把這個值寫到/proc/sys/kernel/printk這個檔案了。也可以使用下面的指令修改其值
echo 0 > /proc/sys/kernel/printk
cat /proc/sys/kernel/printk
0 4 1 7
它們根據日志記錄消息的重要性,定義将其發送到何處。關于不同日志級别的更多資訊,請閱讀 syslog(2) 聯機幫助頁。該檔案的四個值為:
控制台日志級别:優先級高于該值的消息将被列印至控制台
預設的消息日志級别:将用該優先級來列印沒有優先級的消息
最低的控制台日志級别:控制台日志級别可被設定的最小值(最高優先級)
預設的控制台日志級别:控制台日志級别的預設值