TOP生产环境最近频频发生日志丢失事件,上了三拨人去解决,过了一段时间又出现了,太诡异了!具体现象如下:
1. 有一半的机器日志正常生成,而另一半的机器几乎没有生成日志。
2. 在日志丢失的机器上,所有普通logger配置的日志文件都没有生成,而root logger配置的日志文件却生成了,并且root logger只记录了搜索引擎的日志,其它日志信息一个都没有。
同样的机器,同样的代码,同样的环境,为什么会出现这种问题呢?
要想弄清楚原因,我们还得先来了解JAVA开源世界里的各种日志组件。
一、日志介绍
1. commons-logging: Apache最早提供的日志门面接口,主要是为了避免程序的代码和具体的实现相耦合。类似于JDBC的API接口,具体的JDBC Driver是由各个数据库提供商来实现的。通过统一接口解耦,不过其内部也实现了一些简单的日志方案。
2. log4j: 应用最广泛的一种日志解决方案,主要由Appender, Logger, Pattern, Category等组成,通过log4j.xml或log4j.properties配置文件来实现日志系统的管理和多样化配置。可单独做为日志方案来使用,也可以配合commons-logging接口来使用,以达到解耦。
3. slf4j: Simple Logger Facade for JAVA,是继commons-logging后的又一日志门面接口。与commons-logging的配置加载实现不同,slf4j是通过类加载来感知实现的。slf4j还有一个比较好的特性是,可以通过占位符{}来实现日志替换,避免了log.isXXXEnabled这种无耐的判断。
4. logback: log4j作者的又一力作,作为一个通用可靠、快速灵活的日志框架,将作为log4j的替代和slf4j组成新的日志系统的完整实现。官网上称具有极佳的性能,在关键路径上执行速度是log4j的10倍,且内存消耗更少。
二、加载顺序
1. commons-logging:它是通过LogFactory.getgetFactory()方法按照固定的顺序来加载实现类的:
1) 首先:通过查找系统变量org.apache.commons.logging.LogFactory的配置值来加载相应的实现(可通过JVM的启动参数来配置)。
2) 否则,扫描ClassPath路径下的META-INF/services/org.apache.commons.logging.LogFactory文件,通过此文件的第一行配置值来加载实现(jcl-over-slf4j.jar中包含此文件)。
3)否则,从ClassPath中寻找commons-loggings.properties文件,通过里面的配置项org.apache.commons.logging.LogFactory来加载相应的实现。
4)否则,使用默认的配置方式:如果能找到log4j则默认使用log4j实现,如果没有则使用JDK14Logger实现,再没有则使用commons-logging内部提供的SimpleLog实现。
2. slf4j: 它是通过LoggerFactory类在编译时绑定的import org.slf4j.impl.StaticLoggerBinder类加载的,任何一种基于slf4j的实现都要有一个这个类。
三、如何使用
1. commons-logging + log4j
这是应用最广泛的日志方案,大部分开源软件都采用了这种方式。使用此方案只需引入commons-logging和log4j两个jar包,并提供log4j.xml或log4j.properties配置文件即可。代码如下:
1) private static final Log log = LogFactory.getLog(LogTest.class); //推荐使用这种方式
2) private static final Logger log = Logger.getLogger(LogTest.class); // 使用这种方式其实只需要引入log4j包即可
2. slf4j + logback
此方案性能高,使用灵活方便,可使用默认配置文件,也可以通过加载指定的配置文件。使用此方案需要引入slf4j, logback-core和logback-classic三个jar包。代码如下:
private static final Logger logger = LoggerFactory.getLogger(LogTest.class);
3. commons-logging + slf4j + log4j
如果原有的系统中使用的是commons-logging + log4j,需要迁移到slf4j,则需要使用jcl-over-slf4j桥接包,这个包提供了一个桥接,让底层实现是基于slf4j。使用此方案需要引入commons-logging, jcl-over-slf4j, slf4j-log4j和log4j四个jar包。代码和commons-logging + log4j是一样的。
private static final Log log = LogFactory.getLog(LogTest.class)
四、问题诊断
有了上面的了解,现在来回头看一下日志丢失的问题就方便了,你会发现所有的诡异问题背后其实都是有原因的。
首先来看一下TOP生产环境中都依赖了哪些日志jar包:
- commons-logging
- log4j
- slf4j
- logback(包含org.slf4j.impl.StaticLoggerBinder)
- jcl-over-slf4j(包含META-INF/services/org.apache.commons.logging.LogFactory)
- slf4j-log4j(包含org.slf4j.impl.StaticLoggerBinder)
几乎引入了上面提到的所有日志组件,不出问题才怪,现在我们来分析一下原因:
系统中依赖了commons-logging, jcl-over-slf4j两个包,根据commons-logging的加载顺序可以知道,只要依赖了jcl-over-slf4j包,系统必定被桥接到了slf4j的日志方案上来。更加杯具的是,系统中有两个org.slf4j.impl.StaticLoggerBinder实现,由于JVM加载类的随机性,整个系统将会出现两种日志方案:
1) commons-logging + slf4j + logback
2) commons-logging + slf4j + log4j
由于TOP系统是采用log4j.xml来配置的,如果系统采用的是1)方案,则显然没有日志输出;如果采用的是2)方案,则输出正常。这也就解释了为什么会出现“有一半的机器日志正常生成,而另一半的机器几乎没有生成日志”
但还有一个问题无法解释的是:为什么被采用1)方案的机器上还有root.log生成,并且里面只有搜索引擎的日志。细心的同学可以发现上面的“使用方式”中介绍了可以直接通过log4j的Logger log = Logger.getLogger(LogTest.class)来使用,果然通过查看搜索引擎的代码发现里面是直接使用了log4j来记日志的,没有采用commons-logging门面接口,而log4j是认识log4j.xml的,再加上搜索引擎的包路径没有被配置成普通的logger,所以搜索引擎的日志会被记录在root logger下。这也就解释了什么会出现“普通的logger没有日志生成,而root logger却有日志生成”
五、如何解决
1) 删除jcl-over-slf4j.jar,采用commons-logging + log4j实现
或者
2) 删除logback.jar,采用commons-logging + slf4j + log4j实现
分享到:
相关推荐
### 流程日志中丢失事件的启发式恢复 #### 摘要解析与扩展 在当前企业环境中,业务流程往往是事件驱动的。一方面,业务流程的执行由事件触发并控制;另一方面,当业务流程执行时,会产生大量的事件数据。因此,...
### Oracle日志丢失数据库恢复技巧 #### 背景与问题描述 在Oracle数据库管理过程中,日志文件丢失是一个常见的问题。例如,在某次事件中,测试部门反馈了一个关于内部网络上的Oracle数据库(版本1.105)无法正常...
删除日志并不直接推荐,因为可能会丢失重要信息。但是,如果你确定不再需要某个日志,可以先删除其事件源,然后再删除日志本身。注意,删除日志前必须确认没有其他正在使用的事件源关联到它。 ```csharp public ...
然而,在日常运维过程中,由于各种原因,如意外删除、硬件故障等,可能会导致Oracle的日志文件丢失。日志文件,尤其是重做日志(Redo Log),在数据库的正常运行中扮演着至关重要的角色,它们记录了所有对数据库的...
然而,清空日志需谨慎操作,因为一旦丢失,可能导致无法追溯历史问题,尤其是安全事件。 "保存日志"则是将日志备份到另一个位置,通常是外部存储设备或云存储,以便于后续查阅和分析。保存日志有助于长期保留重要...
Oracle 数据库联机日志文件丢失处理方法 Oracle 数据库联机日志文件是数据库运行的重要组件,负责记录数据库的事务信息,以便在出现故障时可以恢复数据库。然而,在某些情况下,联机日志文件可能会丢失,从而导致...
"备份日志(剪切)11111.exe"可能是这个自动备份工具的执行程序,通过运行这个程序,系统会按照预定的配置或脚本,将Windows事件日志复制到安全的位置,以防止原始日志被覆盖或丢失。通常,这种脚本会包含Windows...
1. **日志缓冲区**:一个线程安全的数据结构,用于临时存储日志信息,例如环形缓冲区可以有效地管理内存并避免日志丢失。 2. **日志级别**:支持不同级别的日志,如DEBUG、INFO、WARNING、ERROR等,用户可以根据...
oracle dataguard丢失日志处理方法,不需要重新实施dataguard
在IT领域,尤其是在数据库管理与维护中,遇到SQL日志文件丢失的情况是较为常见的问题之一。这不仅可能影响到数据库的正常运行,还可能导致数据的完整性受到威胁。本文将基于给定的标题“SQL日志文件丢失后处理方法”...
5. **故障回溯**:当问题发生后,可以通过历史日志回溯事件链,重现问题现场,便于修复。 至于压缩包子文件的“LogHelper”,我们可以推测这是一个C#编写的日志辅助类。它可能提供了方便的日志写入、读取、分析和...
当发现日志丢失时,首先需要确认日志丢失的具体情况,以便采取相应的措施进行恢复。本文将基于提供的文件信息来探讨具体的解决方案。 #### 二、日志丢失的识别与确认 **1. 日志Gap查询** 首先,我们需要检查是否...
### ORACLE日志丢失的恢复 在Oracle数据库管理与维护过程中,日志文件的重要性不言而喻。它们记录了数据库的所有事务操作,是实现数据恢复的关键。本文将围绕“Oracle日志丢失的恢复”这一主题,详细介绍如何处理...
同时,定期备份事务日志也是确保数据安全的重要步骤,因为这使得在灾难性事件后能够快速恢复到某个备份点。 在事务处理过程中,ACID(原子性、一致性、隔离性和持久性)属性的实现也离不开事务日志的支持。原子性...
日志文件应该定期备份,以防数据丢失,同时要限制对日志文件的访问,防止篡改。此外,根据合规性和法规要求,可能需要保留日志数据一定的时间。 总结来说,Windows日志审计是一个复杂的过程,包括设置审计策略、...
《基于SpringBoot的日志脱敏:Logback与Slf4j的实战应用》 在现代的软件开发中,日志系统是不可或缺的一部分,它为开发者提供了系统运行时的详细信息,帮助排查问题,优化性能。SpringBoot框架以其简洁的配置和强大...
在IT行业中,日志文件是系统、应用或程序运行过程中的重要组成部分,它们记录了程序运行的状态、错误信息以及调试信息等,对于故障排查和性能...在进行日志操作时,务必注意数据安全,避免因误操作导致重要信息丢失。
xxl-job-admin读取执行日志的逻辑为:向执行了该任务的执行器发送请求,让执行器从本地读取执行日志。但在k8s中,即使将本地文件通过nfs独立存储,在pod重建后也通常会因为ip变更,找不到执行器,导致读取不到执行...
尽管清除日志可以释放磁盘空间和保护隐私,但也要注意,频繁清除日志可能导致丢失重要信息,影响故障排查和审计。因此,在决定清理日志前,应确保已备份必要数据,并理解清除日志可能带来的后果。同时,定期审查和...
通过对日志的备份,可以确保在数据丢失后能够恢复到特定的时间点。 综上所述,SQLSERVER日志分析工具是数据库管理员的得力助手,它不仅可以帮助我们理解数据库的运行状态,还能提供宝贵的洞察来提升数据库性能、...