`
carver
  • 浏览: 50464 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JAVA日志丢失终极剖析

    博客分类:
  • Java
阅读更多

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实现

 

来源:http://rdc.taobao.com/team/top/2011/03/06/java%E6%97%A5%E5%BF%97%E4%B8%A2%E5%A4%B1%E7%BB%88%E6%9E%81%E5%89%96%E6%9E%90/

分享到:
评论

相关推荐

    Java反序列化终极测试工具

    5. **日志和报告**:记录测试结果,提供详细的日志信息,方便分析和调试。 6. **自动化测试**:支持集成到持续集成/持续部署(CI/CD)流程,自动运行反序列化测试,确保每次代码更改后,反序列化安全仍能得到保障。 ...

    使用Java正则表达式分析处理日志

    本篇将围绕“使用Java正则表达式分析处理日志”这一主题,探讨如何利用Java的正则表达式功能来提取、过滤和操作日志数据。 首先,我们需要理解正则表达式的基本概念。正则表达式(Regular Expression)是一种模式...

    Java日志控件

    Java日志控件是一种在Java EE环境中用于日志监控的组件,它专注于提供对应用程序日志的高效管理和控制。此控件设计的核心理念是通过切面编程(Aspect-Oriented Programming, AOP)来实现日志拦截,允许开发者在不...

    Java项目linux启动脚本以及日志分割安装软件

    通过结合这两个工具,开发者可以构建一个高效、可扩展的Java项目运行环境,确保服务在Linux上的稳定运行,并能有效地管理和分析日志数据,从而提升系统的可维护性和可靠性。在实际操作中,还需要结合具体的业务需求...

    java swing用Logger输出错误日志.docx

    `SimpleFormatter`将日志输出为易于阅读的文本格式,而`XMLFormatter`则生成XML格式的日志,更便于解析和分析。 在代码中,我们可以创建`FileHandler`并将其添加到`Logger`实例,以实现自定义的日志输出。下面是一...

    java发送syslog日志,支持多目的ip

    Java发送Syslog日志是一种常见的系统日志管理方式,尤其在分布式系统中,它能帮助开发者收集、分析和处理来自不同节点的日志信息。Syslog协议是一个标准的日志消息传递协议,广泛应用于网络设备、操作系统和其他软件...

    syslog协议发送日志(java)

    syslog协议是网络设备、操作系统和应用程序之间广泛使用的标准日志记录协议,它允许系统将日志消息发送到中央日志服务器,便于管理和分析。在Java环境中实现syslog协议发送日志,我们可以利用相关的库或者自定义编程...

    jvm crash的崩溃日志详细分析及注意点

    总之,理解和分析JVM崩溃日志是诊断和解决Java应用程序性能问题的关键步骤。通过深入研究日志内容,我们可以找到可能导致崩溃的原因,从而采取相应的优化措施或修复代码,确保应用的稳定性和可靠性。

    Java日志终极指南

    Java日志系统是一个至关重要的工具,它用于记录应用程序在运行过程中的各种事件,帮助开发者调试问题、监控系统状态以及追踪错误。本篇文章将深入探讨Java日志的核心概念、组件、框架选择及其配置。 首先,Java日志...

    Java 日志从入门到实战.docx

    【Java 日志从入门到实战】Java 日志在软件开发中扮演着至关重要的角色,它不仅帮助程序员在项目开发和维护阶段追踪问题,还能提升系统的可维护性和安全性。本文主要针对Java程序员,深入探讨日志的各个方面,以帮助...

    如何在Java中实现微服务的日志分析

    在Java中实现微服务的日志分析是一个涉及多个层面的任务,包括日志的收集、存储、分析和可视化。以下是如何在Java微服务中实现日志分析的详细步骤和代码示例。 通过上述步骤,可以在Java微服务架构中实现全面的日志...

    java-log-project Java日志项目.zip

    Java日志项目是一个专注于日志处理的开源项目,主要针对Java开发者。日志在软件开发中扮演着至关重要的角色,它记录了程序运行时的详细信息,帮助开发者追踪错误、调试代码以及优化性能。这个项目可能包含了一系列...

    SQLSERVER日志分析工具

    SQLSERVER日志分析工具是一种专门针对Microsoft SQL Server数据库系统设计的实用软件,旨在帮助数据库管理员和开发者有效地管理和解析SQL Server的日志数据。日志分析在数据库管理中扮演着至关重要的角色,因为它能...

    c#log日志类和日志分析器(源码)

    本文将深入探讨“c# log日志类和日志分析器”的相关知识点,包括日志的创建、存储、分析以及提供的源码在实际项目中的应用。 首先,让我们了解什么是日志。日志是程序运行过程中产生的事件记录,这些记录包含了...

    jca javacore分析工具

    分析javacore文件通常包括检查线程状态,找出可能的阻塞点,以及查找CPU使用率高的线程。 2. **Heap Dump 文件**: Heap Dump是JVM内存的快照,包含了运行时的所有对象、类元数据、垃圾收集器信息等。当遇到内存...

    Java 日志工具 LogUtil 源码 不依赖第三方jar包

    Java日志工具LogUtil是Java开发中常见的自定义日志工具类,它的主要特点是不依赖任何第三方的日志框架,如Log4j、Logback或SLF4J等。这种独立性使得开发者在某些特定场景下,例如轻量级应用、嵌入式系统或者对依赖...

    Nginx日志分析工具2.1.0.zip

    Nginx日志分析工具2.1.0是一款专为Windows平台设计的软件,用于高效地解析、统计和分析Nginx服务器产生的日志文件。Nginx作为一款高性能的Web服务器和反向代理服务器,广泛应用于各类网站和应用程序中。在日常运维...

    eoms.rar_eo_eoms_java 日志_java 权限_权限管理

    Java提供的如Log4j、SLF4J或Java.util.logging等日志框架,能够帮助开发者对应用程序运行过程中的信息进行详细记录,包括错误、警告、调试信息等,便于后期分析系统性能、定位问题以及优化代码。同时,日志还可以...

    基于C和Java的跨平台日志系统.zip

    日志文件保存支持将日志保存到文件中,便于后续分析和处理。 灵活的回调机制提供文件和错误回调函数,方便用户定制处理逻辑。 安装使用步骤 Android 1. 添加依赖 在项目的build.gradle文件中添加jitpack仓库

Global site tag (gtag.js) - Google Analytics