记一次项目上线后log4j2不输出日志的坑(代码片段)

zeng1994 zeng1994     2023-01-16     578

关键词:

    公司项目采用了Log4j2来输出日志,在开发环境和测试环境下均可以输出日志,但在生成环境就没有日志输出。开始毫无头绪,后来通过不断的排查,终于解决了这个问题。在此记录下该问题的解决过程,便于后续查阅。

一、发现问题

    开发环境打印日志但生产环境不打印日志这个问题比较棘手。一直找不到原因,后面突然想到在启动的时候打印信息肯定会有所不同。通过在2个环境启动同一个项目的控制台打印信息对比有了以下的发现:
(1)出现了SL4J的警告信息,都是提示包冲突
            Multiple bindings were found on the class path
(2)但是仔细观察发现了加载这两个冲突的jar包的顺序不同,具体见下图:

    ①开发环境日志冲突jar包加载顺序图

技术分享图片
        防止图失效,我把文字复制过来了
SLF4J:Class path contains mutiple SLF4J bindings
SLF4J:Found binding in[jar:file:/WEB-INF/lib/log4j-slf4j-impl-2.6.6.jar!/org/slf4j/impl/StaticLoggerBider.class]
SLF4J:Found binding in[jar:file:/WEB-INF/lib/slf4j-log4j12-1.7.22.jar!/org/slf4j/impl/StaticLoggerBider.class]
3
 
1
SLF4J:Class path contains mutiple SLF4J bindings
2
SLF4J:Found binding in[jar:file:/WEB-INF/lib/log4j-slf4j-impl-2.6.6.jar!/org/slf4j/impl/StaticLoggerBider.class]
3
SLF4J:Found binding in[jar:file:/WEB-INF/lib/slf4j-log4j12-1.7.22.jar!/org/slf4j/impl/StaticLoggerBider.class]

    

    ②生产环境日志冲突jar包加载顺序图

技术分享图片
       防止图失效,我把文字复制过来了

SLF4J:Class path contains mutiple SLF4J bindings
SLF4J:Found binding in[jar:file:/WEB-INF/lib/slf4j-log4j12-1.7.22.jar!/org/slf4j/impl/StaticLoggerBider.class]
SLF4J:Found binding in[jar:file:/WEB-INF/lib/log4j-slf4j-impl-2.6.6.jar!/org/slf4j/impl/StaticLoggerBider.class]
3
 
1
SLF4J:Class path contains mutiple SLF4J bindings
2
SLF4J:Found binding in[jar:file:/WEB-INF/lib/slf4j-log4j12-1.7.22.jar!/org/slf4j/impl/StaticLoggerBider.class]
3
SLF4J:Found binding in[jar:file:/WEB-INF/lib/log4j-slf4j-impl-2.6.6.jar!/org/slf4j/impl/StaticLoggerBider.class]

二、分析

  • 在开发环境,先加载的是log4j-slf4j-impl,后加载的是slf4j-log4j12。而生产环境,先加载的是slf4j-log4j12,后加载的是log4j-slf4j-impl
  • 通过查阅官方资料发现slf4j在绑定时,如果有多个可以绑定的包,SLF4J选择绑定的方式由JVM确定,并且出于所有实际目的应该被认为是随机的
  • 但是,经过我12次在slf4j源码打断点测试发现slf4j优先绑定先加载的jar包。所以在开发环境slf4j绑定的是log4j-slf4j-impl这个jar包,而在生产环境中绑定的是slf4j-log4j12这个jar包。
  • 通过查阅log4j2官方资料可知,slf4j集成log4j2时需要的桥接包是log4j-slf4j-impl开发环境中slf4j绑定是正确的,因此可以打印日志。而生产环境中slf4j绑定的jar包是slf4j-log4j12。所以生产环境输出不了日志。产生这个问题的根本原因是lib里面有多个了slf4j可绑定的jar包。

三、解决方案

    由于是slf4j绑定jar包错误而导致打印不了日志。所以我们必须要把这个slf4j-log4j12.jar包排除干净。这个包主要来源有:
1framework-logger(公司自己封装的框架)
2zkclient
3zookeeper
   排除完jar包后,本地进行打包。打包完成后,必须要检查一遍,看一下生成的打包文件的lib文件夹下是否还存在slf4j-log4j12.jar。如果有,应该是jar包没排除干净。可以通过maven命令查看依赖树,看看是那个依赖把这个jar给传递进来的。命令为:dependency:tree

四、小结

(1)使用SLF4j+Log4j2时使用的桥接包是log4j-slf4j-impl
(2)当有多个SLF4j的桥接包时,一定要排除不需要的包
(2)项目启动时控制台输出的信息很重要,耐心观察启动日志可以解决很多问题



















记一次log4j2日志无法输出的心酸史

问题描述:部分日志无法输出到日志文件中。  项目中的代码:@ResourceprivateConfigInfoconfigInfo;privatestaticfinalLoggerlogger=Logger.getLogger(UdmpUtil.class);@PostConstructpublicvoidinitialize(){try{logger.info("logwrite....");U 查看详情

记一次storm提交任务遇到的坑(代码片段)

摘要:主要是自己没有真正理解stormjar命令参数的意义。 情景复现:  在storm集群中使用命令提交后,在UI界面中,一直看不见任务提交上来的任务,但是在集群提交的shell界面中,是可以看到相关任务的日志输出情况的。 ... 查看详情

记一次解密的坑

做项目遇到请求对方页面,对方返回的参数串直接拼接到我的URL上,是一个加密串.因为忘记了之前有URLEncoder这个步骤,解密的时候没有使用URLDecoder进行解密,直接使用AES解密遇到报错,Inputlengthmustbemultipleof16whendecryptingwithpad还可能报Il... 查看详情

记一次使用cobar踩到的坑(代码片段)

起因起因是因为日志里经常报出锁等待超时的错误,并且这个是环环相扣的,一个锁等待会直接引发另外的锁等待,所以危害非常严重,影响非常深远。寻找原因发现是C3P0报出了DEADLOCK,如下图所示:分析... 查看详情

记一次java的内存泄露分析

当前环境jdk==1.8httpasyncclient==4.1.3代码地址git地址:https://github.com/jasonGeng88/java-network-programming背景前不久,上线了一个新项目,这个项目是一个压测系统,可以简单的看做通过回放词表(http请求数据),不断地向服务发送请求,... 查看详情

系统上线那点事-记一次线上系统故障

该项目是一个微信转盘游戏抽奖营销项目。因为运营营销时间要求紧迫。开发測试部署上线用了10天不到,有些准备工作并没有到位,如:1.因为总体开发在上线前2天才完毕,測试了解这个项目需求是在开发的第二周,并没有充... 查看详情

一次鞭辟入里的log4j2异步日志输出阻塞问题的定位(代码片段)

一次鞭辟入里的Log4j2日志输出阻塞问题的定位问题现象线上某个应用的某个实例突然出现某些次请求服务响应极慢的情况,有几次请求超过60s才返回,并且通过日志发现,服务线程并没有做什么很重的操作。这种情况... 查看详情

记一次拿webshell踩过的坑(如何用php编写一个不包含数字和字母的后门)(代码片段)

0x01前言最近在做代码审计的工作中遇到了一个难题,题目描述如下:<?phpinclude‘flag.php‘;if(isset($_GET[‘code‘]))$code=$_GET[‘code‘];if(strlen($code)>40)die("Long.");if(preg_match("/[A-Za-z0-9]+/",$code))die("NO.");@eval($ 查看详情

记一次weblogic发布springboot遇到的坑

项目使用的是Springboot,之前直接使用JAR包的方式发布,但在客户这边实施发布的时候,客户使用的容器是weblogic,版本为10.3.6。 痛苦就此开始!不过项目组还有另外一个也同样使用了Springboot,他们已经顺利发布了,嗯~再百... 查看详情

从ffmpeg输出日志中分析问题原因——记一次输出流顺序异常(代码片段)

本文出处:http://blog.csdn.net/chaijunkun/article/details/117572832,转载请注明。由于本人不定期会整理相关博文,会对相应内容作出完善。因此强烈建议在原始出处查看此文。输出流的顺序怎么无法改变一个视频文件,常... 查看详情

从ffmpeg输出日志中分析问题原因——记一次输出流顺序异常(代码片段)

本文出处:http://blog.csdn.net/chaijunkun/article/details/117572832,转载请注明。由于本人不定期会整理相关博文,会对相应内容作出完善。因此强烈建议在原始出处查看此文。输出流的顺序怎么无法改变一个视频文件,常... 查看详情

记一次项目部署经历

昨天接到任务,需要在一台新机器上部署一个用springboot搭建的项目,我一想,不就是个部署,soeasy,愉快地开始干~按部就班配置好application.yml,执行启动脚本,一看进程,诶,没有进程啊,怎么回事再来一遍,还是没有,一脸... 查看详情

记一次生产的bug

  第一个在代码中使用 newSimpleDateFormat("EEEE")来判断周几。在本地测试过程中通过日志打印出来的周几比如周日对应的是中文汉字“星期日”,然后使用判断if("星期日".equals(weekDay)){ }(其中weekDay是要使用的日期)。在本地... 查看详情

记一次typescript+react的match的坑(代码片段)

1importReactfrom"react";2importmatchfrom‘react-router-dom‘34interfaceProps5match:match<id?:string>678constRdx:React.FC<Props>=(match:Props)=>9constid=match.params.id;10return(11<div>12我是Rdx页面,id是id13</div>14);1516exportdefaultRdx 查看详情

记一次oom查询处理过程

记一次OOM查询处理过程 问题的爆出及分析排查现场排查后的解决方案项目的jvm参数总结 一、问题的爆出及分析排查现场  服务偶尔会出现不可用的情况,导致出现timeout,然后我迅速登录现场,直接查看当时的gc日志,... 查看详情

记一次ceph日志损坏的分析处理过程

1、故障现象今天下午看到群友在说一个问题,说ceph的某个osd处于down的状态,我大概整理下他的处理过程1、查看OSD的状态2、查看日志信息3、启动对应的ceph-osd服务4、检查集群健康状态2、日志损坏了,如何让osd重新上线思路:... 查看详情

记一次内存溢出查找的问题

情景:今天测试环境发现应用出现内存溢出的问题。这是从来没有出现过的问题,在关闭此次版本新上线的功能后仍发现Perm区的内存持续在增长。jdk版本:1.7环境:linux======================================================起因:测试环境出... 查看详情

记一次系统性能优化

用thinkphp3.2.3做了自己的毕业设计,上线使用后发现,响应时间比较长,经过检测后发现是SQL的查询时间太长。这里要感谢系统性能监控平台听云,他们的官网是:http://www.tingyun.com它能检测到不正常的web请求不正常的SQL查询接着... 查看详情