当前位置:网站首页 > 技术博客 > 正文

rsyslog syslog



常用可选方案:

  1. rsyslog发送端 + rsyslog接收端: 直接存在接收端的本地硬盘
  2. rsyslog发送端 + logstash接收端 + <后续第三方处理>: 接受到log更新行后,通过logstash简单处理后,可以继续往第三方处理,如放到ElasticSearch,或者放到消息队列Kfaka等
  3. rsyslog发送端 + Splunk: Splunk是商业软件,也是业内用的比较多的方式,价格不菲

不管哪种方案都得监控本地文件的变化,rsyslog属于必选。我们需求比较简单,暂时选用了落地到本地盘,默认存储15天debug日志。

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

rsyslog 在Linux上自带,兼容syslog语法,在syslog基础上增加了更多协议的支持,配合额外module插件可以完成很多场景的使用。借用下官网的图片:

rsyslog-features-imagemap

注: Windows 平台需要 nxlog (nxlog 是用C 语言写的一个跨平台日志收集处理软件)。

在CentOS 6.8 Final 上自带的版本为 5.8.10。如需最新版本,可参考官网。

后面介绍以V5版本为例,如有不同的,会单独指出。

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

一份配置文件主要包括以下几个部分:

  1. MODULES
  2. RULES
  3. 全局指令,模板,模块参数等

自带的配置文件如下,参考后面的注释:

为了完成我们的任务,除了上面默认的模块,还需要加载 ,,来指定监控哪些文件,参考文档。

该模块支持如下指令,一组如下设置,可以称为一个 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处理。 这里我们并不需要,只要命中就保存到接收端同名的文件里。

  1. 加载 imfile 模块
  2. 指定要监控的 log 文件路径,设置合适的tag
  3. 指定远端的接收端的地址

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

  1. 加载 imtcp 模块
  2. 设置 message 格式
  3. 设置 文件存储路径,文件名格式

完整配置: /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行。

  1. echo追加:
  2. 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 配置

    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

版权声明


相关文章:

  • scanf函数的功能是什么2025-09-14 15:01:03
  • 跳表实现排行榜2025-09-14 15:01:03
  • usb驱动详解2025-09-14 15:01:03
  • sscom使用教程2025-09-14 15:01:03
  • pythonunittest框架详解2025-09-14 15:01:03
  • jdk环境变量如何配置2025-09-14 15:01:03
  • 极品五笔86版官方下载2025-09-14 15:01:03
  • obs软件直播教程2025-09-14 15:01:03
  • c++结构体和c结构体2025-09-14 15:01:03
  • uniapp离线打包白屏2025-09-14 15:01:03