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 syslogd@%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內容爲:
注意在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)