踩坑之路 - 日志配置错误导致日志丢失

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 原起在排查一个问题时,发现本应该每天定时执行的日志,在某些日期居然没有,中间的 11.26 、11.28、11.30 的日志呢? 查看同样代码的 打的 A 日志文件,日志均匀,每天都有B 文件的日志为什么某些天丢失了? (这些日志文件本来是做数据对账的,比较重要)分析第一时间反应会不会是踩了 SLS 中间件 日志搜集上传的坑?开始登录机器去查看 A 和 B 当天的日志文件,发现 当天打印 A 日志

原起

在排查一个问题时,发现本应该每天定时执行的日志,在某些日期居然没有,中间的 11.26 、11.28、11.30 的日志呢? 

查看同样代码的 打的 A 日志文件,日志均匀,每天都有

B 文件的日志为什么某些天丢失了? (这些日志文件本来是做数据对账的,比较重要)

分析

  1. 第一时间反应会不会是踩了 SLS 中间件 日志搜集上传的坑?

开始登录机器去查看 A 和 B 当天的日志文件,发现 当天打印 A 日志的机器,确实没有打印 B 日志,奇怪了 。 

  1. logback 日志打印丢失了? 查看 B 日志的日志配置 和 机器日志清单

tail -200 查看最后 200 行 out_user.log 后发现,日志停留在了 11月25号,已经停止更新 5 天了。

定位

已经怀疑到了是日志滚动问题,查了问题日志文件的 logback 配置:

而本项目中正常打印日志的的logback 配置如下: 

这样对比来看,一下就猜测性的定位了问题 , 有人将 SizeAndTimeBasedRollingPolicy的 fileNamePattern 拷贝到了 FixedWindowRollingPolicy 

而FixedWindowRollingPolicy 的 滚动策略配置了 %d{yyyy-MM-dd} 样式的在滚动代码执行时估计异常了

验证:将模板修改为  ${OUT_USER_FILE}.%i.log 后发现问题解决。

深究

为了搞清楚错误的原因,简单分析源码后,在关键位置打上断点

 ch.qos.logback.core.rolling.helper.FileNamePattern 第 66 行,看 parse 方法第 65 行的结果:  

如图所示,logback 中自制的分词器将 biz-%d{yyyy-MM-dd_HH}.%i.txt 解析成了 tokenList。

接下来代码执行到第 67 行,看一下 Node 的结果:

 

%d{yyyy-MM-dd_HH} 和 %i 被解析成了关键字,其他则保持字面值。

关键字 d 和 i 对应不同的转换器:

    static final Map<String, String> CONVERTER_MAP = new HashMap<String, String>();
    static {
        // i 对应 IntegerTokenConverter
        CONVERTER_MAP.put(IntegerTokenConverter.CONVERTER_KEY, IntegerTokenConverter.class.getName());
        // d 对应 DateTokenConverter
        CONVERTER_MAP.put(DateTokenConverter.CONVERTER_KEY, DateTokenConverter.class.getName());
    }

又因为 FixedWindowRollingPolicy 产生的参数值只有 Integer 型的,所以遇到 %d{yyyy-MM-dd_HH} 就会出错了 

总结

很多时候,我们在编写日志配置时,往往都死直接COPY 或者 照猫画虎 , 一不小心就会配置错误,然后 logback-core 并不会在这里做异常配置启动检测,或者做 try catch 处理这个小错误 。 

而日志丢失问题可大可小,如果正好赶上问题排查的关键日志丢失,可能让排查问题的过程非常痛苦,另外如果赶上业务操作日志等重要举证内容,技术同学的说服力大大降低; 

挡路牌指示语: 

 FixedWindowRollingPolicy 策略的  fileNamePattern 不能包含 %d{yyyy-MM-dd}  

补坑:

该问题在 logback 官方确定为 bug , Issues 链接: https://jira.qos.ch/browse/LOGBACK-1293  

想要完全规避该问题,需要将 logback-core 的版本升级到 1.4.6 以上 ;

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
3天前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
72 30
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
1月前
|
网络协议 Linux Windows
Rsyslog配置不同端口收集不同设备日志
Rsyslog配置不同端口收集不同设备日志
|
1月前
|
开发工具 git
git显示开发日志+WinSW——将.exe文件注册为服务的一个工具+图床PicGo+kubeconfig 多个集群配置 如何切换
git显示开发日志+WinSW——将.exe文件注册为服务的一个工具+图床PicGo+kubeconfig 多个集群配置 如何切换
35 1
|
1月前
|
数据采集 监控 Java
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
本文是关于SpringBoot日志的详细教程,涵盖日志的定义、用途、SLF4J框架的使用、日志级别、持久化、文件分割及格式配置等内容。
91 0
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
|
3月前
|
Java 应用服务中间件 HSF
Java应用结构规范问题之配置Logback以仅记录错误级别的日志到一个滚动文件中的问题如何解决
Java应用结构规范问题之配置Logback以仅记录错误级别的日志到一个滚动文件中的问题如何解决
|
3月前
|
Java 应用服务中间件 HSF
Java应用结构规范问题之配置Logback以在控制台输出日志的问题如何解决
Java应用结构规范问题之配置Logback以在控制台输出日志的问题如何解决
|
3月前
|
存储 Ubuntu Apache
如何在 Ubuntu VPS 上配置 Apache 的日志记录和日志轮转
如何在 Ubuntu VPS 上配置 Apache 的日志记录和日志轮转
46 6
|
3月前
|
存储 Ubuntu 应用服务中间件
如何在 Ubuntu VPS 上配置 Nginx 的日志记录和日志轮转
如何在 Ubuntu VPS 上配置 Nginx 的日志记录和日志轮转
32 4
|
3月前
|
存储 容器
【Azure 事件中心】为应用程序网关(Application Gateway with WAF) 配置诊断日志,发送到事件中心
【Azure 事件中心】为应用程序网关(Application Gateway with WAF) 配置诊断日志,发送到事件中心
|
3月前
|
人工智能
【Azure Application Insights】在Azure Function中启用Application Insights后,如何配置不输出某些日志到AI 的Trace中
【Azure Application Insights】在Azure Function中启用Application Insights后,如何配置不输出某些日志到AI 的Trace中