常用可选方案:
- rsyslog发送端 + rsyslog接收端: 直接存在接收端的本地硬盘
- rsyslog发送端 + logstash接收端 + <后续第三方处理>: 接受到log更新行后,通过logstash简单处理后,可以继续往第三方处理,如放到ElasticSearch,或者放到消息队列Kfaka等
- rsyslog发送端 + Splunk: Splunk是商业软件,也是业内用的比较多的方式,价格不菲
不管哪种方案都得监控本地文件的变化,rsyslog属于必选。我们需求比较简单,暂时选用了落地到本地盘,默认存储15天debug日志。
本文主要介绍rsyslog发送端、接收端的配置,以及遇到的一些坑。
rsyslog 在Linux上自带,兼容syslog语法,在syslog基础上增加了更多协议的支持,配合额外module插件可以完成很多场景的使用。借用下官网的图片:

注: Windows 平台需要 nxlog (nxlog 是用C 语言写的一个跨平台日志收集处理软件)。
在CentOS 6.8 Final 上自带的版本为 5.8.10。如需最新版本,可参考官网。
后面介绍以V5版本为例,如有不同的,会单独指出。

message先进入主队列再过滤到分支队列, 最后在各个processor线程中输出内容, 输出方式可以是kafka/rsyslog/file/ES..

一份配置文件主要包括以下几个部分:
- MODULES
- RULES
- 全局指令,模板,模块参数等
自带的配置文件如下,参考后面的注释:
为了完成我们的任务,除了上面默认的模块,还需要加载 ,,来指定监控哪些文件,参考文档。
该模块支持如下指令,一组如下设置,可以称为一个 listener:
接收端配置,注意tag里的逗号 ,稍后在接收端,会它来分隔:
日志设备(可以理解为日志类型):
- 文件: /var/log/messages
- 用户: root,*(表示所有用户), 会发到/var/spool/mail/收件箱里
- 日志服务器: @192.168.56.10 或者 @@192.168.56.10
- 管道: | COMMAND
一个 表示 , 两个 表示 协议。
语法:
默认的消息格式
如果只需要显示原始消息,可设置
模板里支持一些 内置的变量:
上面的例子,在接收端会保存为
解释下这个指令
上面的接收端,在一条规则后,加上了如下的指令(也叫停止指令),代表如果log被当前的rule已经处理过了,则完成本次执行,跳过后续rule的处理。 类似 C++里 switch/case,如果忘记加break的穿透副作用。
如果没有这个指令,则一条新来的消息可以被多个rule处理。 这里我们并不需要,只要命中就保存到接收端同名的文件里。
- 加载 imfile 模块
- 指定要监控的 log 文件路径,设置合适的tag
- 指定远端的接收端的地址
完整配置: /etc/rsyslog.conf 和 /etc/rsyslog.d/product.conf
- 加载 imtcp 模块
- 设置 message 格式
- 设置 文件存储路径,文件名格式
完整配置: /etc/rsyslog.conf
引用官方有关 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.
配置好接收端、发送端rsyslog后,需要验证下是否能正确传送新的log行。
- echo追加:
- vim编辑:
默认大小是2k,大概可以保存1000个中文字符,参考官方说明 $MaxMessageSize, 最小也是2k。
在加载imtcp/imudp之前设置, 此配置包括发送和接收,所以rsyslog客户端、服务端都要设置:
在命中某条rule后,直接break停止
要注意自定义tag的前缀匹配,如果两个tag有共同的前缀,需要把长的放在前面,调整好顺序。
Fix 前:
Fix 后:
个人理解,Linux中关于文件名(255),文件路径(4096)的限制如下,而在接收端,都没有超过这个长度。
进过一番艰难的测试复现,猜测是 这个 的原因。
官方解释Sending messages with tags larger than 32 characters。
发送端默认的模板为:
可以看到 ,被截断到32字符,这个也与我测试的结果一致。
免责声明:由于折腾这个rsyslog太累,最后一条暂时没有Fix,如有需要,请自行测试后再用。
UPDATED @ 2017-01-24
这个问题越来越严重,所以必须花时间解决掉。
如下的两个%syslogtag%,由于前32个字符都相同,导致最后日志写到同一个文件 (按照逗号切割后)了。
其中起作用的就是 这个模板。
解决过程 :
TL;DR
参考了上面的链接: 官方解释Sending messages with tags larger than 32 characters 和 tag getting truncated。
全文搜索关键字 , 最终在如下几个文件找到蛛丝马迹:
- 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
全文搜索关键字 :
- rsyslog-5.8.10/tools/syslogd.c
这里,就能找到我们需要的正确的默认格式了, 可以看到 %syslogtag% 截取了前面32个字符,把ForwardFormat规则替换成完整的 %syslogtag% 即可,注意:最大的长度是512。
通过一番设置,我们已经能成功收集若干台线上机器的日志了:
那么问题来了:
上百台机器的上几百G的日志,怎么才能避免接收端硬盘爆掉?
得用另一个Linux自带的脚本 , 来配合 rsyslog。
请参考: 日志集中化收集(二):logrotate 配置
- rsyslog官方v5版本文档
- rsyslog imfile 模块
- rsyslog Template
- rsyslog 内置属性
- rsyslog 属性处理
- Storing Messages from a Remote System into a specific File
- Writing specific messages to a file and discarding them
- Sending messages with tags larger than 32 characters
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/10874.html