Linux 日志級別(loglevel)詳解



http://smilejay.com/2011/12/linux_loglevel/


前幾天,我在想printk中到底是哪些信息會打印到console上,哪些東西可以通過dmesg來查看。參考了網上一些資料以及自己做的一些實驗,總結一下Linux中的console loglevel以及printk, dmesg知識。

只有當printk打印信息時的loglevel小於console loglevel的值(即:優先級高於console loglevel),這些信息才會被打印到console上。

改變console loglevel的方法有如下幾種:
1.啟動時Kernel boot option:loglevel=level
2.運行時Runtime: dmesg -n level
(注意:demsg -n level 改變的是console上的loglevel,dmesg命令仍然會打印出所有級別的系統信息。)
3.運行時Runtime: echo $level > /proc/sys/kernel/printk
4.運行時Runtime:寫程序使用syslog系統調用(可以man syslog)

在kernel boot option中:

loglevel Set the default console log level.
loglevel=level
Specify the initial console log level. Any log messages with levels less than this (that is, of higher priority) will be printed to the console, whereas any messages with levels equal to or greater than this will not be displayed.
The console log level can also be changed by the klogd program, or by writing the specified level to the /proc/sys/kernel/printk file. (在2.6.32及之上kernel的Linux系統中,我沒有找到klogd這個程序了,應該是有所變化了)

The kernel log levels are:
0 (KERN_EMERG)
The system is unusable.
1 (KERN_ALERT)
Actions that must be taken care of immediately.
2 (KERN_CRIT)
Critical conditions.
3 (KERN_ERR)
Noncritical error conditions.
4 (KERN_WARNING)
Warning conditions that should be taken care of.
5 (KERN_NOTICE)
Normal, but significant events.
6 (KERN_INFO)
Informational messages that require no action.
7 (KERN_DEBUG)
Kernel debugging messages, output by the kernel if the developer enabled debugging at compile time.

KERN_ERR, KERN_DEBUG等是一些宏定義,在$Linux_SRC/include/linux/printk.h中可以查看到。

dmesg是從kernel的ring buffer(環緩沖區)中讀取信息的.
man dmesg得到如下信息:
dmesg is used to examine or control the kernel ring buffer.
The program helps users to print out their bootup messages. Instead of copying the messages by hand, the user need only: dmesg > dmesg.log

那什么是ring buffer呢?
在LINUX中,所有的系統信息(包內核信息)都會傳送到ring buffer中。而內核產生的信息由printk()打印出來。系統啟動時所看到的信息都是由該函數打印到屏幕中。printk()打出的信息往往以 <0>…<2>… 這的數字表明消息的重要級別。高於一定的優先級別(當前的console loglevel)就會打印到console上,否則只會保留在系統的緩沖區中(ring buffer)。
至於dmesg具體是如何從ring buffer中讀取的,大家可以看dmesg.c源代碼。$Linux-SRC/arch/m68k/tools/amiga/dmesg.c,很短,比較容易讀懂。

默認的loglevel在kernel/printk.c中有定義:

cat /proc/sys/kernel/printk
4 4 1 7
所得到的信息是$Linux_SRC/include/linux/printk.h中定義的宏:
#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])
依次分別為:
控制台日志級別:優先級高於該值的消息將被打印至控制台
缺省的消息日志級別:將用該優先級來打印沒有優先級的消息
最低的控制台日志級別:控制台日志級別可被設置的最小值(最高優先級)
缺省的控制台日志級別:控制台日志級別的缺省值

為了下面我做的一個實驗:
首先,需要一個module,我的loglevel.c代碼如下:

將這個module編譯好之后,有了loglevel.ko這個module文件。

console上打印的信息如下:
##注意DEBUG級別的信息沒有打印在console上
Loading loglevel module…
Hello, Jay.
————————————
Hello, EMERG.
Hello, ALERT.
Hello, CRIT.
Hello, ERR.
Hello, WARNING.
Hello, NOTICE.
Hello, INFO.
————————————

改變console loglevel之后,

##注意”Hello, Jay.”這樣的INFO級別的就沒有打印到console上
————————————
Hello, EMERG.
Hello, ALERT.
Hello, CRIT.
Hello, ERR.
————————————

在kernel啟動項目中加入了debug,則啟動后:

##注意這次DEBUG等級的信息也被打印在console上了
Loading loglevel module…
Hello, Jay.
————————————
Hello, EMERG.
Hello, ALERT.
Hello, CRIT.
Hello, ERR.
Hello, WARNING.
Hello, NOTICE.
Hello, INFO.
Hello, DEBUG.
————————————

而dmesg始終都是可以打印出module所print出來的所有信息的,不管console loglevel為多少,當insmod loglevel之時,dmesg始終會打印如下信息:

Loading loglevel module...
Hello, Jay.
------------------------------------
Hello, EMERG.
Hello, ALERT.
Hello, CRIT.
Hello, ERR.
Hello, WARNING.
Hello, NOTICE.
Hello, INFO.
Hello, DEBUG.
------------------------------------

另外,最后見說一下syslogd吧(或者新的叫做rsyslogd進程)。 在比較新的系統(比如RHEL6.1)中,syslogd已經存在了,取而代之的是rsyslogd,功能是差不多的,配置文件在/etc/rsyslogd.conf
syslogd這個守護進程根據/etc/syslog.conf,將不同的服務產生的Log記錄到不同的文件中.
LINUX系統啟動后,由/etc/init.d/sysklogd先后啟動klogd,syslogd兩個守護進程。
其中klogd會通過syslog()系統調用或者讀取/proc/kmsg文件來從系統緩沖區(ring buffer)中得到由內核printk()發出的信息.而syslogd是通過klogd來讀取系統內核信息.
(1)所有系統信息是輸出到ring buffer中去的,dmesg所顯示的內容也是從ring buffer中讀取的.
(2)LINUX系統中/etc/init.d/sysklogd會啟動2個守護進程:Klogd, Syslogd
(3)klogd是負責讀取內核信息的,有2種方式:
syslog()系統調用(這個函數用法比較全,大家去MAN一下看看);
直接的對/proc/kmsg進行讀取(再這提一下,/proc/kmsg是專門輸出內核信息的地方)
(4)Klogd的輸出結果會傳送給syslogd進行處理,syslogd會根據/etc/syslog.conf的配置把log信息輸出到/var/log/下的不同文件中.

可以將printk與syslog接合使用, 用在內核開發方面很不錯的應用:
修改/etc/syslog.conf (或者是/etc/rsyslogd.conf)
kern.* /tmp/my_kernel_debug.txt
就可將kernel的信息輸出到文件中了,這樣更方便查看。

日志文件詳細地記錄了系統每天發生的各種各樣的事件。用戶可以通過日志文件檢查錯誤產生的原因,或者在受到攻擊和黑客入侵時追蹤攻擊者的蹤跡。日志的兩個比較重要的作用是:審核和監測。
Linux系統的日志主要分為兩種類型:
1.進程所屬日志
由用戶進程或其他系統服務進程自行生成的日志,比如服務器上的access_log與error_log日志文件。
2.syslog消息 【syslogd, klogd協同作用,前面以及提及,新版本中都沒了klogd了】
系統syslog記錄的日志,任何希望記錄日志的系統進程或者用戶進程都可以給調用syslog來記錄日志。
日志系統可以划分為三個子系統:
1.連接時間日志–由多個程序執行,把紀錄寫入到/var/log/wtmp和/var/run/utmp,login等程序更新wtmp和utmp文件,使系統管理員能夠跟蹤誰在何時登錄到系統。
2.進程統計–由系統內核執行。當一個進程終止時,為每個進程往進程統計文件(pacct或acct)中寫一個紀錄。進程統計的目的是為系統中的基本服務提供命令使用統計。
3.錯誤日志–由syslogd(8)執行。各種系統守護進程、用戶程序和內核通過syslog(3)向文件/var/log/messages報告值得注意的事件。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM