一次日志配置未生效问题排查记录

这篇具有很好参考价值的文章主要介绍了一次日志配置未生效问题排查记录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

某天排查业务问题时,在我司的日志收集平台上,未能发现相关业务服务接口访问日志。经过和相关同事确定,发现业务服务未能将接口访问日志吐到日志收集平台,由此开启一段有点漫长的排查之旅。

业务服务是典型的SpringBoot web应用,日志记录采用slf4j+log4j2组合。

通过application.propertis文件中logging.config配置项指定了日志配置文件log4j2.xml具体位置。

通过实现org.apache.logging.log4j.core.Appender接口实现自定义的HttpAppender,将接口访问记录发送到日志收集平台。在log4j2.xml配置文件里如下图

 一次日志配置未生效问题排查记录

具体管理与日志收集平台服务连接,发送请求的是类HttpManager,HttpManager的属性url决定了接收日志信息的日志收集平台地址(来源是配置文件中HttpAppender的url属性)。

所有HttpAppender对象共享同一个HttpManager,按照单例模式创建,合理的做法应是每个HttpAppender有自己单独的HttpManager。

这会导致在有配置多个HttpAppender的情况下,只有在实例化第一个HttpAppender时,其配置的日志平台收集服务的地址会生效。其他的通通无效.

合理的办法是改动HttpAppender源代码,但是我没权限。只能从日志配置文件加载方面想办法,想办法让我们指定的日志配置文件生效。

 文章来源地址https://www.toymoban.com/news/detail-507185.html

基本情况介绍完毕,下面开始排查之旅。

在和同事确定之后没有讲日志信息发送到日志收集平台,凭直觉猜测日志收集平台地址是否正确。检查日志配置文件,发现地址配置正确。难道就这样结束了?不,你已经是一个成熟的程序员了,要学会自己排查问题了。

遇到这种情况时,我看了一下其他服务,相同的配置,却稳定正常的向日志收集平台在发送日志。那我就有理由猜测线上服务实际生效的日志收集平台地址不是我们想要的,但是如何验证了。

我们如何方便的可以查看线上服务某个类对象的字段值了,那就要亮出大杀器了,阿里巴巴开源的Arthas。使用arthas的vmtool命令查看jvm进程中的实例对象数据

一次日志配置未生效问题排查记录

看到的结果让人始料未及,线上服务使用的是日志收集平台的测试地址。现在问题变成了,是什么原因导致了线上加载了错误的配置。

在idea中全局搜索发现,在resources目录下的log4j2.xml中,含有相同的HtppAppender,url属性配置成了日志收集平台的测试地址,maven打包之后,业务jar中也会含有log4j2.xml文件。

那接下来要验证的是jar包里的log4j2.xml是否被加载,如果被加载,这样算下来就会有两份位置不同log42.xml文件被加载。

接下来就是如何进行验证了。

思路是如果加载了两份不同的位置的log4j2.xml,那么创建HttpAppender的方法就会被调用两次,如果能追踪到创建HttpAppender方法的被调用路径,那么排查起来就会轻松些了.

这次还是借助Arthas,通过其stack命令,可以查看指定方法被调用的调用路径。

因为SpringBoot应用一起动,便会在SpringApplication的prepareEnvironment方法里触发日志配置文件加载,等我通过Arthas attach到指定的jvm进程,执行stack命令的时候,日志配置加载已经结束了,为时已晚。

解决办法是通过在启动类的main方法里加上一行代码TimeUnit.SECONDS.sleep(30) 延迟应用的启动,以便有足够的时候通过Arthas attach到jvm进程,执行stack命令。结果如下两张图

一次日志配置未生效问题排查记录

一次日志配置未生效问题排查记录

通过上面这两张图得知,在LoggingApplicationListener正常加载日志配置文件之前,BootStrapApplicationListener触发LoggingApplicationListener做了一次日志配置文件加载。

接下来需要分析的是由BootStrapApplicationListener触发加载的是哪个日志配置文件。

通过分析BootStrapApplicationListener的bootstrapServiceContext方法,其新建的SpringApplication实例对象,读取的默认配置文件为bootstrap.yml。因为项目并没有配置bootstrap.yml,导致ConfigFileApplicationListener对Environment进行初始化时,没有设置logging.config。

没有设置logging.config 那ConfigFileApplicationListener是从哪里加载日志配置文件了。通过分析代码,默认的日志配置加载文件位置由org.springframework.boot.logging.AbstractLoggingSystem#getSelfInitializationConfig方法负责,如下图

一次日志配置未生效问题排查记录

通过上图可得知主要检测classpath里是否存在log4j2.xml,logj4j2.json这样的配置文件。不巧的是服务的jar里存在log4j2.xml,且配置的url是日志收集平台的测试地址。那要如何解决了这个问题了。

通过分析BootStrapApplicationListener源代码,通过在启动脚本里启动命令中添加-Dspring.cloud.bootstrap.enabled=false来禁止BootstrapApplicationListener运行.

修改完毕,再次执行vmtool命令检查日志收集平台url配置是否正确。结果显示的还是日志收集平台测试地址。那说明还有其他地方触发加载了jar包内的log4j2.xml文件。

此时瞥了一眼我们的启动类,那么大一个Logger在那杵着,之前愣是没注意。

 一次日志配置未生效问题排查记录

启动类xxxApplication被加载的时候,此时会触发LOGGER的创建,虽然使用的是SLF4J,实际上创建的是log4j2的Logger,由此会触发针对日志配置文件的加载,经过google搜索,和针对log4j的源码分析,如果没有指定配置文件,默认是会加载classpath下的log4j2.xml文件。

 此时想到的简单办法是把LOGGER属性注释掉,那么就会避免发生记在jar包内的log4j2.xml文件,从而只加载服务目录下的log4j2.xml。

修改完毕,进行第二次验证。不巧的是,显示的还是日志收集平台测试地址,那说明还是有其他地方触发加载了jar包内的log4j2.xml文件。

此时我们的办法还是和第一次内似,这次我们用的是watch命令,关注的是org.slf4j.LoggerFactory getLogger方法的被调用的时候入参。

一次日志配置未生效问题排查记录

通过上图,发现工程依赖的公司封装的Apollo配置服务的jar包内的ApolloApplicationContextInitializer触发了Logger的创建,进而触发加载了jar包内的log4j2.xml。

那这个ApolloApplicationContextInitializer是因为什么原因被触发了class加载,导致了Logger的创建。通过查看源码,ApolloApplicationContextInitializer实现了ApplicationListener接口。SpringApplication在构造函数中会收集当前classpath的spring.factories文件中org.springframework.context.ApplicationListener配置项中的Listener,并实例化。因此导致了ApolloApplicationContextInitializer类的初始化。

一次日志配置未生效问题排查记录

到此我们可以做一下总结,业务程序的启动过程中,按先后顺序总共做了三次日志配置文件log4j2.xml的加载。

第一次:由程序启动类XXXApplication的静态属性LOGGER触发,加载的是业务jar包内log4j2.xml。

第二次:  由org.springframework.cloud.bootstrap.BootstrapApplicationListener触发,加载的是业务jar包内log4j2.xml

第三次:  由LoggingApplicationListener负载加载application.properties指定的服务目录下的logj42.xml。


至此,问题的分析与排查可暂时告一段落,接下来的就是如何修复问题,然后进行验证。办法就两条,

1.减少日志配置文件的加载的次数,

2.让log4j2框架第一次加载日志配置文件时,便加载到正确的日志配置文件。

办法1. 通过在服务启动脚本中加入-Dspring.cloud.bootstrap.enable=false,可以避免上面提到的第二次日志文件加载。

办法2. 通过分析lo4j2源代码,在org.apache.logging.log4j.core.config.ConfigurationFactory类中可以发现通过设置名为log4j.configurationFile的sytem property指定要加载的日志配置文件。


 方法都已找到,解决方法如下图所示,综合了前面提到的两条办法。

一次日志配置未生效问题排查记录

经过验证,问题得到解决,接口访问日志顺利吐到日志收集平台。一个问题的解决之旅也就此结束。

其实事后总结,还是基础不够扎实,对日志框架的了解掌握不够深入,排查分析问题不够仔细,对启动类存在的Logger熟视无睹,由此忽略了带来的日志配置加载问题。

 

到了这里,关于一次日志配置未生效问题排查记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 记录一次@Slf4j log.info 日志信息未输出到日志文件的问题

    Spring Boot的起步依赖(如spring-boot-starter-web)中已经包含了Slf4j的依赖,无需额外添加。: 当你在项目中添加了 spring-boot-starter-web 依赖后,它将自动引入以下关键组件和依赖项: Spring MVC:用于构建Web应用程序的模型-视图-控制器(Model-View-Controller)框架。 Tomcat(或其他嵌入式

    2024年02月06日
    浏览(35)
  • clickhouse一次异常排查记录

    clickhouse中报错 关闭了自启动,删了status,重启了clickhouse还是报错 1,排查定时执行的脚本日志(每小时第5分钟执行) INSERT INTO quality0529.previously_reported_urls (url) SELECT url FROM quality0529.hourly_data_view WHERE findUrlListLastTime = now() - INTERVAL 1 HOUR GROUP BY url 2,查看ck执行异常详细信息统计

    2024年02月11日
    浏览(32)
  • 千兆宽带只剩下百兆了,记录一次排查过程

    事情是这样的:昨晚PUBG有大更新,但是下载的时候我突然发现速度只剩下10M/s左右了,用speedtest测了下只剩下了百兆宽带,我家明明是千兆宽带的。然后就开始了排查,没想到这一搞就是3小时。 这是排查前我家的网络拓扑: 几点说明: 1.全部网络设备都是千兆口,还有几个

    2024年02月05日
    浏览(40)
  • 如何在 MySQL 中开启日志记录并排查操作记录

    在数据库管理中,能够追踪和审查操作记录是至关重要的。这不仅有助于识别和分析正常的数据库活动,还可以在数据泄露或未经授权的更改发生时进行调查和响应。本文将介绍如何在 MySQL 中开启通用日志记录,并如何排查操作记录。 通用日志记录了发往 MySQL 服务器的每一

    2024年04月12日
    浏览(38)
  • 记一次 MySQL 主从同步异常的排查记录,百转千回

    你好,我是悟空。 这是悟空的第 183 篇原创文章 官网:www.passjava.cn 本文主要内容如下: 最近项目的测试环境遇到一个主备同步的问题: 备库的同步线程停止了,无法同步主库的数据更改。 备库报错如下: 完整的错误信息: 上面的报错信息是什么意思呢? 翻译一下就是主

    2023年04月17日
    浏览(70)
  • 记录开发环境docker上的一次springboot无法读取更新的配置文件的问题

    背景:一般开发环境的管理不是很严格,当对代码进行一些组件的添加时,往往需要修改spring的配置文件,有的时候为了保险起见,回预先备份原本的配置文件,我采取在./config中创建了一个名为bak-日期的目录,将原本的配置文件mv到该目录下,将新的配置文件移到config目录

    2024年02月11日
    浏览(38)
  • windows wsl2 vscode golang debug不生效问题排查

    golang vscode点击Run- Start Debugging后,看到正常的debug 调用dlv-dap,但是没有命中断点。 原因是我用的wsl2 remote, 默认代码保存在windows上,在wsl里看到的是/mnt/c/xxx的目录,为了在linux中方便使用建立了软连接。最后导致打断点时日志报找不到go文件。 排查思路: 1、在.vscode/launch.

    2024年02月03日
    浏览(50)
  • 一次服务启动慢问题排查

    随着时间推移,参与开发的人员越来越多,项目代码也会越来越复杂,需要我们有意识的定期对代码进行优化,有问题及时解决,避免技术债务越积越多。 这不本人就遇到一个服务启动慢的问题,印象中服务启动是比较快的,一般也就20几秒,但这次开发一个需求发现服务启

    2024年02月16日
    浏览(33)
  • FreeSWITCH 1.10.10 简单图形化界面7-记录一次配置讯时网关的问题

    用户使用的是迅时HX4E。按照这篇文章配置后,能呼出,不能呼入。 直接呼入网关自己挂了,FreeSWITCH也没有收到任何呼入消息; 网关SIP日志,提示自己486 busy; 抓包发现讯时网关把invite 请求行IP是对的,但是消息发给网关自己了,挺纳闷的; 折腾两个小时用户发现把网线查到

    2024年02月09日
    浏览(32)
  • 记录一次mysql死锁日志分析

    记录一次mysql死锁-CSDN博客 MySQL死锁日志的查看和分析_mysql死锁日志解读_lkforce的博客-CSDN博客 此文承接以上两篇文章,文章1原创记录,文章2转载分析 一,死锁sql update tt_task          SET navigation_distance = ?,    plan_arrive_time = ?          where id = ? update tt_task set grabbing_status

    2023年04月15日
    浏览(65)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包