Logback仅向Syslog记录一次日志的异常原因咨询
我之前调试Logback对接Syslog时也踩过类似的坑,结合你的环境(Ubuntu 19.10 + 开启了rsyslog的UDP/TCP 514端口),大概率是这几个原因导致的:
1. Rsyslog默认开启了重复日志抑制
这是最常见的原因!Ubuntu自带的rsyslog默认有一个重复消息合并的功能——当它检测到连续的相同日志内容时,只会保留第一条,后续重复的会被合并成一句类似「last message repeated X times」的汇总日志,不会逐条打印。
你可以检查下rsyslog的主配置文件/etc/rsyslog.conf,看看有没有这行:
$RepeatedMsgReduction on
如果有,把它改成$RepeatedMsgReduction off,然后重启rsyslog服务:
sudo systemctl restart rsyslog
改完之后再测试多次打印日志,应该就能看到每条日志都被正常记录了。
2. Logback SyslogAppender的连接或刷新问题
虽然可能性比第一条低,但也可以排查下Logback的配置。如果你的SyslogAppender没有配置强制刷新,可能存在消息缓存的情况,尤其是短生命周期的测试程序。
可以尝试在你的SyslogAppender配置里添加flushOnClose="true",确保每条日志发送后立即刷新:
<appender name="LOCAL_SYSLOG" class="ch.qos.logback.classic.net.SyslogAppender"> <syslogHost>localhost</syslogHost> <port>514</port> <facility>USER</facility> <suffixPattern>%-5level %logger{36} - %msg</suffixPattern> <!-- 新增这一行,强制刷新 --> <flushOnClose>true</flushOnClose> </appender>
3. 测试程序未正确关闭Logback上下文
如果你的测试代码是运行完就退出的短程序(比如main方法执行完直接结束),有可能Logback还没来得及把所有日志发送到Syslog,进程就终止了。虽然你说修改内容也只记录一次,但还是可以试试在程序退出前手动关闭Logback的上下文:
import org.slf4j.LoggerFactory; import ch.qos.logback.classic.LoggerContext; // 在程序结束前调用这两行 LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); loggerContext.stop();
4. Rsyslog的本地日志过滤规则
偶尔也会碰到rsyslog对本地发送的日志做了优先级或facility的过滤。你可以先验证日志是否真的到达了rsyslog:
在/etc/rsyslog.conf末尾临时添加一行:
# 把所有USER级别的日志输出到测试文件 user.* /var/log/test_logback_syslog.log
然后重启rsyslog,再运行你的测试代码,看看/var/log/test_logback_syslog.log里是否有所有的日志条目。如果有,说明原来的默认日志文件(比如/var/log/syslog)的过滤规则可能把重复消息挡住了。
内容的提问来源于stack exchange,提问作者Dean Schulze

