Linux環境下使用rsyslog管理日志
在 Linux 系統中,日志文件記錄了系統中包括內核、服務和其它應用程序等在內的運行信息。在我們解決問題的時候,日志是非常有用的,它可以幫助我們快速的定位遇到的問題。
在 Cent OS 6中,日志是使用rsyslogd守護進程進行管理的,該進程是之前版本的系統中syslogd的升級版,對原有的日志系統進行了功能的擴展,提供了諸如過濾器,日志加密保護,各種配置選項,輸入輸出模塊,支持通過 TCP 或者 UDP 協議進行傳輸等。
rsyslog的配置文件為 /etc/rsyslog.conf , 大多數日志文件都位于 /var/log/ 目錄中。
定位日志文件
大多數日志文件都位于 /var/log/ 目錄中。在該目錄中,你可能注意到很多日志文件末尾包含一串數字(如 maillog-20150301 ),這說明這些日志文件經過了日志轉儲,這樣可以避免日志文件過大。
在軟件包logrotate中包含了一個定時任務,根據/etc/logrotate.conf文件和/etc/logrotate.d/目錄中的的配置定期的轉儲日志文件。
Rsyslog基本配置
Rsyslog 的主要配置文件為 /etc/rsyslog.conf 文件,在配置文件中,我們通過配置 filter 以及 action 對日志進行管理。
在rsyslog配置文件中,使用如下格式定義規則
filter action
rsyslog發現符合 filter 規則的日志后,會將日志發送到 action 指定的動作進行處理。
Filter
在rsyslog中,提供了三種方式的過濾器方法:
基于設施/優先級的過濾器 (Facility/Priority-based filters)
基于設施/優先級的過濾器是最常用的方法,語法如下:
FACILITY.PRIORITY
FACILITY指定了產生日志消息的子系統,可選值為 auth , authpriv , cron , daemon , kern , lpr , mail , news , syslog , user , ftp , uucp , local0 ~ local7 。
PRIORITY指定了日志消息的優先級,可用的優先級包含 debug (7) , info (6) , notice (5) , warning (4) , err (3) , crit (2) , alert (1) , emerg (0) 。
前置符號=表明只有該優先級的消息會被捕獲,!表明除了該優先級的消息之外的優先級會被捕獲。除了前置符號外,可以使用符號*
表示所有的設施或者優先級,對優先級部分使用none關鍵字會捕獲所有沒有指定優先級的消息。
定義多個設施或者優先級使用,分隔,如果是多個 filter 的話,則使用;進行分隔。
使用范例
kern.* # 選擇所有優先級的內核日志 mail.crit # 選擇所有mail 的優先級高于crit的日志 cron.!info,!debug # 選擇除了 info 和 debug 優先級的 cron 日志
基于屬性的過濾器
基于屬性的過濾器語法
:PROPERTY, [!]COMPARE_OPERATION, "STRING"
:PROPERTY是要比較的日志屬性,COMPARE_OPERATION為要執行的比較操作,這個的!表示取反的意思,"STRING"為比較的值。
可以使用的比較操作:
比較操作 | 描述 |
---|---|
contains | 匹配提供的字符串值是否是屬性的一部分,如果不區分大小寫,使用contains_i |
isequal | 比較屬性和值是否相等 |
startswith | 屬性是否以指定字符串開始(startswith_i) |
regex | 正則表達式(POSIX BRE 基本正則)匹配 |
ereregex | 正則表達式(POSIX ERE 擴展正則)匹配 |
isempty | 判斷屬性是否為空,不需要 value |
使用范例:
:msg, contains, "error" :hostname, isequal, "host1" :msg, !regex, "fatal .* error"
基于表達式的過濾器
基于表達式的過濾器使用了rsyslog自定義的腳本語言 RainerScript 構建復雜的filter,這里暫時不對這種方法進行講述。
Action
Action定義了當匹配指定的 filter 的時候,執行什么操作。
如果要指定多個 ACTION, 使用&連接多個 ACTION。
例如:
kern.=crit user1 & ^test-program;temp & @192.168.0.1
這里的;temp指定了傳遞日志給 test-program 程序時( ^ 開頭表明日志發送給該可執行文件),使用它 temp 模板格式化日志。
在 ACTION 后面追加;模板名稱可以為指定的 action 使用該模板格式化日志。
保存日志到日志文件
語法:
FILTER PATH
這里的 PATH 指定了日志要保存到的文件。例如cron.* /var/log/cron.log指定了所有的定時任務日志都寫入到/var/log/cron.log文件。
默認情況下,每次生成 syslog 的時候,日志信息會同步到日志文件。可以在文件路徑前使用 - 指定忽略同步(如果系統崩潰,會丟失日志,但是這樣可以提高日志性能)。
除了上述方法記錄日志(靜態),也可以動態的生成日志文件。
FILTER ?DynamicFile
這里的DynamicFile是預定義的輸出路徑模板。
通過網絡發送syslog
rsyslog可以使用網絡將日志消息發送或者接受日志,使用這個特性,可以實現使用單一的日志服務器統一管理多臺服務器日志。
@[(zNUMBER)]HOST:[PORT]
這里的@告訴syslog使用 UDP 協議發送日志,要使用 TCP 的話,使用@@。可選值zNUMBER設置了是否允許使用zlib對日志壓縮(壓縮級別1-9)。
使用范例
*.* @192.168.0.1 # 使用 UDP 發送,默認端口514 *.* @@example.com:18 # 使用 TCP 發送到端口18, 默認10514 *.* @(z9)[2001:db8::1] # UDP, ipv6,使用zlib級別9壓縮
丟棄日志
要丟棄日志消息,使用~動作。
FILTER ~
例如:
cron.* ~
模板
任何rsyslog生成的日志都可以根據需要使用模板進行格式化,要創建模板,使用如下指令
$template TEMPLATE_NAME,"text %PROPERTY% more text", [OPTION]
這里的$template指令表明了接下來的內容定義了一個模板,TEMPLATE_NAME是模板的名稱,接下來雙引號之間的內容為模板的內容。
這里還有一個 OPTION , 它指定了模板的功能,支持選項為sql和stdsql,在使用數據庫存儲的時候會用到。
生成動態文件名
模板可以用來生成動態文件名,就如之前所述,在使用動態文件名的時候,需要在 ACTION 中的模板名稱前增加?表明該文件名是動態生成的。
例如:
$template DynamicFile,"/var/log/test_logs/%timegenerated%-test.log" *.* ?DynamicFile
timegenerated屬性從日志信息中提取出消息的時間戳,這樣可以為每個日志生成唯一文件名稱。
屬性
在模板中使用的屬性是在%之間的內容,使用屬性可以訪問日志消息中的內容。
%PROPERTY_NAME[:FROM_CHAR:TO_CHAR:OPTION]%
可用的屬性列表見man rsyslog.conf。
全局指令
全局指令是rsyslogd守護進程的配置指令。所有的全局指令必須以$開始,每行只能有一個指令,例如:
$MainMsgQueueSize 50000
在新的配置格式中(rsyslog v6),已經不在使用這種方式的指令,但是它們仍然是可用的。
隊列
在 rsyslog 中,隊列用來傳輸數據,當 rsyslog 接收到一個消息的時候,首先傳遞消息預處理器,然后加入到主消息隊列,接下來消息會從隊列中取出傳遞給規則處理器。
規則處理器是一個解析過濾引擎,它會基于配置文件中定義的規則,執行相應的動作(action),每一個動作都有自己的動作隊列,消息通過這個隊列發送到對應的動作處理器,然后輸出。
對于同一個消息來說,可以同時傳遞這個消息給多個動作隊列。
定義隊列
在配置文件/etc/rsyslog.conf文件中
$objectQueueType queue_type
這里的隊列類型可選值為 direct , linkedlist , fixedarray (內存隊列), 或者 disk 。
默認情況下,對于主隊列,使用的是FixedArray隊列(10000個消息長度),動作隊列采用的是direct 隊列。
PHP 使用 syslog 輸出日志
在PHP 中,調用系統日志系統的函數有三個
bool openlog ( string $ident , int $option , int $facility ) bool syslog ( int $priority , string $message ) bool closelog ( void )
函數openlog用于打開到系統日志系統的連接,第一個參數$ident是一個字符串,syslog 會將該字符串自動加到使用syslog函數輸出的所有日志消息的前面。第二個參數是日志選項,第三個參數是記錄日志的設施。
函數openlog()和closelog()是可選的。
例如,我們在/etc/rsyslog.conf配置文件中增加如下配置
local5.* /tmp/php_test.log
增加后需要重啟 rsyslog 進程(sudo /etc/init.d/rsyslog restart)
在 PHP 腳本中,執行如下操作
<?php openlog("LogHeader", LOG_PID, LOG_LOCAL5); syslog(LOG_DEBUG, "Hello, Logger");
執行上述腳本,我們可以在/tmp目錄中看到出現名為php_test.log的文件
Mar 10 14:47:04 vm-hp LogHeader[8261]: Hello, Logger
第一部分Mar 10 14:47:04為日志時間,第二部分vm-hp為主機的 HOSTNAME , 我們在 調用openlog函數的時候,指定了indent為LogHeader, 同時在日志中加入進程的 PID(LOG_PID)。
上述日志消息,如果要使用模板的話,是下面這樣的
$template LOG_TMP,"%timegenerated% %HOSTNAME% %msg%" local5.* /tmp/php_test.log;LOG_TMP
我們將所有支持的模板屬性變量輸出如下
msg: Hello, Logger, rawmsg: <175>Mar 10 15:52:49 LogHeader[13845]: Hello, Logger, HOSTNAME: vm-28-234-pro01-hp, FROMHOST: vm-28-234-pro01-hp, syslogtag: LogHeader[13845]:, programname: LogHeader, PRI: 175, PRI-text: local5.debug, IUT: 1, syslogfacility: 21, syslogfacility-text: local5, syslogseverity: 7, syslogseverity-text: debug, timereported: Mar 10 15:52:49, TIMESTAMP: Mar 10 15:52:49, timegenerated: Mar 10 15:52:49, PROTOCOL-VERSION: 0, STRUCTURED-DATA: -, APP-NAME: LogHeader, PROCID: 13845, MSGID: -
參考: Red Hat Enterprise linux 6 Deployment Guide: Chapter 23. Viewing and Managing Log Files