syslog-ng发送Suricata日志时日志轮转导致重复日志的解决方案咨询
syslog-ng发送Suricata日志时日志轮转导致重复日志的解决方案咨询
嗨,这个问题我之前帮朋友排查过,刚好有几个实用的解决思路,你可以根据自己的环境选:
方案一:结合logrotate的copytruncate模式+仅监控原日志文件
这是最直接的解决方式,核心是让syslog-ng始终监控同一个文件句柄,避免读取轮转后的旧文件:
- 修改logrotate的Suricata日志配置(通常在
/etc/logrotate.d/suricata),加入copytruncate参数:/var/log/suricata/eve.json { daily rotate 5 copytruncate # 关键:复制原文件内容到轮转文件,再清空原文件,而非重命名 compress delaycompress missingok notifempty } - 调整syslog-ng的source配置,去掉
wildcard-file,改为直接监控eve.json:source s_eve { file( "/var/log/suricata/eve.json" flags(no-parse) keep-timestamp(no) keep-hostname(no) ); };
这样一来,syslog-ng一直盯着原文件,logrotate不会改变文件的inode,也就不会触发重复读取;同时copytruncate能保证断连时未发送的日志留在原文件里,恢复连接后会继续发送,不会丢日志。
方案二:用syslog-ng磁盘缓存+忽略轮转文件
如果不想用copytruncate,可以通过限制监控范围+本地缓存来解决:
- 保持syslog-ng的source仅监控
eve.json(和方案一的source配置一样),同时给destination加上磁盘缓存,确保断连时日志不会丢失:destination d_eve { network( "172.16.238.15" transport("tls") port(6514) tls( ca_dir("/etc/syslog-ng/ca.d")) template("$MSG\n") ); disk-buffer( mem-buf-size(10000) # 内存缓存大小 disk-buf-size(1000000) # 磁盘缓存大小 dir("/var/lib/syslog-ng/disk-buffer") # 缓存目录 reliable(yes) # 确保缓存日志不丢失 ); }; - 在logrotate配置里添加
postrotate脚本,通知syslog-ng重新加载配置,适配新的日志文件:postrotate /usr/bin/systemctl reload syslog-ng endscript
这种方式下,syslog-ng不会读取轮转后的eve.1.json等文件,磁盘缓存又能兜底断连场景的日志丢失问题。
方案三:利用syslog-ng的inode跟踪机制
syslog-ng的file source默认会跟踪文件的inode,即使原文件被logrotate重命名,它也会继续读取旧inode对应的文件(也就是轮转后的eve.1.json)直到读完,再自动切换到新的eve.json,完全不会重复发送:
- 把syslog-ng的source从
wildcard-file改成file:source s_eve { file( "/var/log/suricata/eve.json" flags(no-parse) keep-timestamp(no) keep-hostname(no) follow-freq(1) # 每秒检查一次文件变化 ); }; - logrotate可以保持默认的重命名模式(不需要
copytruncate),比如:/var/log/suricata/eve.json { daily rotate 5 compress delaycompress missingok notifempty }
这个方案的优势是完全利用syslog-ng自身的文件跟踪能力,不需要修改logrotate的核心轮转逻辑,也能避免重复和丢日志的问题。
备注:内容来源于stack exchange,提问作者19mike95




