詳解rsyslog/Python/LogAnalyzer 記錄和檢視服務端/客戶端日誌
RSYSLOG 是一個高效的日誌系統,也是目前 Ubuntu 和 CentOS 預設使用的日誌系統。
LogAnalyzer 是一個 PHP 寫成的 Web 前端,使用它可以分析和檢視 RSYSLOG 生成的日誌。
經過研究,我準備直接使用這兩個系統。本文記錄了我在配置這兩個系統中遇到的問題。
rsyslog 配置簡介
rsyslog 是負責收集 syslog 的程式,可以用來取代 syslogd 或 syslog-ng。 在這些 syslog 處理程式中,個人認為 rsyslog 是功能最為強大的。其特性包括: 支援輸出日誌到各種資料庫,如 MySQL,PostgreSQL,MongoDB,ElasticSearch,等等;
通過 RELP + TCP 實現資料的可靠傳輸(基於此結合豐富的過濾條件可以建立一種 可靠的資料傳輸通道供其他應用來使用);精細的輸出格式控制以及對訊息的強大 過濾能力;高精度時間戳;佇列操作(記憶體,磁碟以及混合模式等); 支援資料的加密和壓縮傳輸等。
syslog 的相關 RFC 參考 RFC3164, RFC5424, RFC5425, RFC5426。
本文僅覆蓋 rsyslog 的相關配置,其中配置指令的正確性以 官方文件為準, Wiki 作為參考。
配置檔案 /etc/rsyslog.conf
配置文件官方文件請參考這裡。http://www.rsyslog.com/doc/rsyslog_conf.html
rsyslog 的配置檔案一般為 /etc/rsyslog.conf。模組相關的配置指定指定和功能僅在 相應的模組被載入($ModLoad)後才可用。配置行如果太長,可以在行尾使用 “\” 分割成多行。註釋支援兩種語法,一種以 # 開始到行尾,另一種為 C 語言格式。
指令的處理順序為檔案內容從始到末。
使用命令 rsyslogd -f /etc/rsyslog.conf -N1 測試配置檔案檢查。
# rsyslogd -f /etc/rsyslog.conf -N1
rsyslogd: version 7.4.4, config validation run (level 1), master config /etc/rsyslog.conf
rsyslogd: warning: ~ action is deprecated, consider using the 'stop' statement instead [try http://www.rsyslog.com/e/2307 ]
rsyslogd: immark: mark message period must not be 0, can not run
rsyslogd: End of config validation run. Bye.
日誌的傳送測試可以使用 logger 命令,該命令支援通過 UNIX Socket,UDP/TCP 等 傳送 syslog。
下面僅對常用的配置指令 做一些說明,並主要以 legacy rsyslog 的格式來描述。官方文件目前大部分是以 RainerScript 的格式描述。 部分配置指令放在單獨的章節裡說明。
$ActionFileDefaultTemplate [templateName] # 定義檔案動作的日誌輸出模板
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
Dec 30 17:16:58 linux-64 logger[16898]: test syslog
$ActionFileDefaultTemplate RSYSLOG_FileFormat
2013-12-30T17:19:50.926770+08:00 linux-64 logger[7757]: test syslog
$ActionForwardDefaultTemplate [templateName] # 定義預設轉發動作的日誌輸出模板
$ActionExecOnlyWhenPreviousIsSuspended [on/off] # 值為 on 時表示接下來的 動作僅在之前的動作被掛起(失敗)時才執行。
檔案系統相關配置
$DirCreateMode,$DirGroup, $DirOwner # 設定目錄建立模式,屬主和組
$FileCreateMode,$FileGroup,$FileOwner # 設定檔案建立模式,屬主和組
$Umask 0062 # 設定檔案建立掩碼,等價於 man 1 umask
$DynaFileCacheSize # 控制動態檔案保持開啟的個數,針對每個動作
$IncludeConfig # 匯入其他檔案到配置,等價於 C 中的 #include
$MainMsgQueueSize # 主訊息佇列大小
$MaxMessageSize # 日誌最大大小,太大的值需要考慮傳輸協議,如 UDP
$ModLoad xxx # 模組載入
重複訊息控制
$RepeatedMsgReduction on
$RepeatedMsgContainsOrigionalMsg on
日誌接收率控制
Interval 設定率計算的時間間隔,0 表示關閉;Burst 設定該間隔內允許的日誌數。 IMUXSock 針對通過 system log socket 接收的日誌;SystemLog 針對其他輸入源。
$SystemLogRateLimitInterval 0
$SystemLogRateLimitBurst 0
$IMUXSockRateLimitInterval 0
$IMUXSockRateLimitBurst 0
Dec 31 22:02:36 linux-64 rsyslogd-2039: imuxsock begins to drop messages from pid 6927 due to rate-limiting
Dec 31 22:02:39 linux-64 rsyslogd-2039: imuxsock lost 133250 messages from pid 6927 due to rate-limiting
模組
完整的模組列表在這裡。 http://www.rsyslog.com/doc/v8-stable/configuration/modules/index.html
下面僅對常用的各類別模組做簡單的介紹。
輸入模組(im 字首)
imfile - 轉換文字檔案為日誌
imrelp - 通過 RELP 可靠的接收日誌。
$ModLoad imrelp # 載入模組
$InputRELPServerRun 514 # 在 514 埠監聽
imudp - 通過 UDP 接收日誌
$ModLoad imudp
$UDPServerRun 514
imtcp - 通過 TCP 接收日誌
$ModLoad imtcp
$InputTCPMaxSessions 500
$InputTCPServerRun 514
imptcp - 同 imtcp,但針對 Linux 做高效能定製
$ModLoad imptcp
$InputPTCPServerRun 514
immark - 週期性輸出標記資訊
設定為60,每分鐘產生一個 mark 日誌
$MarkMessagePeriod 60
imklog - 獲取核心日誌(通過 dmesg 也能看到相關資訊)
imuxsock - UNIX socket
預設情況下從 /dev/log 獲取日誌。
# netstat -nxp|grep /dev/log
unix 3 [ ] DGRAM 7439519 9074/rsyslogd /dev/log
$ModLoad imuxsock # needs to be done just once
$SystemLogRateLimitInterval 0 # turn off rate limiting
$InputUnixListenSocketCreatePath on # turn on for next socket
$InputUnixListenSocket /var/run/sshd/dev/log
$InputUnixListenSocketHostName jail1.example.net
$AddUnixListenSocket /jail/1/dev/log
$InputUnixListenSocketHostName jail2.example.net
$AddUnixListenSocket /jail/2/dev/log
impstats - rsyslog 內部資料週期統計
輸出模組(om 字首)
omfile - 輸出到檔案
支援靜態檔案;通過模板支援動態檔案;
omfwd - 內建模組,轉發
*.* @192.168.2.11:10514
*.* @@192.168.2.11:10514
omsnmp - SNMP trap 輸出
$ModLoad omsnmp
$actionsnmptransport udp
$actionsnmptarget localhost
$actionsnmptargetport 162
$actionsnmpversion 1
$actionsnmpcommunity public
*.* :omsnmp:
omrelp - RELP output module
$ModLoad omrelp
*.* :omrelp:loghost.example.com:20514
omusrmsg - 內建模組,傳送日誌到指定使用者
# Emergencies are sent to everybody logged in.
*.emerg :omusrmsg:*
omprog - 傳送日誌給程式處理
為方便程式解析,日誌的輸出最好採用 json 格式輸出。
$ModLoad omprog
$ActionOMProgBinary /home/app/rtdatamq/save_log_data.py
:programname,startswith,"log4report" :omprog:;RSYSLOG_TraditionalFileFormat
ommail - 傳送郵件
輸出到資料庫等
ommysql - MySQL
ompgsql - PostgreSQL
ommongodb - MongoDB
omlibdbi - 通用資料庫模組
omhdfs - Hadoop's HDFS
omelasticsearch - ElasticSearch
其他模組
訊息過濾(fm 字首),訊息解析(pm 字首),字串生成(sm 字首),庫模組,等。
規則
規則由過濾器和動作組成。
過濾器
基於設施/優先順序的過濾器
格式如下:
<FACILITY>.<PRIORITY>
其中:
表示生成日誌的子系統。取值範圍為 auth,authpriv,cron, daemon,kern,lpr,mail,news,syslog,user,uucp,local0 到 local7, 參考 man 3 syslog。其對應的數值請參考 /usr/include/sys/syslog.h, 注意需要忽略移位操作。
表示日誌的級別,取值範圍為(從低到高,數值對應 7-0) debug,info,notice,warning,err,crit,alert,emerg。 參考 man 3 syslog。
在級別前可以增加相應的修飾符,例如加 = 表示僅選擇該優先順序的日誌,加 ! 表示選擇不等於優先順序的所有日誌,不加任何符號則表示選擇該優先順序及之上的日誌。 * 可以用來表示所有的日誌子系統和/或訊息級別。關鍵字 none 表示未指定級別的日誌。如果要定義多個設定/優先順序,使用 , 分隔即可。 如果要定義多個過濾條件,則使用 ; 分隔。
示例如下:
kern.* # 選擇所有級別的核心日誌
mail.crit # 選擇所有級別為 crit 及之上的郵件系統相關日誌
cron.!info,!debug # 選擇所有 cron 日誌資訊,排除優先順序為 info 和 debug 的日誌
*.=debug # 選擇所有的除錯級別日誌
*.*;auth,authpriv.none # 選擇所有級別的日誌,以及認證相關無級別的日誌
基於屬性的過濾器
格式如下:
:<PROPERTY>, [!]<COMPARE_OPERATION>, "<STRING>"
其中 ! 表示對匹配結果取反。
該過濾器可以對所有日誌的屬性進行過濾(相對傳統的 syslog 程式而言),例如: timegenerated 或者 syslogtag,所有的屬性列表如下,完整的列表可以參考 這裡的 Available Properties 節。部分屬性如下:
屬性名 說明
msg 日誌正文
hostname 日誌中的主機名
fromhost 從該主機接收到的訊息,可能不是最開始的傳送主機
fromhost-ip fromhost 的 IP
syslogtag 日誌標籤,如 named[12345]
programname 日誌標籤的靜態部分,如 named
pri 日誌的 PRI 部分
pri-text PRI 的文字表示,如 syslog.info
syslogfacility 日誌類別
syslogfacility-text 日誌類別的文字表示
syslogseverity 日誌級別
syslogseverity-text 日誌級別的文字表示
timegenerated 日誌接收時間,或理解為 timereceived
timereported 日誌內的報告時間,或生成時間
$now 當前時間,YYYY-MM-DD
$year 當前年,YYYY
$month 當前月,MM
$day 當前日誌,DD
$hour 當前小時,24 小時格式,HH
$hhour 當前半小時,0-29 對應 0,30-59 對應 1
$qhour 當前1/4小時,0-3
$minute 當前分鐘,MM
timegenerated 和 timereported 的差別請參考 What is the difference between timereported and timegenerated?
每一個屬性可以使用下面的比較操作來和某一個指定的值進行從而定義過濾器。
操作符 說明
contains 屬性包含指定的字串
isequal 屬性等於指定的字串
startswith 屬性由指定字串開始
regex POSIX BRE 正則表示式
ereregex POSIX ERE 正則表示式
示例如下:
:msg,contains,"error" # 選擇包含 error 的日誌
:hostname,isequal, "host1" # 選擇主機名為 host1 的日誌
:msg,!regex,"fatal .* error" # 選擇不匹配指定正則表示式的日誌
基於RainerScript的過濾器
格式如下:
if <EXPRESSION> then <ACTION>
其中,<EXPRESSION> 表示表示式,例如: "$msg startswith 'DEVNAME' or $syslogfacility-text == 'local0'"。 如果表示式結果為真,則會執行相應的動作。
動作
儲存日誌到指定檔案
例如:
cron.* -/var/log/cron.log
如果檔案路徑前有 “-” 則表示每次輸出日誌時不同步(fsync)指定日誌檔案。 檔案路徑既可以是靜態檔案也可以是動態檔案。動態檔案由模板前加 ? 定義。
通過網路傳送日誌
格式如下:
@[(<options>)]<HOST>:[<PORT>]
@ 表示使用 UDP 協議。@@ 表示使用 TCP 協議。<options> 可以為: z<NUMBER> 表示使用 zlib 壓縮,NUMBER 表示壓縮級別。多個選項 使用 , 分隔。
例如:
*.* @192.168.0.1 # 使用 UDP 傳送日誌到 192.168.0.1
*.* @@example.com:18 # 使用 TCP 傳送到 "example.com" 的 18 埠
*.* @(z9)[2001::1] # 使用 UDP 傳送訊息到 2001::1,啟用 zlib 9 級壓縮
傳送訊息到特定使用者
例如
:msg,contains,"error" liuzx
傳送包含 error 的日誌到使用者 liuzx。多個使用者則用 , 分隔,* 表示所有使用者。使用者 的 mesg (參考 man 1 mesg)許可權需要設定為 y。
上面的寫法隨 rsyslog 版本不同,可能會有如下警告資訊,最好做調整。
action 'liuzx' treated as ':omusrmsg:liuzx' - please change syntax, 'liuzx' will not be supported in the future
更多動作
參考輸出模組的文件。例如 omprog 輸出日誌到指定程式的標準輸入,ommysql 輸出 到 MySQL 資料庫,ompgsql 輸出日誌到 PostgreSQL, ...
丟棄日誌
例如
cron.* ~
丟棄所有資訊,即該配置之後的動作不會看到該日誌。
隨 rsyslog 版本不同,如果有如下警告資訊,則將 ~ 修改為 stop。
warning: ~ action is deprecated, consider using the 'stop' statement instead [try http://www.rsyslog.com/e/2307 ]
對每一個過濾條件,可以指定多個動作,每個動作一行即可。這種情況下,也可以通過 “&” 來表示上一行的過濾體檢。例如:
:msg,contains,"error" liuzx
& @192.168.1.1
包含 “error” 日誌被同時傳送給使用者 liuzx 和通過 UDP 傳送到 192.168.1.1。
日誌輸出模板
通過模板可以更具需要來控制日誌輸出的樣式。格式如下:
$template <TEMPLATE_NAME>,"text %<PROPERTY>% more text", [<options>]
$template 為模板指令。<TEMPLATE_NAME> 為模板名。"" 之間的文字為模板格式。 被 % 包含的文字對應相關的屬性。<options> 指定修改 模板功能的一些選項,例如 sql 或者 stdsql 會格式化文字為 SQL 查詢。
動態檔案輸出
通過日誌和/或系統屬性決定輸出檔名。
$template DynamicFile,"/var/log/test_logs/%timegenerated%-test.log"
*.* ?DynamicFile
使用 timegenerated 生成檔名,使用該模板則在前面加上 ?。
其他例子如下:
$template DailyPerHostLogs,"/var/log/syslog/%$YEAR%/%$MONTH%/%$DAY%/%HOSTNAME%/messages.log"
根據屬性控制日誌輸出格式
使用下面的格式可以對模板之中的屬性做各種修改操作從而定製日誌的格式:
%<propname>[:<fromChar>:<toChar>:<options>]%
<propname> 屬性名,可用的屬性名參考上文。
<fromChar> 和 <toChar> 表示對屬性值字串的操作範圍。 設定 <fromChar> 為 R,<toChar> 為正則表示式即可以通過正則 表示式定義範圍。
<options> 則表示屬性選項。完整的列表可以參考 這裡的 Property Options 節。
一些示例如下:
%msg% # 日誌的完整訊息文字
%msg:1:2% # 日誌訊息文字的最開始兩個字元
%msg:::drop-last-lf% # 日誌的完整訊息文字,移出最後的換行符
%timegenerated:1:10:date-rfc3339% # 時間戳的頭10個字元並按 RFC3999 標準格式化
下面是一些模板例子。
輸出日誌的級別,類別,收到日誌時的時間錯,主機名,訊息標籤,訊息正文, 加上換行符:
$template verbose,"%syslogseverity%,%syslogfacility%,%timegenerated%,%HOSTNAME%,%syslogtag%,%msg%\n"
輸出日誌來源,時間以及日誌標籤,正文,同時還有蜂鳴聲(\7):
$template wallmsg,"\r\n\7Message from [email protected]%HOSTNAME% at %timegenerated% ...\r\n %syslogtag% %msg%\n\r"
格式化日誌以便於直接進行 SQL 操作:
$template dbFormat,"insert into SystemEvents (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%',%syslogpriority%, '%timereported:::date-mysql%', '%timegenerated:::date-mysql%',
%iut%, '%syslogtag%')",sql
以 json 格式輸出,方便程式解析:
$template jsonFormat,"{\"message\":\"%msg:::json%\",\"fromhost\":\"%HOSTNAME:::json%\",\"facility\":\"%syslogfacility-text%\",\"priority\":\"%syslogpriority-text%\",\"timereported\":\"%timereported:::date-rfc3339%\",\"timegenerated\":\"%timegenerated:::date-rfc3339%\"}\n"
注意,message 的內容會在最前面多一個空格,其解釋請參考這裡。
rsyslog 也提供了一些預定義的模板(以 RSYSLOG_ 為字首),參考 這裡 的 Reserved Template Names 節,其定義如下:
RSYSLOG_FileFormat
"%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n\"
RSYSLOG_TraditionalFileFormat
"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n\"
RSYSLOG_ForwardFormat
"<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%\"
RSYSLOG_TraditionalForwardFormat
"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%\"
使用這些模板,則在動作後附加 “;template_name” 即可,例如:
:programname,startswith,"cron" -/var/log/cron;RSYSLOG_TraditionalFileFormat
深入理解
佇列是理解 rsyslog 內部原理和配置的重要基礎, 參考 Understanding rsyslog Queues 和 Turning Lanes and Rsyslog Queues - an Analogy。 下圖概要性的說明了 rsyslog 內的資料流圖。
佇列相關的配置指令:
$WorkDirectory /rsyslog/work # 中間檔案存放路徑
$ActionQueueType LinkedList # [FixedArray/LinkedList/Direct/Disk]
$ActionQueueFileName relpact # 定義佇列檔名
$ActionResumeRetryCount -1 # 重試次數, -1 表示無限重試
$ActionQueueSaveOnShutdown on # rsyslog 關閉時將佇列內容存檔,防止資料丟失
*.* :omrelp:172.19.2.10:2514
Syslog系統日誌配置
Linux儲存了系統中所發生事件的詳細記錄,這些記錄稱作日誌檔案或訊息檔案。可以查閱日誌檔案來確定系統當前狀態,觀察入侵者蹤跡,尋找某特定程式(或事件)相關的資料。syslogd與klogd(監控linux核心提交的訊息)守護程序負責記錄,傳送系統或工具產生的資訊,二者的配置檔案都是/etc/syslog.conf。當系統核心或工具產生資訊時,通過呼叫相關函式將資訊傳送到syslogd或klogd守護程序。syslogd與klogd守護程序會根據/etc/syslog.conf中的配置資訊,對訊息的去向作出處理。syslog協議的詳細描述在RFC3164中。
logrotate工具用來定期重新命名、壓縮、郵遞系統日誌檔案,它可以保證日誌檔案不會佔用太大的磁碟空間。
1、配置檔案/etc/syslog.conf: syslog.conf是syslogd程序的配置檔案,將在程式啟動時讀取,預設位置是/etc/syslog.conf。這個配置檔案中的空白行和以"#"開頭的行將被忽略。"facility.level"部分也被稱為選擇符(seletor)。 seletor和action之間使用一個或多個空白分隔。它指定了一系列日誌記錄規則。規則的格式如下:
facility.level action
選擇符(seletor)由facility和level兩部分組成,之間用一個句點(.)連線。
(1)facility:指定了產生日誌的裝置,可以是下面的關鍵字之一:
關鍵字 值 解釋
kern 0 核心資訊,首先通過klogd傳遞
user 1 由使用者程式生成的資訊
mail 2 與電子郵件有關的資訊
daemon 3 與inetd守護程序有關的資訊
auth 4 由pam_pwdb報告的認證活動
syslog 5 由syslog生成的資訊
lpr 6 與列印服務有關的資訊
news 7 來自新聞伺服器的資訊
uucp 8 由uucp生成的資訊(uucp = unix to unix copy)
cron 9 與cron和at有關的資訊
authpriv 10 包括私有資訊(如使用者名稱)在內的認證活動
ftp 11 與FTP有關的資訊
12-15 系統保留
local0 ~ local7 16-23 由自定義程式使用,例如使用local5做為ssh功能
mark syslog內部功能,用於生成時間戳
* 萬用字元代表除了mark以外的所有功能
在大多數情況下,任何程式都可以通過任何facility傳送日誌訊息,但是一般都遵守約定俗成的規則。比如,只有核心才能使用"kern"facility。注意syslog保留從“local0”到“local7”這幾個裝置號來接受從遠端伺服器和網路裝置上傳送過來的日誌資訊。路由器,交換機,防火牆和負載均衡器都很容易給它們各自配置一個獨立的日誌檔案。
(2)level:指定了訊息的優先順序,可以是下面的關鍵字之一(降序排列,嚴重性越來越低):
關鍵字 值 解釋
emerg 0 系統不可用
alert 1 需要立即被修改的條件
crit 2 (臨界)阻止某些工具或子系統功能實現的錯誤條件
err 3 阻止工具或某些子系統部分功能實現的錯誤條件
warning 4 預警資訊
notice 5 具有重要性的普通條件
info 6 提供資訊的訊息
debug 7 不包含函式條件或問題的其他資訊
none (遮蔽所有來自指定裝置的訊息)沒有優先順序,通常用於排錯
* 除了none之外的所有級別
facility部分可以是用逗號(,)分隔的多個裝置,而多個seletor之間也可以通過分號(;)組合在一起。注意多個組合在一起的選擇符,後面的會覆蓋前面的,這樣就允許從模式中排除一些優先順序。預設將對指定級別以及更嚴重級別的訊息進行操作,但是可以通過2個操作符進行修改。等於操作符(=)表示僅對這個級別的訊息進行操作,不等操作符(!)表示忽略這個級別以及更嚴重級別的訊息。這兩個操作符可以同時使用,不過"!"必須出現在"="的前面。
(3)動作action:動作確定了syslogd與klogd守護程序將日誌訊息傳送到什麼地方去。有以下幾種選擇:
普通檔案:使用檔案的絕對路徑來指明日誌檔案所在的位置,例如:/var/log/cron。
終端裝置:終端可以是/dev/tty0~/dev/tty6,也可以為/dev/console。
使用者列表:例如動作為“root hackbutter”,將訊息寫入到使用者root與hackbutter的計算機螢幕上。
遠端主機:將資訊發往網路中的其他主機的syslogd守護程序,格式為“@hostname”。
(4)配置檔案的語法說明:
*用作裝置或優先順序時,可以匹配所有的裝置或優先順序。
*用作動作時,將訊息傳送給所有的登入使用者。
多個選擇器可在同一行中,並使用分號分隔開,且後面的會覆蓋前面的。如uucp,news.crit。
關鍵字none用作優先順序時,會遮蔽所有來自指定裝置的訊息。
通過使用相同的選擇器和不同的動作,同一訊息可以記錄到多個位置。
syslog.conf檔案中後面的配置行不會覆蓋前面的配置行,每一行指定的動作都獨立的運作。
(5)我的Ubuntu中預設的/etc/syslog.conf內容:
# /etc/syslog.conf syslogd的配置檔案
# 更多資訊參考syslog.conf(5)
#
# 首先是一些標準的日誌檔案,訊息由相應裝置傳送
#
# 認證活動auth,authpriv的日誌訊息傳送到auth.log中
auth,authpriv.* /var/log/auth.log
# 除auth和authpriv之外的所有裝置的所有訊息都要傳送到syslog中
*.*;auth,authpriv.none -/var/log/syslog
# cron及at的訊息傳送到cron.log
#cron.* /var/log/cron.log
# inetd的所有訊息傳送到daemon.log
daemon.* -/var/log/daemon.log
# 核心的所有訊息(如klogd的訊息)傳送到kernlog
kern.* -/var/log/kern.log
# 列印服務的所有訊息傳送到lpr.log
lpr.* -/var/log/lpr.log
# 郵件的所有訊息傳送到mail.log
mail.* -/var/log/mail.log
# 使用者程式的所有訊息傳送到user.log
user.* -/var/log/user.log
#
# 郵件系統的日誌記錄。分割成不同的檔案,以便能夠比較容易地寫指令碼來
# 解析這些檔案
#
# 郵件的info或更高級別的訊息傳送到mail.info,warn更高級別的訊息傳送到mail.warn,
# err或更高級別的訊息傳送到mail.err
mail.info -/var/log/mail.info
mail.warn -/var/log/mail.warn
mail.err /var/log/mail.err
# INN新聞系統的日誌記錄:來自新聞伺服器的訊息
#
news.crit /var/log/news/news.crit
news.err /var/log/news/news.err
news.notice -/var/log/news/news.notice
#
# 一些捕捉用的日誌檔案
#
# 除auth,authpriv,news,mail之外的所有裝置的debug級別訊息都要傳送到debug中
*.=debug;/
auth,authpriv.none;/
news.none;mail.none -/var/log/debug
# 除auth,authpriv,cron,daemon,mail,news之外的所有裝置的info,notice,
# warn級別訊息都要傳送到messages中
*.=info;*.=notice;*.=warn;/
auth,authpriv.none;/
cron,daemon.none;/
mail,news.none -/var/log/messages
#
# 所有裝置的emerg級別訊息(系統無法使用)會發送給所有登入的使用者
#
*.emerg *
#
# 希望一些訊息顯示在控制檯,但只在虛擬控制檯上:daemon,mail的任何訊息;news的危險、
# 錯誤、通知訊息;任何裝置的除錯、資訊、通知、預警訊息
#
#daemon,mail.*;/
# news.=crit;news.=err;news.=notice;/
# *.=debug;*.=info;/
# *.=notice;*.=warn /dev/tty8
# 命名管道/dev/xconsole用於xconsloe工具。為了使用它,你必須帶-file選項來呼叫xconsole
# $ xconsole -file /dev/xconsole [...]
# 注意:調整下面的列表,否則如果你有一個相當繁忙的站點,你將變得發狂
daemon.*;mail.*;/
news.err;/
*.=debug;*.=info;/
*.=notice;*.=warn |/dev/xconsole
某些應用軟體也會將自己的執行狀況記錄到特定的日誌檔案上,它不受syslog.conf檔案的控制。如檔案/var/log/apache2/access.log,目錄/var/log/apache2, /var/log/cups, /var/log/gdm, /var/log/mysql, /var/log/samba等。
修改完/etc/syslog.conf後,可用service syslog restart重啟syslog服務,Debian/Ubuntu中則用sudo /etc/init.d/sysklogd restart。檢視日誌檔案裡最新的記錄可用tail -f /var/log/messages。
2、將日誌資訊記錄到遠端Linux伺服器上: 將你的系統資訊記錄到遠端伺服器上將是一個很好的安全措施。如果把公司所有的伺服器的日誌資訊都記錄到一個集中的syslog伺服器上,這將會方便你管理各個伺服器中發生的相關事件。這也會使得掩蓋錯誤和惡意攻擊變得更困難,因為對各個日誌檔案的惡意刪除在日誌伺服器上不能同時發生,特別是當你限制使用者訪問日誌伺服器時。
配置Syslog伺服器:在預設情況下,syslog並不會接受遠端客戶端的資訊,要啟用它,RedHat/Fedora中需要修改/etc/sysconfig/syslog檔案,在SYSLOGD_OPTIONS引數中增加-r選項,以允許記錄遠端機器的資訊。Debian/Ubuntu中則是修改/etc/default/syslogd檔案中的SYSLOGD引數,也可直接編輯syslog啟動指令碼/etc/init.d/sysklogd,將SYSLOGD的引數定義為“-r”。修改完後要重啟syslog服務。
配置客戶端:syslog伺服器現在可以接受syslog資訊了。你還要設定好遠端linux客戶端以向伺服器傳送資訊。假設客戶端主機名為smallfry,可通過編輯/etc/hosts檔案來實現。
(1)確定遠端伺服器的IP地址和有效的域名。
(2)在客戶端班機的/etc/hosts檔案中加入遠端伺服器的描述:IP地址 完整域名 伺服器名 “別名”,例如192.168.1.100 bigboy.my-site.com bigboy loghost,這樣為伺服器主機bigboy設定了一個別名loghost。
(3)編輯客戶端的/etc/syslog.conf檔案,使得syslog資訊能傳送到你新設定的日誌伺服器loghost上。
*.debug @loghost
*.debug /var/log/messages
重啟syslog服務,現在你的機器將會將所有“除錯”級別及以上級別的資訊同時傳送到伺服器bigboy和本地檔案/var/log/messeges上。你可以做個簡單測試看看syslog伺服器是否在接受你的資訊了。比如重啟一下lpd印表機守護程序,看看能否在伺服器上看到相關日誌訊息。
3、配置檔案/etc/logrotate.conf: 它是logrotate的一般性配置檔案。你可以通過它設定哪個日誌檔案被迴圈重用以及多久重用一次。可以設定的迴圈引數有每週(weekly)或每天(daily)。rotate引數定義保留多少份日誌檔案備份,create引數指定在每輪迴圈後就新建空的日誌檔案。我的Ubuntu中預設的/etc/logrotate.conf內容為:
- # 更多細節參考"man logrotate"
- # 每週迴圈更新日誌檔案
- weekly
- # 保留4份日誌檔案的備份,若日誌檔案為logfile,則其備份
- # 分別為logfile.0~logfile3
- rotate 4
- # 在每輪迴圈後建立新的空白日誌檔案
- create
- # 如果你想壓縮日誌檔案,則取消下面註釋
- #compress
- # 一些使用syslog的軟體包會把日誌輪轉資訊放在這個目錄下,因此要包含進來
- include /etc/logrotate.d
- # 沒有軟體包擁有wtmp或btmp,我們將在這裡輪轉
- /var/log/wtmp {
- missingok # 如果日誌檔案丟失,使用下一個並且不傳送任何錯誤訊息
- monthly # 輪轉週期為每月
- create 0664 root utmp # 建立新日誌檔案時,許可權為0664,屬主為root,組為utmp
- rotate 1
- }
- /var/log/btmp {
- missingok
- monthly
- create 0664 root utmp
- rotate 1
- }
- # 特定於系統的日誌可以在這裡配置
注意在Debian/Ubuntu系統中,/etc/cron.daily.sysklogd指令碼將讀取/etc/syslog.conf檔案,並根據它輪轉所有設定的日誌檔案。所以,對於一般的系統日誌,你不必再在/etc/logrotate.d資料夾中重複設定了。因為在 /etc/cron.daily資料夾中它沒24小時便執行一次。在Fedora/Redhat系統中,這個指令碼被/etc/cron.daily/logrotate取代,而且它不讀取syslog配置檔案。所以,你必須在/etc/logrotate.d設定好。
對logrotate的設定只有在你使用logrotate -f命令時才會生效。如果你想讓logrotate只讀取特定的配置檔案而不是所有,把配置檔名作為logrotate的引數執行即可,如logrotate -f /etc/logrotate.d/syslog。如果你的網頁訪問量比較高,那麼日誌檔案將變得異常大。你可以通過編輯logrotate.conf檔案加入壓縮選項compress來實現對日誌檔案的壓縮。這些日誌檔案將用gzip來壓縮,所有的檔案將會有一個.gz的副檔名。檢視這些檔案的內容依然很容易,因為你可以用zcat命令快速的將它們的內容顯示在螢幕上。
Syslog伺服器的一個缺點是沒有把不良來源的訊息過濾掉。因此,當你的的伺服器位於一個不安全的網路時,使用TCP wrappers軟體或防火牆來限制可以接受的訊息來源是一個明智的舉措。這將有助於限制拒絕服務攻擊的成效,這種拒絕服務攻擊的目的是填塞你的伺服器的硬碟或加重其他系統資源負擔,它有可能最終導致伺服器崩潰。
現在使用越來越廣泛的syslog-ng程式結合了logrotate和syslog的特性,它能給使用者提供更多的自定義功能,從功能上也更加豐富了。如果你想使用它,可到www.balabit.com上去下載安裝,其配置檔案為/etc/syslog-ng/syslog-ng.conf。
我的系統配置:
CentOS 6.3
RSYSLOG 5.8.10
LogAnalyzer 4.1.1(v4-beta)
一、篩選日誌到到獨立的檔案
在 git 和 server.git 和 serverctrl.git 兩個庫中,我使用了 Server-side hook(服務端鉤子) 實現自動部署。這兩個鉤子程式會產生日誌資訊。
下面的設定,做了三件事:
將 FACILITY 為 local5 ,PRIORITY 為任意值的日誌寫入 all.log ;
將程式名稱為 hhl-git-serverctrl 的日誌寫入 serverctrl.log ;
將程式名稱為 hhl-git-server 的日誌寫入 server.log 。
-
local5.* /var/log/hhl/all.log
:programname,isequal,"hhl-git-serverctrl" /var/log/hhl/serverctrl.log
:programname,isequal,"hhl-git-server" /var/log/hhl/server.log
我將這些內容放在獨立的配置檔案中,存放在 /etc/rsyslog.d/ 資料夾下。它會在 rsyslogd 服務重啟的時候被自動載入。
二、LogAnalyzer 不顯示 FACILITY 和 PRIORITY
這是因為日誌檔案預設採用老的格式,而 LogAnalyzer 不完全支援這種格式。RSYSLOG WIKI 提供瞭解決方案。需要做下面幾處修改:
1. 修改 /etc/rsyslog.conf 查詢下面的內容:
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
將其替換成為:
$ActionFileDefaultTemplate RSYSLOG_SyslogProtocol23Format
這個操作將日誌格式替換成了 RFC 5424 定義的格式。替換完畢記得重啟 rsyslogd 。
2. 同上,將這個模版加入配置檔案
$template TraditionalFormatWithPRI,"<%syslogpriority%>%syslogseverity% %timegenerated% %HOSTNAM E% %syslogtag%%msg:::drop-last-lf%\n"
3. 進入 LogAnalyzer 的 Admin Center 介面,修改 Source 使其使用 RSyslog Format23(RFC 5424) 。
三、使用 Python 寫入日誌
使用 Python 的 logging 包可以直接將日誌寫入 RSYSLOG 。在上面的配置檔案中,我指定 FACILITY 是 local5 ,因此這裡給出了相同的值。
還要注意 Formatter 第一個引數的第二段就是程式名稱,RSYSLOG 可以依賴這個名稱來篩選日誌,寫入到不同的檔案。
#!/usr/bin/env python
import logging
from logging.handlers import SysLogHandler
log = logging.getLogger('git')
log.setLevel(logging.DEBUG)
log_hdlr = SysLogHandler(facility=SysLogHandler.LOG_LOCAL5, address='/dev/log')
log_format = logging.Formatter(
'%(asctime)s hhl-%(name)s-server[%(process)d]: %(message)s:', '%b %e %H:%M:%S')
log_hdlr.setFormatter(log_format)
log.addHandler(log_hdlr)
如果希望同時加上 print 效果,加入 StreamHandler 即可。
#!/usr/bin/env python
log_hdlr2 = logging.StreamHandler(sys.stdout)
log_hdlr2.setFormatter(log_format)
log.addHandler(log_hdlr2)