最近接手了一个流传很多手的魔性古早代码,追日志时发现有明显缺失。对log4j不熟,不过可以猜测日志出问题肯定和多进程使用同一个log4j配置有关。经多次排查,终于捋清了其中逻辑。本文对排查过程进行复盘。

一、表征

故事背景:项目有多个入口。一边即以持续运行获取消息的后台进程形式运行,一边又作为单次任务调度的普通进程被不断启动并结束退出。也就是说,同一个项目同时运行着多个进程,并且使用着同一个log4j配置。
下面称后台进程为进程A,普通进程为进程B。A在后台持续运行,B多次短暂执行。
|<----------------- A ------------------- ......
|<- B ->| |<--- B --->| |<- B ->|
起因:进程B的运行效果与预计不符,需排查B的日志定位问题。
神奇的现象:
1)有的B有日志有的没有,没发现明显的出现规律。
2)有的B日志完整,有的不完整。
3)只有近几个小时的B有日志,写进文件的B的日志居然过一段时间会消失。
4)历史日志中,绝大多数日期只有一个B的日志,而个别日志有很多。
 
 

二、内因

每一个A/B的日志指针都分别以append方式打开日志文件,文件指针互相独立,各自向后写。从而导致两个问题:
问题1:因A写的慢、B写的快(业务实际情况),所以每一个B均在文件末尾append,和上一B相邻,而A会逐渐覆盖B的日志,直到开始滚动分页。
 
问题2:当切换到下一自然日0点时,开始滚动分页时,如果此时有B正在运行,则A和B各自有一个指针。
如果A先写,则两次滚动分页后,A往log.yesterday中写,而B往log中写,并在任务完成后释放句柄并退出。新的B继续在log中写。
如果B先写,则两次滚动分页后,A往log中写,B往log.yesterday中写,并在任务完成后释放句柄并退出。新的B继续在log中写。
无论如何,真正的log.yesterday都已经被覆盖。
 
 
 
day1
day2
day3
day4
day5
day6
假设  
A先写
A先写
B先写
B先写
A先写
log
day1的A+B
day2的B
day3的B
day4的A+其他B
day5的A+其他B
day6的B
log.day1
 
day2的A
day2的A
day2的A
day2的A
day2的A
log.day2    
day3的A
day3的A
day3的A
day3的A
log.day3      
day4的第一个B
day4的第一个B
day4的第一个B
log.day4        
day5的第一个B
day5的第一个B
log.day5          
day6的A
 
D日(D <= T-2)的日志只有四种情况:(T日即当前日期)
① 记录了D+1日的第一个B(因为D+1日有B跨天,且B先写)
② 记录了D+1日的所有A(因为D+1日有B跨天,且A先写)
③ 记录了D日的所有A+ 未被覆盖的B(因为D+1日没有B跨天,且D日B先写)
④ 记录了D日的所有的非首个B(因为D+1日没有B跨天,且D日A先写)
 
符合观察到的现象。
done

多进程使用同一log4j配置导致的日志丢失与覆盖问题的更多相关文章

  1. 日志log4j配置详情,日志log具体到你想不到

    一.Log4j简介Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局). 1.LoggersLoggers组件在此系统中被分为五个级别:DEBU ...

  2. 配置Tomcat的日志系统

    成功配置tomcat的log4j日志系统,格式:HTML+每天以yyyy-mm-dd.log命名的日志文件 一.引言: 实习单位让用log4j配置webapp的日志系统,要求产生的日志文件是html格 ...

  3. log4j配置日志文件log4j.appender.R.File相对路径方法

    方法一. 解决的办法自然是用相对路径代替绝对路径,其实log4j的FileAppender本身就有这样的机制,如:log4j.appender.logfile.File=${WORKDIR}/logs ...

  4. Log4j配置的经典总结,打印日志文件,日志存库

        一.介绍 Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制 日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务 器.NT的事件记录器.UNIX Sy ...

  5. Log4j实现对Java日志的配置全攻略

    1. 配置文件 Log4J配置文件的基本格式如下: #配置根Logger log4j.rootLogger = [ level ] , appenderName1 , appenderName2 , ...

  6. Log4j配置详解及不同的包(package)下的日志写入到不同的日志文件下

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt262 以下都是log4j.properties要写入的内容: 一:参数介绍: ...

  7. Log4j按级别输出日志到不同文件配置分析 (转:projava)

    关于LOG4J 按照级别输出日志,并按照级别输出到不同文件中的说法有很多, 网上贴的最多的log4j.properties的设置是这样的 log4j.rootLogger=info,stdout,in ...

  8. log4j 配置日志输出(log4j.properties)

    轉: https://blog.csdn.net/qq_29166327/article/details/80467593 一.入门log4j实例 1.1 下载解压log4j.jar(地址:http: ...

  9. log4j日志输出到日志文件中和控制台中 +log4j配置详解

    1.引入log4j的jar包 https://mvnrepository.com/,可以找到log4j的jar和依赖. 2.创建log4j.properties,并配置log4j #设置日志的级别 , ...

随机推荐

  1. 什么是Viewport

    什么是Viewport 手机浏览器是把页面放在一个虚拟的“窗口”(viewport)中,通常这个虚拟的“窗口”(viewport)比屏幕宽,这样就不用把每个网页挤到很小的窗口中(这样会破坏没有针对手机 ...

  2. ApplicationContextAware使用理解

    接口的作用 当一个类实现了这个接口(ApplicationContextAware)之后,Aware接口的Bean在被初始之后,可以取得一些相对应的资源,这个类可以直接获取spring 配置文件中 所 ...

  3. Mysql 索引类型+索引方法

    MYSQL索引: PRIMARY(唯一且不能为空:一张表只能有一个主键索引). INDEX(普通索引). UNIQUE(唯一性索引). FULLTEXT(全文索引:用于搜索很长一篇文章的时候,效果最好 ...

  4. 使用koa-mysql-session时报错

    描述 在本地测试代码没问题,但是部署到服务器上时就报错. 错误 > cross-env WEBPACK_TARGET=node NODE_ENV=production node ./server ...

  5. 这次一定要教会你搭建Redis集群和MySQL主从同步(非Docker)

    前言 一直都想自己动手搭建一个Redis集群和MySQL的主从同步,当然不是依靠Docker的一键部署(虽然现在企业开发用的最多的是这种方式),所以本文就算是一个教程类文章吧,但在动手搭建之前,会先聊 ...

  6. 永恒之蓝复现(win7/2008)

    Kali对Windows2008/7的MS17010漏洞测试(MSF自带模块) 0x01 说明 其实这个MSF自带的exp模块还是挺让人伤脑筋的,因为它支持的OS并不是很多,也就Windows Ser ...

  7. python变量和运算

    本文收录在Python从入门到精通系列文章系列 1. 指令和程序 计算机的硬件系统通常由五大部件构成,包括:运算器.控制器.存储器.输入设备和输出设备. 其中,运算器和控制器放在一起就是我们通常所说的 ...

  8. js 重写a标签的href属性和onclick事件

    适应场景:假如移动端拨打电话,需要给a标签添加href属性,但是由于需求,需要链接跳转的同时给a标签添加onclick事件,如果不做任何处理的话,默认执行点击事件,而不会跳转href属性的链接. 怎么 ...

  9. 一种logging封装方法,不会产生重复log

    在调试logging的封装的时候,发现已经调用了logging封装的函数,在被其它函数再调用时,会出现重复的logging.原因是不同的地方创建了不同的handler,所以会重复,可以使用暴力方法解决 ...

  10. 微软的分布式应用框架 Dapr

    微服务架构已成为构建云原生应用程序的标准,微服务架构提供了令人信服的好处,包括可伸缩性,松散的服务耦合和独立部署,但是这种方法的成本很高,需要了解和熟练掌握分布式系统.为了使用所有开发人员能够使用任何 ...