Open chenpengcong opened 6 years ago
最近完成了这样一个需求:采集各个服务器上的业务日志(文件格式存储)到一台中央服务器上
出于性能和资源占用两个方面我选择了rsyslog来完成这个任务,在此记录下rsyslog的使用心得
配置的模板大致如下
业务服务器
input(type="imrelp" port="20514" ruleset="RemoteLogProcess") module(load="omrelp") module(load="imfile") module(load="impstats" interval="600" severity="7" log.syslog="off" # need to turn log stream logging off! log.file="/var/spool/rsyslog/stats.log") # 每隔600秒输出运行信息 /** * action.resumeRetryCount="-1": action失败时无限重试 * action.resumeInterval="10": action重试时间为(numRetries / 10 + 1) * action.resumeInterval * queue.filename="q_sendToLogServer": 队列文件名前缀为q_sendToLogServer * queue.spoolDirectory="/var/spool/rsyslog": 设置队列文件存储目录 * queue.size="50000": 内存队列最多存储50000条消息 * queue.highwatermark="45000", queue.lowwatermark="30000": 当内存队列存储超过45000条消息时,开始写将内存队列里的消息写入磁盘,直到减至30000 * queue.maxdiskspace="10g": 所有队列文件最多在磁盘上占用10g * queue.saveonshutdown="on": 当rsyslog关闭时未发送的消息被写入磁盘 **/ ruleset(name="Log2LogServer"){ action(type="omrelp" Target="1.1.1.1" Port="20514" Template="RSYSLOG_ForwardFormat"\ action.resumeRetryCount="-1" action.resumeInterval="10"\ queue.filename="q_sendToLogServer" queue.spoolDirectory="/var/spool/rsyslog" queue.type="LinkedList" queue.size="50000" queue.highwatermark="45000" queue.lowwatermark="30000" queue.maxdiskspace="10g" queue.saveonshutdown="on") } input(type="imfile" addMetadata="on" File="/path/to/your/file" Tag="tomcat_access" Ruleset="Log2LogServer")
要理解上面的配置,还需要认识disk-assisted queue
中央服务器
module(load="imrelp") module(load="impstats" interval="600" severity="7" log.syslog="off" # need to turn log stream logging off! log.file="/var/spool/rsyslog/stats.log") template(name="TomcatAccessLogFormat" type="string" string="%fromhost-ip% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n") /** * asyncWriting="on", ioBufferSize="64k": 开启异步写,当缓冲的数据达到64k才进行写文件 * flushInterval="1": 每秒将已缓冲但未写的数据进行写操作 **/ ruleset(name="RemoteLogProcess"){ if ($syslogtag startswith "tomcat_access") then { action(type="omfile" File="/data/log/access.log" template="TomcatAccessLogFormat" asyncWriting="on" flushInterval="1" ioBufferSize="64k" flushOnTXEnd="off") } } input(type="imrelp" port="20514" ruleset="RemoteLogProcess")
如何在消息中额外添加数据再进行转发
由于rsyslog是根据一定格式解析消息, 所以如果我们的消息转发使用了自定义的模板(template),中央服务器的rsyslog可能会解析消息错误,解决方法是将要添加的信息作为消息中msg的一部分,中央服务器的rsyslog再从msg中截取我们想要的数据
比如我们经过一系列逻辑处理得到一个变量$.mydata,现在需要将该变量的值传递到远程rsyslog,并且远程rsyslog可以获取该值,如果我修改上面的配置,使用以下模板进行转发
template(name="myT" type="string" string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %$.mydata% $.mydata% %syslogtag%%msg%")
那么远程rsyslog解析消息后%syslogtag%的值是变量$.mydata的值而不是指定的Tag="tomcat_access"
原因是rsyslog解析不了我们自定义的模板,内置模板RSYSLOG_ForwardFormat的格式是<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32% %msg:::sp-if-no-1st-sp%%msg%,和自定义模板myT的区别是在%syslogtag%之前多了个%$.mydata%,因此该位置的值被解析为属性syslogtag
<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32% %msg:::sp-if-no-1st-sp%%msg%
%syslogtag%
%$.mydata%
正确做法是将变量放在%msg%前面(不要空格),整体作为msg传递到远程rsyslog
ruleset(name="TrimMsg"){ set $.trimed_msg=ltrim($msg); }
远程rsyslog先去除可能存在的前置空格,然后可以在string template中截取出变量mydata的内容%$.trimed_msg:1:3%
%$.trimed_msg:1:3%
注意点
定位问题手段
$ /path/to/rsyslogd -f/path/to/config-file -N3
$ /sbin/rsyslogd ..your options.. -dn > logfile
工具
官网提供了几个蛮有用的工具
消息乱序
rsyslog使用disk-assisted queue可能会出现消息乱序问题 Confirmation on disk assisted queue functionality rsyslog reorders log file content
resources
references
最近完成了这样一个需求:采集各个服务器上的业务日志(文件格式存储)到一台中央服务器上
出于性能和资源占用两个方面我选择了rsyslog来完成这个任务,在此记录下rsyslog的使用心得
配置的模板大致如下
业务服务器
要理解上面的配置,还需要认识disk-assisted queue
中央服务器
如何在消息中额外添加数据再进行转发
由于rsyslog是根据一定格式解析消息, 所以如果我们的消息转发使用了自定义的模板(template),中央服务器的rsyslog可能会解析消息错误,解决方法是将要添加的信息作为消息中msg的一部分,中央服务器的rsyslog再从msg中截取我们想要的数据
比如我们经过一系列逻辑处理得到一个变量$.mydata,现在需要将该变量的值传递到远程rsyslog,并且远程rsyslog可以获取该值,如果我修改上面的配置,使用以下模板进行转发
template(name="myT" type="string" string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %$.mydata% $.mydata% %syslogtag%%msg%")
那么远程rsyslog解析消息后%syslogtag%的值是变量$.mydata的值而不是指定的Tag="tomcat_access"
原因是rsyslog解析不了我们自定义的模板,内置模板RSYSLOG_ForwardFormat的格式是
<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32% %msg:::sp-if-no-1st-sp%%msg%
,和自定义模板myT的区别是在%syslogtag%
之前多了个%$.mydata%
,因此该位置的值被解析为属性syslogtag正确做法是将变量放在%msg%前面(不要空格),整体作为msg传递到远程rsyslog
远程rsyslog先去除可能存在的前置空格,然后可以在string template中截取出变量mydata的内容
%$.trimed_msg:1:3%
注意点
定位问题手段
$ /path/to/rsyslogd -f/path/to/config-file -N3
$ /sbin/rsyslogd ..your options.. -dn > logfile
工具
官网提供了几个蛮有用的工具
消息乱序
rsyslog使用disk-assisted queue可能会出现消息乱序问题 Confirmation on disk assisted queue functionality rsyslog reorders log file content
resources
references