syslog協議及rsyslog服務全解析
背景:需求來自於一個客戶想將伺服器的日誌轉發到自己的日誌伺服器上,所以希望我們能提供這個轉發的功能,同時還要滿足syslog協議。
一、什麼是syslog協議
1、介紹(略)
2、syslog標準協議如下圖
這裡的facility為模組,serverity為等級,由這兩個資訊共同計算出一個PRI頭部。HEADER部分包含了時間和主機名。在HEADER和MSG之間有一個空格,MSG是需要記錄的日誌部分(日誌訊息體)。
這裡也就是說,理論上使用這種格式構造的字串傳送,接收方就能解析出來。實際上根據實驗,我使用了UDP傳送,接收方syslog日誌伺服器能正確解析。
這裡需要注意的是,如果使用了程式的庫,比如:python的syslog庫(同樣c++也有相似的庫),那麼就不再需要關注PRI和HEADER部分,只要將相關的引數(facility,severity,time,ip)傳入函式,呼叫傳送就可以,不必自己構造字串。對服務端來說,接收到的是整個訊息,但通常來講,比如使用linux預設的rsyslog作為接收服務端的話,是不能看到除MSG之外的部分。所看到的訊息跟接收端配置有關,這個在下面有具體的講。
3、以下是各級別及對應的數字程式碼
Facility:有0-23種裝置可選,在python的syslog庫中有一部分缺失
0 kernel messages
1 user-level messages
2 mail system
3 system daemons
4 security/authorization messages
5 messages generated internally by syslogd
6 line printer subsystem
7 network news subsystem
8 UUCP subsystem
9 clock daemon
10 security/authorization messages
11 FTP daemon
12 NTP subsystem
13 log audit
14 log alert
15 clock daemon
16-23 local0 - local7
Severity:日誌等級
0 Emergency
1 Alert
2 Critical
3 Error
4 Warning
5 Notice
6 Informational
7 Debug
這裡結合等級再詳細講一下syslog協議:
Priority(優先順序) = facility * 8 + severity值。比如說,一個核心資訊(facility=0)和一個Emergency的severity將會產生優先順序為0。同樣, 一個“local use 4”資訊(facility=20)和一個Notice的severity(severity=5)將會產生165的優先順序。
標題(HEADER)部分由稱為TIMESTAMP和HOSTNAME的兩個域組成,PRI結尾的“>”會馬上跟著一個 TIMESTAMP,任何一個TIMESTAMP或者HOSTNAME域後面都必須跟著一個空格字元。HOSTNAME包含主機的名稱,若無主機名或無法 識別則顯示IP地址。如果一個主機有多個IP地址,它通常會使用它傳送資訊的那個IP地址。TIMESTAMP是本機時間,採用的格式是“Mmm dd hh:mm:ss”表示月日時分秒。HOSTNAME域僅僅能夠包括主機名稱,Ipv4地址或者是資訊產生者的Ipv6地址。
MSG部分是Syslog資料包剩下的部分。這通常包含了產生資訊程序的額外資訊,以及資訊的文字部分。MSG部分有兩個域,分別為TAG域和 CONTENT域,TAG域的值是產生資訊的程式或者程序的名稱,CONTENT包含了這個資訊的詳細內容。傳統上來說,這個域的格式較為自由,並且給出 一些時間的具體資訊。TAG是一個不許超過32個字元的字母數字字串,任何一個非字母數字字元都將會終止TAG域,並且被假設是CONTENT域的開 始。在大多數情況下,表示TAG結束的CONTENT域的第一個字元用左大括號( [ ],分號( : )或者是空格來表示。
下面是一個使用socket實現syslog日誌的py指令碼,大家可以參考,加深理解syslog協議
4、Syslog庫
以python的庫為例:
openlog(ident[, logopt[, facility]])
首先需要使用openlog指定模組及相應的資訊。ident為頭部需要顯示的字串,這個資訊不包含在MSG中,可以通過配置日誌伺服器模板決定是否顯示。logopt是一些引數,可選擇有(LOG_PID, LOG_CONS, LOG_NDELAY, LOG_NOWAIT and LOG_PERROR),對應的分別是(包括每個訊息PID,直接寫入系統控制檯,立即開啟連線,不等待子程序(因為其有可能在記錄訊息的時候就被建立了,GNU C庫不建立子程序,所以該選項在Linux上沒有影響),同時輸出到stderr)。facility則是模組引數,需要填入對應的值,這裡syslog庫中有以下引數使用:
1 2 |
LOG_KERN,
LOG_USER, LOG_MAIL, LOG_DAEMON, LOG_AUTH, LOG_LPR
LOG_NEWS,
LOG_UUCP, LOG_CRON and LOG_LOCAL0
to LOG_LOCAL7
|
通常來說,openlog需要在模組最開始指定,即限定了這個模組內都是一個facility的日誌。
syslog([sevirity], msg):
這個是具體列印日誌的函式,第一個引數指定訊息的級別,第二個引數為日誌內容。
sevirity對應的引數為:
1 |
LOG_EMERG,
LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, <br>LOG_NOTICE, LOG_INFO, LOG_DEBUG.
|
closelog():
這個是關閉的功能,不過多解釋了。
5、說明部分
python的syslog庫列印日誌是依賴了rsyslog服務,具體的轉發規則,記錄檔案等在rsyslog.conf中配置
二、瞭解rsyslog服務
1、rsyslog介紹(略)
2、rsyslog配置檔案
配置檔案/etc/rsyslog.conf大概分為三個部分
#MODULES
這個部分是針對接收配置的,主要是指定接收日誌的協議和埠。若要配置日誌伺服器,則需要將相應的配置項去掉註釋。
#GLOBAL DIRECTIVES
這個部分主要用來配置模板,模板的作用是指定你希望在日誌檔案中儲存的日誌格式。
預設配置為:
1 2 |
#
Use default timestamp format
$ActionFileDefaultTemplate
RSYSLOG_TraditionalFileFormat
|
這裡列舉一個模板,將所有資訊儲存:
1 2 3 4 5 6 7 8 9 10 11 12 |
#
這裡第一行(為了方便顯示,引數寫成了一列)是模板,即日誌伺服器記錄到日誌檔案的格式
#
第二行是指定需要使用的模板myFormat,這個名字可以自己定義
$template
myFormat," % TIMESTAMP % host = % HOSTNAME % ,
relayHost = % FROMHOST % ,
tag = % syslogtag % ,
|