Linux日志機(jī)制的核心是rsyslog守護(hù)進(jìn)程,該服務(wù)負(fù)責(zé)監(jiān)聽Linux下的日志信息棋恼,并把日志信息追加到對應(yīng)的日志文件中,一般在/var/log目錄下。它還可以把日志信息通過網(wǎng)絡(luò)協(xié)議發(fā)送到另一臺Linux服務(wù)器上邦邦,或者將日志存儲在MySQL或Oracle等數(shù)據(jù)庫中。目前rsyslog的大版本為v8醉蚁。
配置文件
一般情況下燃辖,rsyslog 配置的文件文件位于/etc/rsyslog.conf 以及 /etc/rsyslog.d/文件夾下,在/etc/rsyslog.conf中通過$IncludeConfig
指令將/etc/rsyslog.d/的所有配置合并到一起网棍。配置主要可以分為以下幾類:
全局配置
加載一些通用的模塊
module(load="imuxsock") # provides support for local system logging
module(load="imklog") # provides kernel logging support
設(shè)置默認(rèn)的日志格式:
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
一些權(quán)限相關(guān)黔龟,在后面的一些配置中需要特別注意:
$FileOwner syslog
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
$Umask 0022
$PrivDropToUser syslog
$PrivDropToGroup syslog
規(guī)則
每條規(guī)則都由選擇器和相應(yīng)的動作組成,選擇器說明來源和日志級別滥玷,而動作則說明如何處理對應(yīng)的日志,下面是一些例子:
cron.* /var/log/cron
mail.warn /var/log/mail.warn
把所有來自cron守護(hù)進(jìn)程的消息保存到/var/log/cron文件中氏身。 當(dāng)指定日志級別時,所有等于或大于該日志等級的信息都要被處理惑畴。比如在下面的例子中蛋欣,mail子系統(tǒng)所有warning及以上信息的日志都保存在/var/log/mail.warn文件中。
mail.=info -/var/log/mail.info
使用=可以指定日志等級如贷,加上 -
表明日志異步寫入陷虎。
mail.!info /var/log/mail.info
使用!可以排除這類信息到踏。
自定義channel
除了將日志寫入本地文件外,rsyslog還支持自定義的規(guī)則尚猿,下面的指令就定義了一個名稱為NAME的channel:
$outchannel NAME, FILE_NAME, MAX_SIZE, ACTION
下面是一個例子注意omfile指明輸出到文件窝稿。
$outchannel log_rotation, /var/log/test_log.log, 104857600, /home/millions/log_rotation_script
*.* :omfile:$log_rotation
實(shí)際用例
如果rsyslog只能做將日志寫入本地文件那就有點(diǎn)沒意思了,下面我們來看一下rsyslog的一些高級一點(diǎn)的功能谊路。
收集nginx的access log 寫入文件中
從nginx的access log中可以分析出很多東西讹躯,但是在分布式環(huán)境下nginx通常部署在多個不同的服務(wù)器下,使用rsyslog可以將這些日志整合起來缠劝。
我們在/etc/rsyslog.d/文件夾下新建一個配置文件access_log.conf:
module(load="imfile")
ruleset(name="remote") {
action(type="omfwd"
Protocol="tcp"
Target="127.0.0.1"
Port="8899")
stop
}
input(type="imfile"
File="/var/log/nginx/access.log"
Facility="user"
Severity="info"
Tag="web_access"
PersistStateInterval="1"
Ruleset="remote")
由于要讀取文件潮梯,我們引入module(load="imfile")
。然后在input中指明輸入的文件位置惨恭,以及日志的類型和級別秉馏。PersistStateInterval
表示持久化的間隔,可以根據(jù)需要調(diào)整脱羡,Ruleset表示使用的規(guī)則是什么萝究。在規(guī)則中,我們指明了輸出類型為轉(zhuǎn)發(fā)锉罐,目標(biāo)是127.0.0.1的8899端口帆竹,并且使用tcp協(xié)議。
接下來脓规,我們再增加一個接受轉(zhuǎn)發(fā)日志的配置:
module(load="imtcp")
template(name="msg" type="string" string="%msg:2:$%\n")
ruleset(name="analysis") {
action(type="omfile"
File="/home/millions/log/access.log"
Template="msg")
stop
}
input(type="imtcp"
Port="8899"
Ruleset="analysis")
這里我們的input是tcp栽连,并且監(jiān)聽在8899端口上,輸出到指定的文件侨舆,并使用自定義的模板msg
秒紧。這里要注意權(quán)限問題。
然后去訪問nginx挨下,就可以看到指定目錄下的文件了熔恢。
收集nginx日志并重定向到程序
稍微修改以下我們接收日志的配置,就可以把日志重定向給某個程序的標(biāo)準(zhǔn)輸入了:
module(load="imtcp")
module(load="omprog")
template(name="msg" type="string" string="%msg:2:$%\n")
ruleset(name="analysis") {
action(type="omprog"
Binary="/usr/bin/php /home/millions/log/test.php"
Template="msg")
stop
}
input(type="imtcp"
Port="8899"
Ruleset="analysis")
為了方便起見臭笆,我們這里采用php腳本叙淌,也可以換成其他想使用的語言,test.php的內(nèi)容如下愁铺。
$fp = fopen("/home/millions/log/f.log", "w+");
while (($data = fgets(STDIN)) !== false) {
fwrite($fp, "got data:" . $data);
}
這樣就可以看到f.log中記錄的數(shù)據(jù)了:
got data:192.168.0.102 - - [08/Jan/2017:11:58:00 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"
got data:192.168.0.102 - - [08/Jan/2017:13:20:34 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"
如果kill掉test.php凿菩,下次同步日志時rsyslog還會啟動一個新的test.php,這樣可以在運(yùn)行一定次數(shù)后退出進(jìn)程防止內(nèi)存泄露帜讲。
總結(jié)
上面只是對rsyslog的使用做了一個簡單的介紹衅谷,具體使用還有很大的發(fā)揮空間。比如在腳本中不是簡單的把日志寫入本地文件似将,而是發(fā)往kafka获黔,記錄到mysql蚀苛,mongodb中去。進(jìn)一步的學(xué)習(xí)還是需要查看rsyslog的官方文檔玷氏。