rsyslog詳解實戰和避坑

目標是要把線上環境的debug日誌及集中化收集起來,一方面是方便開發調試;一方面是避免直接到線上環境查看,存在安全隱患。

常用可選方案:

  1. rsyslog發送端 + rsyslog接收端: 直接存在接收端的本地硬盤
  2. rsyslog發送端 + logstash接收端 + <後續第三方處理>: 接受到log更新行後,通過logstash簡單處理後,可以繼續往第三方處理,如放到ElasticSearch,或者放到消息隊列Kfaka等
  3. rsyslog發送端 + Splunk: Splunk是商業軟件,也是業內用的比較多的方式,價格不菲

基本原理和處理流程都是類似的: 監控本地log文件內容的變化,然後把變化的文件內容發送到遠端收集服務上。
例如常說的ELKstack(ElasticSearch+Logstash+Kibana)的第一步都是配置rsyslog發送端。

不管哪種方案都得監控本地文件的變化,rsyslog屬於必選。我們需求比較簡單,暫時選用了落地到本地盤,默認存儲15天debug日誌。

本文主要介紹rsyslog發送端、接收端的配置,以及遇到的一些坑。

rsyslog 簡介

rsyslog 在Linux上自帶,兼容syslog語法,在syslog基礎上增加了更多協議的支持,配合額外module插件可以完成很多場景的使用。借用下官網的圖片:

rsyslog-features-imagemap

注: Windows 平臺需要 nxlog (nxlog 是用C 語言寫的一個跨平臺日誌收集處理軟件)。

安裝

在CentOS 6.8 Final 上自帶的版本爲 5.8.10。如需最新版本,可參考官網

1
2
3
4
5
6
7
8
9
10
11
$ rsyslogd -version
rsyslogd 5.8.10, compiled with:
FEATURE_REGEXP: Yes
FEATURE_LARGEFILE: No
GSSAPI Kerberos 5 support: Yes
FEATURE_DEBUG (debug build, slow code): No
32bit Atomic operations supported: Yes
64bit Atomic operations supported: Yes
Runtime Instrumentation (slow code): No
 
See http://www.rsyslog.com for more information.

V5版本開發於2010年,屬於比較舊的版本,最新版本是V8,支持了更多的字符串處理函數和更多module,當然性能也更好。
缺點是:新舊配置語法不兼容,而採用內置版本的另一個偷懶的好處是雲端的鏡像也不需要再額外升級,能支持更多老機器。

後面介紹以V5版本爲例,如有不同的,會單獨指出。

工作流

 

message先進入主隊列再過濾到分支隊列, 最後在各個processor線程中輸出內容, 輸出方式可以是kafka/rsyslog/file/ES..

 

 

 

配置文件介紹

執行文件: /sbin/rsyslogd
主配置文件: /etc/rsyslog.conf
自定義配置文件: /etc/rsyslog.d/*.conf
修改配置文件後,重啓服務: sudo /etc/init.d/rsyslog restart

一份配置文件主要包括以下幾個部分:

  1. MODULES
  2. RULES
  3. 全局指令,模板,模塊參數等

自帶的配置文件如下,參考後面的註釋:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# rsyslog v5 configuration file
 
# For more information see /usr/share/doc/rsyslog-*/rsyslog_conf.html
# If you experience problems, see http://www.rsyslog.com/doc/troubleshoot.html
 
#### MODULES #### # 模塊放在開頭加載
 
$ModLoad imuxsock # provides support for local system logging (e.g. via logger command) # 可以用來調試,稍後有例子
$ModLoad imklog # provides kernel logging support (previously done by rklogd)
#$ModLoad immark # provides --MARK-- message capability
 
# Provides UDP syslog reception
#$ModLoad imudp
#$UDPServerRun 514
 
# Provides TCP syslog reception # TCP server,接收端需要加載這個模塊,發送端不需要
#$ModLoad imtcp
#$InputTCPServerRun 514
 
 
#### GLOBAL DIRECTIVES ####
 
# Use default timestamp format
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat # 消息格式
 
# File syncing capability is disabled by default. This feature is usually not required,
# not useful and an extreme performance hit
#$ActionFileEnableSync on
 
#### RULES #### # 用來指定哪種類型的,哪種級別的log,發送給誰處理
 
# Log all kernel messages to the console.
# Logging much else clutters up the screen.
# kern.* /dev/console
 
# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none;cron.none /var/log/messages
 
# The authpriv file has restricted access.
authpriv.* /var/log/secure
 
# Log all the mail messages in one place.
mail.* -/var/log/maillog # '-' 表示異步
 
 
# Log cron stuff
cron.* /var/log/cron
 
# Everybody gets emergency messages
*.emerg *
 
# Save news errors of level crit and higher in a special file.
uucp,news.crit /var/log/spooler
 
# Save boot messages also to boot.log
local7.* /var/log/boot.log # local開頭的是自定義的日誌類型
 
 
# ### begin forwarding rule ###
# The statement between the begin ... end define a SINGLE forwarding
# rule. They belong together, do NOT split them. If you create multiple
# forwarding rules, duplicate the whole block!
# Remote Logging (we use TCP for reliable delivery)
#
# An on-disk queue is created for this action. If the remote host is
# down, messages are spooled to disk and sent when it is up again.
#$WorkDirectory /var/lib/rsyslog # where to place spool files
#$ActionQueueFileName fwdRule1 # unique name prefix for spool files
#$ActionQueueMaxDiskSpace 1g # 1gb space limit (use as much as possible)
#$ActionQueueSaveOnShutdown on # save messages to disk on shutdown
#$ActionQueueType LinkedList # run asynchronously
#$ActionResumeRetryCount -1 # infinite retries if host is down
# remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional
#*.* @@remote-host:514
# ### end of the forwarding rule ###
 
# Finally include all config files in /etc/rsyslog.d. This allows overrides
# of the default configuration above.
$IncludeConfig /etc/rsyslog.d/*.conf # 這裏會自動加載自定義的*.conf配置文件,可以覆蓋默認參數

模塊 imfile

爲了完成我們的任務,除了上面默認的模塊,還需要加載 imfile,,來指定監控哪些文件,參考文檔

1
$ModLoad imfile # Load the imfile input module

該模塊把標準的文本文件轉換成syslog的message格式, 所謂標準文本是指:保護可打印的字符,每行以 LF 作爲分隔符號。 支持文件正在在logrotate的時候,仍能正確處理。
它會把監控文件的讀取到哪一個位置(類似遊標cursor),存儲在state文件裏(由 $WorkDirectory 指定)。

該模塊支持如下指令,一組如下設置,可以稱爲一個 listener:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$InputFileName /path/to/file # 待監控的文件路徑
 
$InputFileTag tag # 文件唯一標識tag,最好保持唯一,用於接收端區分原始log文件,可以包含特殊字符,如":"、","等
 
$InputFileStateFile /path/to/state/file
# 【重要】需要保證發送端唯一,記錄讀取到哪兒,狀態文件保存在$WorkDirectory,默認爲 /var/lib/rsyslog
# 如果某個要監控的文件名變化了,一定要重新設置該值
 
$InputFileFacility facility # log類型,默認local0, local開頭的表示自定義類型
 
$InputFileSeverity severity # log級別:info,warning,默認notice
 
$InputRunFileMonitor # 啓動監控當前的文件,如果忘記這行,則啥事也不會發生
 
$InputFilePollInterval seconds # 全局設置,默認輪詢是10s
 
$InputFilePersistStateInterval lines # 每多少行更新state文件狀態
 
$InputFileReadMode mode # 官網竟然沒這個解釋,不過也沒用到。。。
 
$InputFileMaxLinesAtOnce number
# 默認10240,如果在發送端,需要同時監控多個文件,會處理完當前文件特定行後,切換到下一個文件,避免一個文件一直佔用處理,導致收集別的文件不及時。
 
$InputFileBindRuleset ruleset # 屬於較高級的設置,可以把這個listener綁定到特點的規則(http://www.rsyslog.com/doc/v5-stable/concepts/multi_ruleset.html)

接收端配置,注意tag裏的逗號 ',',稍後在接收端,會它來分隔:

1
2
3
4
5
6
7
8
9
# For product, total 19 files.
 
$InputFileName /Data/logs/product/cache-Statistic.log
$InputFileTag product,cache-Statistic
$InputFileSeverity info
$InputFileStateFile state_product_cache-Statistic
$InputFilePersistStateInterval 25000
$InputFileFacility local5
$InputRunFileMonitor

 

Rule 設置

一條rule的語法格式如: <Facility>.<Severity> <Target>
例如:

1
2
3
4
5
6
7
8
# Log cron stuff
cron.* /var/log/cron
 
# 記錄info到本地messages文件,.none 結尾表示排除掉這些文件類型。
*.info;mail.none;authpriv.none;cron.none /var/log/messages
 
# 所有爲local5的任意級別日誌發送到遠端514
local5.* @@192.168.56.10:514

 

Facility

日誌設備(可以理解爲日誌類型):

1
2
3
4
5
6
7
8
9
10
11
auth #pam產生的日誌,認證日誌
authpriv #ssh,ftp等登錄信息的驗證信息,認證授權認證
cron #時間任務相關
kern #內核
lpr #打印
mail #郵件
mark(syslog) #rsyslog服務內部的信息,時間標識
news #新聞組
user #用戶程序產生的相關信息
uucp #unix to unix copy, unix主機之間相關的通訊
local 1~7 #自定義的日誌設備

 

Severity

1
2
3
4
5
6
7
8
debug #有調式信息的,日誌信息最多
info #一般信息的日誌,最常用
notice #最具有重要性的普通條件的信息
warning, warn #警告級別
err, error #錯誤級別,阻止某個功能或者模塊不能正常工作的信息
crit #嚴重級別,阻止整個系統或者整個軟件不能正常工作的信息
alert #需要立刻修改的信息
emerg, panic #內核崩潰等嚴重信息

Target

  • 文件: /var/log/messages
  • 用戶: root,*(表示所有用戶), 會發到/var/spool/mail/收件箱裏
  • 日誌服務器: @192.168.56.10 或者 @@192.168.56.10
  • 管道: | COMMAND

一個 @ 表示 UDP, 兩個 @@ 表示 TCP 協議。

常用指令

模板$template

模板 $template, 最主要的一個指令,在 接收端 可用來定義消息格式、文件名。主要是在接收端使用。
可參考 官方文檔Templates

語法:

1
2
$template <name>,<內容>,<可選項>
$template MyTemplateName,"\7Text %property% some more text\n",<options>

 

默認的消息格式 RSYSLOG_TraditionalFileFormat

1
2
<接收內容的時間> <發送者的hostname> <$InputFileTag> <原始消息%msg%>
Dec 18 20:39:27 jumper-172-31-56-18 karltestdemoTag blala... dummy msg

 

如果只需要顯示原始消息,可設置

1
$template CleanMsgFormat,"%msg%\n"

 

內置屬性 Properties

模板裏支持一些 內置的變量

1
2
3
4
5
6
7
8
%msg%
%syslogfacility%
%HOSTNAME%
%syslogpriority%
%timereported:::date-mysql%
%timegenerated:::date-mysql%
%iut%
'%syslogtag%'

屬性處理 Property Replacer

Property Replacer 用來處理變量,支持一些簡單的字符串處理,如大小寫,substring等,類似jinja2的filter概念。
版本越新支持的處理函數越強大。
語法: %property:fromChar:toChar:options%

1
2
3
4
# For product
$template productFileFormat,"/Data/logs/product/%fromhost-ip%/%syslogtag:F,44:2%-%$YEAR%%$MONTH%%$DAY%.log"
if $syslogtag startswith 'product' then ?productFileFormat;CleanMsgFormat
& ~

 

上面的例子,在接收端會保存爲 /Data/logs/product/198.168.56.123/karltest_demo-20161218.log

解釋下這個指令%syslogtag:F,44:2%

F, - 代表自定義一個分隔符
44 - 是逗號 , 的 ASCII 碼值,如需要別的分隔符,需要查對應 ASCII 值
2 - 取分隔後的第二個字段

所以就是: 假設發送端自定義的tag爲 $InputFileTag product,karltest_demo
如果tag以product開始,則取出逗號分隔的第二個字段作爲保存的文件名,這也是爲啥上面tag裏要設置一個逗號的緣故。

另外,還支持一定的 regex 語法,可以進行更高級的控制。官方提供了一個在線的 regex 語法測試
友情提醒:真的很難用。。。

停止指令

上面的接收端,在一條規則後,加上了如下的指令(也叫停止指令),代表如果log被當前的rule已經處理過了,則完成本次執行,跳過後續rule的處理。 類似 C++裏 switch/case,如果忘記加break的穿透副作用。

1
& ~

 

如果沒有這個指令,則一條新來的消息可以被多個rule處理。 這裏我們並不需要,只要命中就保存到接收端同名的文件裏。

發送端配置

  1. 加載 imfile 模塊
  2. 指定要監控的 log 文件路徑,設置合適的tag
  3. 指定遠端的接收端的地址

完整配置: /etc/rsyslog.conf 和 /etc/rsyslog.d/product.conf

接收端配置

  1. 加載 imtcp 模塊
  2. 設置 message 格式
  3. 設置 文件存儲路徑,文件名格式

完整配置: /etc/rsyslog.conf

遇到的坑

UDP or TCP ?

一般來說選擇TCP都是OK的,除非忍受部分丟失,在意影響性能,可以改用UDP。
但是注意:如果你的消息每行大小超過了4k,只能用TCP。這是因爲UDP棧大小限制的。

引用官方有關 MaxMessageSize 的描述:

Note: testing showed that 4k seems to be the typical maximum for UDP based syslog. This is an IP stack restriction. Not always … but very often. If you go beyond that value, be sure to test that rsyslogd actually does what you think it should do ;) It is highly suggested to use a TCP based transport instead of UDP (plain TCP syslog, RELP). This resolves the UDP stack size restrictions.

如何測試: vim vs echo ?

配置好接收端、發送端rsyslog後,需要驗證下是否能正確傳送新的log行。

  1. echo追加: echo "dummy message" >> /Data/logs/product/karltest.log
  2. vim編輯: vim /Data/logs/product/karltest.log

用vim編輯後,保存會刷新整個文件,導致rsyslog在比較state file的時候,認爲全部是新增的行,會在接收端出現重複的log行。
所以正確測試方法是用 echo 追加的方式。

Tips:
發送端:可以配合 watch 來測試: watch -n 1 " echo $(date) dummy message >> /Data/logs/product/karltest.log "
接收端: tailf /Data/logs/karltest/karltest.log

接收端:log行太長,被截斷了

默認大小是2k,大概可以保存1000箇中文字符,參考官方說明 $MaxMessageSize, 最小也是2k。

在加載imtcp/imudp之前設置, 此配置包括髮送和接收,所以rsyslog客戶端、服務端都要設置:

1
2
3
4
5
$MaxMessageSize 32k
 
# Provides TCP syslog reception
#$ModLoad imtcp
#$InputTCPServerRun 514

 

發送端:/var/log/messages 文件變大

log除了發送到了接收端,還在本地 /var/log/messages 裏重複出現了,導致messages上G
罪魁禍首是默認的配置文件如下這行:

1
2
3
4
5
# 修改前
*.info;mail.none;authpriv.none;cron.none /var/log/messages
 
# Fix後
*.info;mail.none;authpriv.none;cron.none;local5.none;local6.none /var/log/messages

因爲前面有通配符 *.info 導致我們自定義的 local5.info 也會寫到本地messages文件。
爲了保險,請把接收端、發送端的配置文件都修改掉,忽略掉local5。

接收端:消息被多個rule處理

在命中某條rule後,直接break停止

1
2
3
4
5
6
7
if $syslogtag startswith 'product' then ?productFileFormat;CleanMsgFormat
& ~
 
# 新版本v6之後,變爲:
# rsyslogd: warning: ~ action is deprecated, consider using the 'stop' statement instead [try http://www.rsyslog.com/e/2307 ]
if $syslogtag startswith 'product' then ?productFileFormat;CleanMsgFormat
stop

接收端: 保存的文件路徑不對

要注意自定義tag的前綴匹配,如果兩個tag有共同的前綴,需要把長的放在前面,調整好順序。

Fix 前:

1
2
3
4
5
6
7
8
9
# For erp_wms
$template erp_wms_FileFormat,"/Data/logs/erp/wms/%fromhost-ip%/%syslogtag:F,44:2%-%$YEAR%%$MONTH%%$DAY%.log"
if $syslogtag startswith 'erp_wms' then ?erp_wms_FileFormat;CleanMsgFormat
& ~
 
# For erp_wms3
$template erp_wms3_FileFormat,"/Data/logs/erp/wms3/%fromhost-ip%/%syslogtag:F,44:2%-%$YEAR%%$MONTH%%$DAY%.log"
if $syslogtag startswith 'erp_wms3' then ?erp_wms3_FileFormat;CleanMsgFormat
& ~

 

Fix 後:

1
2
3
4
5
6
7
8
9
10
# 這裏注意下面的tag的順序, 一定要讓長的tag(erp_wms3)保持在上面,因爲他們有共同的前綴(erp_wms)
# For erp_wms3
$template erp_wms3_FileFormat,"/Data/logs/erp/wms3/%fromhost-ip%/%syslogtag:F,44:2%-%$YEAR%%$MONTH%%$DAY%.log"
if $syslogtag startswith 'erp_wms3' then ?erp_wms3_FileFormat;CleanMsgFormat
& ~
 
# For erp_wms
$template erp_wms_FileFormat,"/Data/logs/erp/wms/%fromhost-ip%/%syslogtag:F,44:2%-%$YEAR%%$MONTH%%$DAY%.log"
if $syslogtag startswith 'erp_wms' then ?erp_wms_FileFormat;CleanMsgFormat
& ~

 

接收端: rsyslog 文件名太長後被截斷

比如發送端原始文件名tag: product,cache_status_im_request.log
但是到了接收端就截斷了: cache_status_im_re-20161218.log
因爲本來名字就長,加上了時間後更長了,

個人理解,Linux中關於文件名(255),文件路徑(4096)的限制如下,而在接收端,都沒有超過這個長度。

$ cat /usr/include/linux/limits.h

#ifndef _LINUX_LIMITS_H
#define _LINUX_LIMITS_H

#define NR_OPEN         1024

#define NGROUPS_MAX    65536    /* supplemental group IDs are available */
#define ARG_MAX       131072    /* # bytes of args + environ for exec() */
#define LINK_MAX         127    /* # links a file may have */
#define MAX_CANON        255    /* size of the canonical input queue */
#define MAX_INPUT        255    /* size of the type-ahead buffer */
#define NAME_MAX         255    /* # chars in a file name */
#define PATH_MAX        4096    /* # chars in a path name including nul */
#define PIPE_BUF        4096    /* # bytes in atomic write to a pipe */
#define XATTR_NAME_MAX   255    /* # chars in an extended attribute name */
#define XATTR_SIZE_MAX 65536    /* size of an extended attribute value (64k) */
#define XATTR_LIST_MAX 65536    /* size of extended attribute namelist (64k) */

#define RTSIG_MAX         32

#endif

進過一番艱難的測試復現,猜測是 $InputFileTag 這個 %syslogtag%的原因。

官方解釋Sending messages with tags larger than 32 characters

發送端默認的模板爲:

1
2
3
# 忽略舊的5.8.6的語法
template (name="ForwardFormat" type="string" string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME%
%syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%")

 

可以看到 %syslogtag:1:32%,被截斷到32字符,這個也與我測試的結果一致。

所以如果需要處理更長的tag,需要修改 發送端的template模板,去掉 :1:32 限制。
然後綁定這個模板到對應的target上。
注意:接收端可能也要相應處理,才能handle更長的tag名(未測試)。

免責聲明:由於折騰這個rsyslog太累,最後一條暫時沒有Fix,如有需要,請自行測試後再用。

UPDATED @ 2017-01-24
這個問題越來越嚴重,所以必須花時間解決掉。

如下的兩個%syslogtag%,由於前32個字符都相同,導致最後日誌寫到同一個文件 databas.log (按照逗號切割後)了。

1
2
3
4
5
6
$InputFileName /Data/logs/mqorder/order-mq-aws/database-stat.log
$InputFileTag erp_mqorder-order-mq-aws,database-stat # 長度39
...
$InputFileName /Data/logs/mqorder/order-mq-aws/database-timeout.log
$InputFileTag erp_mqorder-order-mq-aws,database-timeout # 長度42
...

解決方法 :
在發送端的主配置文件 /etc/rsyslog.conf裏修改發送規則:

1
2
3
4
5
6
7
8
9
10
11
# ### begin forwarding rule ###
$template LongTagForwardFormat,"<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%"
$WorkDirectory /var/lib/rsyslog # where to place spool files
$ActionQueueFileName karlzhou_fwdRule # unique name prefix for spool files
$ActionQueueMaxDiskSpace 5g # 5gb space limit (use as much as possible)
$ActionQueueSaveOnShutdown on # save messages to disk on shutdown
$ActionQueueType LinkedList # run asynchronously
$ActionResumeRetryCount -1 # infinite retries if host is down
local5.* @@rsyslog.karlzhou.org:514;LongTagForwardFormat
 
# ### end of the forwarding rule ###

 

其中起作用的就是 LongTagForwardFormat 這個模板。

解決過程 :

TL;DR

參考了上面的鏈接: 官方解釋Sending messages with tags larger than 32 characters 和 tag getting truncated

官方解釋裏是 5.8.6 的舊的語法,而CentOS6.x Final上自帶的是 5.8.10, 語法不一樣。
從官網下載5.8.10的源碼: http://www.rsyslog.com/files/download/rsyslog/rsyslog-5.8.10.tar.gz

全文搜索關鍵字 %syslogtag, 最終在如下幾個文件找到蛛絲馬跡:

  • rsyslog-5.8.10/tools/smfwd.c
  • rsyslog-5.8.10/tools/smtradfile.c
  • rsyslog-5.8.10/tools/smtradfwd.c
  • rsyslog-5.8.10/tools/syslogd.c

全文搜索關鍵字 ForwardFormat:

  • rsyslog-5.8.10/tools/syslogd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
/* hardcoded standard templates (used for defaults) */
static uchar template_DebugFormat[] = "\"Debug line with all properties:\nFROMHOST: '%FROMHOST%', fromhost-ip: '%fromhost-ip%', HOSTNAME: '%HOSTNAME%', PRI: %PRI%,\nsyslogtag '%syslogtag%', programname: '%programname%', APP-NAME: '%APP-NAME%', PROCID: '%PROCID%', MSGID: '%MSGID%',\nTIMESTAMP: '%TIMESTAMP%', STRUCTURED-DATA: '%STRUCTURED-DATA%',\nmsg: '%msg%'\nescaped msg: '%msg:::drop-cc%'\ninputname: %inputname% rawmsg: '%rawmsg%'\n\n\"";
static uchar template_SyslogProtocol23Format[] = "\"<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg%\n\"";
static uchar template_TraditionalFileFormat[] = "=RSYSLOG_TraditionalFileFormat";
static uchar template_FileFormat[] = "=RSYSLOG_FileFormat";
static uchar template_ForwardFormat[] = "=RSYSLOG_ForwardFormat";
static uchar template_TraditionalForwardFormat[] = "=RSYSLOG_TraditionalForwardFormat";
static uchar template_WallFmt[] = "\"\r\n\7Message from syslogd@%HOSTNAME% at %timegenerated% ...\r\n %syslogtag%%msg%\n\r\"";
static uchar template_StdUsrMsgFmt[] = "\" %syslogtag%%msg%\n\r\"";
static uchar template_StdDBFmt[] = "\"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";
static uchar template_StdPgSQLFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-pgsql%', '%timegenerated:::date-pgsql%', %iut%, '%syslogtag%')\",STDSQL";
static uchar template_spoofadr[] = "\"%fromhost-ip%\"";
/* end templates */

正如官網鏈接所說,源碼裏 hardcoded 裏多個默認模板格式,
其中我們需要關注的就是 RSYSLOG_ForwardFormat, 對應的文件即:rsyslog-5.8.10/tools/smfwd.c

1
2
3
4
5
6
7
8
9
10
11
/* smfwd.c
* This is a strgen module for the traditional (network) forwarding format.
*
* Format generated:
* "<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%"
*
* NOTE: read comments in module-template.h to understand how this file
* works!
*
* File begun on 2010-06-01 by RGerhards
*

這裏,就能找到我們需要的正確的默認格式了, 可以看到 %syslogtag% 截取了前面32個字符,把ForwardFormat規則替換成完整的 %syslogtag% 即可,注意:最大的長度是512。

接下來……

通過一番設置,我們已經能成功收集若干臺線上機器的日誌了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# tree -I "*gz|*log" /Data/logs/
/Data/logs/
├── gateway
│   ├── 172.31.70.18
│   │   └── archived
│   ├── 172.31.70.19
│   │   └── archived
│   ├── 172.31.70.195
│   │   └── archived
│   ├── 172.31.70.197
│   │   └── archived
│   ├── 172.31.70.198
│   │   └── archived
│   └── 172.31.70.20
│   └── archived
├── product
│   ├── 172.31.70.118
│   │   └── archived
│   ├── 172.31.70.119
│   │   └── archived
│   ├── 172.31.70.23
│   │   └── archived
│   └── 172.31.70.24
│   └── archived
...
 
# du -sh /Data/logs
271G /Data/logs

那麼問題來了:

上百臺機器的上幾百G的日誌,怎麼才能避免接收端硬盤爆掉?

得用另一個Linux自帶的腳本 /usr/sbin/logrotate, 來配合 rsyslog。

請參考: 日誌集中化收集(二):logrotate 配置

參考鏈接

    1. rsyslog官方v5版本文檔
    2. rsyslog imfile 模塊
    3. rsyslog Template
    4. rsyslog 內置屬性
    5. rsyslog 屬性處理
    6. Storing Messages from a Remote System into a specific File
    7. Writing specific messages to a file and discarding them
    8. Sending messages with tags larger than 32 characters
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章