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協議
https://github.com/ucookie/anytools/blob/master/usyslog/usyslog.py
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 % ,
programName = % programname % , procid = % PROCID % , facility = % syslogfacility - text % , sev = % syslogseverity - text % , appName = % APP - NAME % , msg = % msg % \n" $ActionFileDefaultTemplate
myFormat |
模板額外說明:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#在rsyslog7
和更高版本使用以下格式: template(name = "scalaLogFormat" type = "list" )
{ property (name = "timestamp" dateFormat = "rfc3339" ) constant(value = "
host=" ) property (name = "hostname" ) constant(value = ",
relayHost=" ) property (name = "fromhost" ) constant(value = ",
tag=" ) property (name = "syslogtag" ) constant(value = ",
programName=" ) property (name = "programname" ) constant(value = ",
procid=" ) property (name = "procid" ) constant(value = ",
facility=" ) property (name = "syslogfacility-text" ) constant(value = ",
sev=" ) property (name = "syslogseverity-text" ) constant(value = ",
appName=" ) property (name = "app-name" ) constant(value = ",
msg=" ) property (name = "msg" ) constant(value = "\n" ) } |
### begin forwarding rule
這個模組主要講一下轉發
#*.* @@remote-host:514
根據這個例項可以看出,分為4個部分[模組.等級] [轉發協議][日誌伺服器地址]:[日誌伺服器埠],其中轉發協議的引數@@為TCP協議,對應的接收端也需要配置接受TCP協議。@為UDP協議。
注:使用TCP協議,若地址錯誤或不能連同的情況,轉發的協議會寫入快取,但是不用擔心會卡死伺服器,當到達一定限度後會自動轉存到硬碟,這個不是我們應該關心的部分,使用就好了。
說明:
針對rsyslog.conf配置檔案的所有操作都需要重啟服務生效(service rsyslog restart)
在新版本的rsyslog中,對日誌傳送有預設限速,如果有集中大量推送日誌的情況,需要在配置檔案中加上引數$SystemLogRateLimitInterval 0(具體位置沒有影響,但通常寫在GLOBAL DIRECTIVES模組)
通常來說,日誌推送到伺服器的協議使用UDP
三、例項演示轉發日誌模組
1、python庫實現
這個具體檢視官方文件吧
2、使用TCP/UDP通訊,自己構造syslog訊息傳送
首先了解syslog協議,及接受的方式,自己使用網路程式設計實現轉發日誌變成了可能,下面介紹syslog接受原理
接受端伺服器收到傳送給它的syslog資料包,它將檢查它的有效PRI。如果第一次字元不是一個“<”,或者第三、第四或者第五不是一個 “>”,接收端將認為資料包沒有包含有效的PRI。接著檢查在標題部分的有效TIMESTAMP,從這些規則中,資訊的接收一般有三個情況,下面給 出了這三個情況的通常屬性,並列舉了隨後在這篇中什麼地方會描寫這些情況。
有效的PRI and TIMESTAMP:在資料包中發現一個有效的PRI和TIMESTAMP,那麼會接著檢查資料包的內部配置,接收端必須根據資料包的優先順序來還原,或者 在不對資料包做任何變化的情況下將它轉發出去。這裡要注意到的是接受端沒有必要確認TIMSTIMP裡面的時間,同時接收端也沒有必要確認 HOSTANME的值和傳送資訊裝置的主機名或者IP地址一致。
有效的 PRI,但沒有TIMESTAMP 或者TIMESTAMP無效:要是在資料包中發現一個有效的TIMESTAMP,那麼必須馬上新增一個TIMESTAMP和一個空格字元在PRI部分的結 尾的方括號內,它還必須新增一個HOSTNAME和空格字元在TIMESTAMP後面,接收到的資訊包剩下的部分必須被當曾MSG的CONTENT域並附 加上,由於無法識別產生資訊的裝置所發出的程式,TAG的值無法被識別出來,
所以不會包含再裡面。TIMESTAMP將會是接收端的本地時間,HOSTNAME是裝置的名稱,它被中繼器所識別。如果名字如能被決定, 裝置的IP地址將被使用到。要是中繼器新增一個TIMESTAMP(或者同時新增TIMESTAMP和HOSTNAME)在PRI後面, 然後檢 查是否資料包的總體長度仍然小於或等於1024個位元組。如果資料包被擴充套件超過1024個位元, 中繼器必須截去一部分資料包資料使它到達到1024位元。這將會導致原始資料包結尾部分重要資訊的丟失. 所以,這就是產生的syslog資料包的PRI和HEADER部分包含在4.3節所記錄的值和域之中的緣故。
沒有 PRI or 或者 PRI無法識別:如果收不到PRI或者PRI不可識別,除了必須插入一個優先順序為13的PRI和我們在上面描述的TIMESTAMP,還必須插入一個 HOSTNAME。被接收到的資料包的全部內容將被認為是被傳遞的MSG的CONTENT並被新增在後面。一個不可識別的PRI的例子就是“< 00>”,這也許是一個資訊的前4個字元。如果接收到這樣的syslog資訊,那麼它的優先順序將被中繼器或收集者改為13,並且加入
TIMESTAMP。具體如下:
原來接收到的資訊
<00>...
被傳遞或識別的資訊
<13>TIMESTAMP HOSTNAME <00>...
如果中繼器新增一個TIMESTAMP(或者同時新增一個TIMESTAMP和HOSTNAME)在PRI後面, 那麼它將檢查這個資料包的總體長度是否等於或者小於1024個位元。
在UNIX檔案系統裡頭,syslog裝置依據兩個重要的檔案:syslogd(守護程式)和syslog.conf配置檔案。習慣上,多數syslog 資訊被寫到/var/adm或/var/log目錄下的資訊檔案中(syslog或messages.*)。一個典型的syslog紀錄包括生成程式的名 字和一個文字資訊。它還包括一個裝置和一個優先順序範圍(但不在日誌中出現)。Syslog.conf的格式比較複雜,大家可以參考一下有關書籍(或者在主
機上man syslog.conf),主要是如下語句形式: facility、level、action。Facility代表各種服務,level代表syslog的認證級別,action代表的是針對前面資訊 的處理動作。Action欄位如果是@loghos(主機名或具體IP),則把資訊傳送到loghost,而不是本地的 /var/adm/messages。
所以根據以上規則就可以實現,這裡給一個偷懶的可使用python程式碼
https://github.com/ucookie/anytools/blob/master/usyslog.py
簡單介紹下這個模組程式碼,主要分為三個部分:獲取日誌,處理日誌,傳送日誌。其中獲取日誌,是從/var/log/app目錄下定期獲取日誌,由於實際情況中,會出現日誌轉存到情況,如果只是單純的從一個檔案讀取,在這個過程中日誌被轉存了等情況,程式是不能知道的,會造成混亂。第二部分處理日誌可以選用(這裡是由於使用者需求不明確導致了這個模組產生,實際上是不必要的),第三部分是這一節想講的,使用的是UDP傳送,只要構造了正確規範的字串傳送,syslog日誌伺服器就能解析。
轉:https://www.cnblogs.com/newguy/p/6093290.html
相關文章
- 待機顯示服務協議及隱私政策協議
- ARP(地址解析協議)和RARP(逆地址解析協議)協議
- Linux-本地日誌服務管理(rsyslog基礎)Linux
- ARP 地址解析協議協議
- HTTP 協議完全解析HTTP協議
- CAP一致性協議及應用解析協議
- 真正“搞”懂HTTP協議11之代理服務HTTP協議
- 音視訊同步!RTCP 協議解析及程式碼實現TCP協議
- WebSocket的Frame協議解析Web協議
- 淺談WebSocket協議、WS協議和WSS協議原理及關係Web協議
- netty原始碼分析之服務端啟動全解析Netty原始碼服務端
- 超詳細 DNS 協議解析DNS協議
- 基於Netty實現自定義訊息通訊協議(協議設計及解析應用實戰)Netty協議
- ARP協議 地址解析協議:IP地址轉換為MAC地址協議Mac
- 認識流媒體協議,從 RTSP 協議解析開始!協議
- MQTT協議從服務端到客戶端詳解MQQT協議服務端客戶端
- 測試開發之網路篇-常用服務協議協議
- ipad協議及原始碼iPad協議原始碼
- 利用 NetBIOS 協議名稱解析及 WPAD 進行內網滲透iOS協議內網
- 螞蟻金服開源的 SOFAMesh 的通用協議擴充套件解析協議套件
- [服務端與網路]http協議與http狀態碼服務端HTTP協議
- Python使用socket的UDP協議實現FTP檔案服務PythonUDP協議FTP
- Protobuf協議逆向解析-APP爬蟲協議APP爬蟲
- 中科三方與上交所簽訂雲解析服務協議,科技翹楚助力金融巨頭協議
- rsyslog
- HTTP協議分析及攻防方法HTTP協議
- WEB基礎及HTTP協議WebHTTP協議
- Linux TCP/IP協議棧全過程LinuxTCP協議
- Automata Network用Rust編寫的去中心化的服務協議Rust中心化協議
- OpenVPN 協議解析-握手資料包分析協議
- ARP地址解析協議-個人總結協議
- 除錯備忘錄-SWD協議解析除錯協議
- Rsyslog配置
- dotnet core 開發無縫相容Http和Websocket協議的介面服務HTTPWeb協議
- TCP協議服務端和客戶端的連線與通訊TCP協議服務端客戶端
- 音訊和視訊流最佳選擇?SRT 協議解析及報文識別音訊協議
- 一個私有協議檔案DB 的解析.協議
- consul 原始碼解析(一)raft 協議實現原始碼Raft協議