一、Rsyslog整體架構

Rsyslog消息流:輸入模塊——>預處理模塊——>主隊列——>過濾模塊——>執行隊列——>輸出模塊
1. 輸入模塊
輸入模塊是消息來源

2. 預處理模塊
主要解決各種syslog協議實現間的差異
3. 隊列模塊
負責消息的存儲,從Input傳入的未經過濾的消息放在主隊列,過濾后的消息放入到不同的action queue中,再由執行隊列送到各個輸出模塊
4. 過濾模塊
Filter模塊處理消息的分析和過濾,rsyslog可以對消息的任何部分進行過濾

5. 輸出模塊
消息的目的地

6. rsyslog命令的參數

7. 其他概念
基本結構:數據流動過程中內置的基本處理框架,但是對於消息流,是可以高度定制化的。定制工作是通過自定義rsyslog對象來完成的。
消息流和對象概覽:消息通過input模塊進入rsyslog,接着到ruleset,進行規則匹配,也就是做一些處理,比如寫到文件,數據庫或者繼續轉發到遠程主機。
處理原則:每個ruleset會包含>=0個規則,一條規則包含一個過濾器和一個動作列表,一個動作列表會包含一個或多個動作
過濾器:控制流量,動作列表不會再出現過濾器
處理順序:rsyslog.conf中得命令是從上到下一次執行的,所以,如果你停止了對某消息的處理,那么這行之后的命令就不會再被檢查和執行了
流程控制語句:
if expr then ... else ...- 條件語句 stop - 停止處理當前消息 call - 調用一個rulese(類似子程序調用) continue - 一個空操作(NOP),很有用。比如在if語句的then部分
流控制也可以通過過濾器條件來實現
數據操作語言:
set - 設置一個用戶變量 unset - 刪除之前設置的用戶變量
二、Rsyslog的作用
- 接收來自多種源的輸入
- 傳輸接收的內容
- 輸出到不同類型的目的端
三、Rsyslog的特征
- 多線程
- TCP/SSL/TLS/RELP
- MySQL/PostgreSQL/Oracle等
- 對syslog日志的任何部分進行篩選和過濾
- 完全可控的輸出格式
- 適合企業級的日志系統
四、 rsyslog配置相關概念
1. 屬性替代
Rsyslog 預定義了一些屬性,來代表消息中的信息,我們可以在定義輸出格式、動態文件名的時候使用到這些屬性。這里面比較重要的屬性比如:msg(消息體)、hostname、pri(消息等級和類別)、time(時間有關),屬性的名稱中以$開頭的是從本地系統獲得的變量、不帶$是從消息中獲得變量。
屬性替代的語法格式:
%propname:fromChar:toChar:options:fieldname%
屬性替換的功能很強大,你可以使用起始字符獲取自己所需的字段,也可以使用正則表達式,也可以使用分隔符。舉幾個例子:為了兼容一個rfc協議,rsyslog規定如果用戶輸入的msg不是以空格開頭,rsyslog會自動補充一個空格,因此如果你希望輸出的時候去掉這個空格,就可以使用,舉例:
%msg:2:$% #選取msg變量中,起始位置為2,終止位置為結尾
我們經常需要根據空格來分析字符串,F表示使用字符分割,32是空格的ascii碼,例:
%msg:F,32:3% #按照空格分隔,取第三個子串
正則匹配可以匹配特定的文字和格式,屬性替代中還用到了一類特殊的以$!開頭的變量,這是使用mmnormalize模塊時特有的,可以實現類似於syslog-ng中parser模塊的功能。
2. 模板(詳細使用見Rsyslog模板文章)
功能:
(1)定義輸出的格式
(2)定義omfile模塊的動態路徑、動態文件。需要用到屬性替換
形式:
(1)一般簡單格式,可以使用string的形式
(2)復雜的格式,可使用list形式
(3)子樹(subtree)
(4)插件(plugin)
3. Ruleset(規則集)
(1)實現多實例功能
(2)針對syslog的來源使用不同的過濾規則
(3)需要在配置文件中先定義ruleset,才可以使用
舉例:針對不同端口使用不同的過濾規則
#定義規則:以local3開頭的所有日志發送到10.0.0.44的1999端口,以local4開頭的日志發送到10.0.0.44的2000端口 $Ruleset tcp1999 $RulesetCreateMainQueue on Local3.* @@10.0.0.44:1999 #定義規則2 類似於上 $Ruleset tcp2000 $RulesetCreateMainQueue on Local4.* @@10.0.0.44:2000
4. Filter模塊
rsyslog可使用rsyslog標准的過濾規則,同時自己添加了一些擴展。比如在輸出中指定rsyslog自己的處理方式,可以指定輸出模板(template)
使用方法:在規則(ruleset)后面添加模板的名字,用分號隔開
舉例:
#第一種方式:將local3.*的日志保存到所指目錄中,輸出處理使用t_msg模塊 Local3.* -/data0/logs/local3.log;t_msg #?問號表示使用模板定義的動態路徑 Local4.* -?f_local3_test;t_msg #第二種方式 #除了syslog標准的規則,rsyslog的作者還自己開發了一個叫做rainerscript的腳本語言,來定義更復雜的過濾規則,rainerscript可以對 #屬性進行startwith、contains、%(取余)等過濾規則 if $pri-txt == local3.* and $msg contains "abc" then { *.* -/data0/logs/local3.log;t_msg } #這個例子表示如果pri是local3,且在消息中包含子串‘abc’ #第三種方式:使用屬性的表示方式 :msg, regex, "^ [g-z]" /root/rsyslog_worker_dir/2000.log #以字母g到z開頭的消息,注意msg開頭有空格
5. 隊列
隊列的種類:主隊列和工作隊列。從輸入模塊進入主隊列;主隊列的消息,經過過濾模塊,進入到相應的工作隊列隊列的四種工作模式。
隊列的四種工作模式:

此外,內存隊列還可以通過指定一個queuename來添加DA模式,DA模式主要是為了防止意外情況(進程關閉,server端宕機)下,內存隊列可以不丟失。
關於隊列的配置:
因為 MainMsgQueue 和 ActionQueue 的配置基本一樣(除了有些默認值可能不同), 所以這里以MainMsgQueue 為例:
$MainMsgQueueType [FixedArray/LinkedList/Direct/Disk] $MainMsgQueueFileName <name> #針對disk queue的配置,定義隊列名,存儲隊列數據時用的文件名就是這個名稱 MainMsgQueueCheckpointInterval <number> #針對disk queue的配置,單位條數,設置在檢查點寫入相關信息,增加可靠性,但是會降低性能 $MainMsgQueueDequeueBatchSize <number> [default 32] #設置多少條隊列作為一個batch一起出隊,針對一個日志量很大的系統,可以考慮把這個值調高來增加性能,不過要結合可使用內存考慮實際情況
對於DA隊列,最有特點就是隊列閾值的設置了。主要包括這幾個配置:
$MainMsgQueueSize #設置隊列的最大大小 $MainMsgQueueDiscardMark <number> [default 9750] #配合下面的 $MainMsgQueueDiscardSeverity,超過這個watermark后,不重要的日志都會丟棄,包括新進來和已經在隊列里的 $MainMsgQueueDiscardSeverity <severity> [default 4 (warning)] 0-Emergency, 1-Alert, 2-Critical, 3-Error, 4-Warning, 5-Notice, 6-Informational, 7-Debug $MainMsgQueueHighWaterMark <number> [default 8000] #設置 high watermark $MainMsgQueueLowWaterMark <number> [default 2000] #設置 low watermark $MainMsgQueueMaxFileSize <size_nbr> [default 1m] #針對disk情況下,單個文件的最大大小 $MainMsgQueueMaxDiskSpace #控制占用硬盤總空間大小
DA 對於閾值處理的邏輯比較有意思,並不是單純的內存滿了就開始使用硬盤。首先,有 low watermark 和 high watermark 這兩個概念。
如果隊列大小達到 high watermark,隊列開始寫數據到disk 如果隊列大小降到 low watermark,停止寫入disk(直到再次達到 high watermark); 或者 disk queue 隊列為空(即da隊列里的數據處理完),這兩種情況都會進入in-memory 模式
關於終止隊列的一些處理配置:
$MainMsgQueueTimeoutEnqueue [number is timeout in ms (1000ms is 1sec!), default 2000, 0 means indefinite] #當隊列或硬盤滿了,在這個超時時間后新來的日志,設置0可以直接丟棄掉 $MainMsgQueueTimeoutShutdown <number> [number is timeout in ms (1000ms is 1sec!), default 0 (indefinite)] #當隊列關閉時,還有數據在進入隊列,rsyslog會盡可能在這個timeout周期內處理掉這些數據 $MainMsgQueueTimeoutActionCompletion <number> [number is timeout in ms (1000ms is 1sec!), default 1000, 0 means immediate!] #配置需要多久來處理完當前的數據 $MainMsgQueueSaveOnShutdown [**on**/off] #針對disk queue的配置,當運行中的隊列關閉時,會先把隊列中的數據存在硬盤中 $MainMsgQueueDequeueSlowdown <number> [number is timeout in microseconds (1000000us is 1sec!), default 0 (no delay). Simple rate-limiting!] # 簡單的出隊速度限制,單位微秒 $MainMsgQueueImmediateShutdown [on/off] #棄用的選項,當配置的隊列大小或硬盤空間滿了以后,rsyslogd 會限制數據submitter。配置 $MainMsgQueueTimeoutEnqueue 后,當超過這個時間后新來的日志會被丟棄;設置0為直接丟棄。 #$MainMsgQueueTimeoutShutdown、$MainMsgQueueTimeoutActionCompletion 和 $MainMsgQueueSaveOnShutdown 是在隊列終止后可以做的一系列措施。
關於隊列的worker thread:
$MainMsgQueueWorkerThreadMinumumMessages <number> [default 100] $MainMsgQueueWorkerThreads <number> [num worker threads, default 1, recommended 1] $MainMsgQueueWorkerTimeoutThreadShutdown <number> [number is timeout in ms (1000ms is 1sec!), default 60000 (1 minute)]
每個隊列(direct queue除外)都有一個工作線程池(worker thread pool). 初始時,是沒有worker thread的,當有消息來是,會自動啟動一個. “$MainMsgQueueWorkerThreadMinumumMessages” 配置一個worker thread處理的消息大小, $MainMsgQueueWorkerThreads 配置work thread的上限值。
比如設置一個worker thread的最小處理消息大小是100個,當小於100個是,只有一個worker,當超過100個,小於200個時,會有兩個worker...
以上配置要注意單位, 默認值,Main Queue 和 Action Queue 可能有些配置的默認值不一樣。
另外所有指明針對disk的配置,都是包括 disk queue 和 DA queue.
更多配置參考這里:
在一般情況下,大部分的配置都可以直接使用默認的配置,這里給出一份Action使用DA隊列的配置:
# 這兩個是全局的 $ActionResumeRetryCount 3 $ActionResumeInterval 10 # 以下是每個ActionQueue自己的配置 $ActionQueueType LinkedList $ActionQueueFileName da_queue $ActionQueueMaxFileSize 100M # 設置單個disk文件的大小 $ActionQueueMaxDiskSpace 10G # 設置最大占用空間 $ActionQueueDisacdSeverity 3 # 設置忽略的等級 $ActionQueueLowWaterMark 5000 # 默認是2000 $ActionQueueHighWatermark 15000 # 默認是8000 $ActionQueueDiscardMark 30000 # 默認是9750 $ActionQueueSize 80000 # 文檔沒寫,測試發現默認是1000 $ActionQueueSaveOnShutdown on *.* @log-center.xxx.com:514 Main Queue 的默認模式是 FixedArray,Action Queue 的默認模式是 Direct
五、實例
1. TCP+DA模式實現可靠消息傳輸
tcp協議的不可靠性,比如server端宕機等情況,需要在client端配置一個本地文件,用在server端宕機的情況下,暫時保存消息。需要注意的是。隊列名和過濾規則對應,一個隊列只能用於一個過濾規則
舉例:
$ActionQueueType LinkedList $ActionQueueFileName local3 $ActionResumeRetryCount -1 $ActionQueueSaveOnShutdown on Local3.* @@10.0.0.44:1999 $ActionQueueType LinkedList $ActionQueueFileName local4 $ActionResumeRetryCount -1 $ActionQueueSaveOnShutdown on Local4.* @@10.0.0.44:1999
上例中可將兩條過濾規則合成一條:local3.*;local4.*
強調一點:本地隊列只有在需要使用的時候才會創建,當后端出現短暫不可用時,rsyslog的內存隊列就可以保存消息,內存隊列不夠用時,才會創建本地隊列。
