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

log日志框架的学习

    博客分类:
  • java
阅读更多

 

Commons-log + log4j 这黄金搭档一直以来都让我们很省心,很好的完成了日志的需求。但是随着技术的变更和对性能的追求,slf4j 和 logback 这对后起之秀的到来好像打破了原本很平静的日志系统,频繁的出现包冲突... 

       和平的日子不在了,让我们一起来看看究竟发生了什么...

 

 

首先看看这些个包,特别是slf4j引入后就引入了一大堆包之后就有点懵了。


为什么commons-logging和jcl-over-slf4j会有冲突呢?看一下它们的类结构


很清晰的可以看到jcl-over-slf4j 重写了 commons-logging...

 

还有slf4j-api的实现呢,同样看类:

其实就这么简单,往往看了代码之后才发现错误是这么显而易见。。。

 

 

顺着研究,继续看一下slf4j的源码及流程

1.测试类

 

package com.taobao.wuzhong.log;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * DESC:
 * 
 * Copyright: Copyright 2011 m.taobao.com
 * 
 * @author wuzhong@taobao.com
 * @time 2011-4-6 下午03:42:11
 * @version 1.0
 **/
public class LogTest {

	// Logback tries to find a file called logback.groovy in the classpath.
	// If no such file is found, logback tries to find a file called
	// logback-test.xml in the classpath.
	// If no such file is found, it checks for the file logback.xml in the
	// classpath..
	// If neither file is found, logback configures itself automatically using
	// the BasicConfigurator which will cause logging output to be directed to
	// the console.
	@Test
	public void test() {
                //commons-logging的方式获取
		Log log = LogFactory.getLog(LogTest.class);
                //slf4j直接的方式获取,推荐用这个
		Logger log2 = LoggerFactory.getLogger(LogTest.class);
		log.debug("eeeeee {} {} {}");
		log2.debug("{} {} {}", new String[] { "a", "b", "c" });
	}

}
 

 

logFactory.getLog 会调用内部静态变量 Slf4jLogFactory.getInstance方法,如下:

 

 public Log getInstance(String name) throws LogConfigurationException {

    Log instance = null;
    // protect against concurrent access of loggerMap
    synchronized (this) {
      instance = (Log) loggerMap.get(name);
      if (instance == null) {
        Logger logger = LoggerFactory.getLogger(name);   //slf4j的方式,代理过去了
        if(logger instanceof LocationAwareLogger) {
          instance = new SLF4JLocationAwareLog((LocationAwareLogger) logger);  //包装了一层,做适配
        } else {
          instance = new SLF4JLog(logger);
        }
        loggerMap.put(name, instance);
      }
    }
    return (instance);
  }

 

loggerFactory 会调用getILoggerFactory().getlOgger()

 

LoggerFactory.java
 public static ILoggerFactory getILoggerFactory() {
    if (INITIALIZATION_STATE == UNINITIALIZED) {
      INITIALIZATION_STATE = ONGOING_INITILIZATION;
      performInitialization();

    }
    switch (INITIALIZATION_STATE) {
    case SUCCESSFUL_INITILIZATION:
      return getSingleton().getLoggerFactory();
    case FAILED_INITILIZATION:
      throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
    case ONGOING_INITILIZATION:
      // support re-entrant behavior.
      // See also http://bugzilla.slf4j.org/show_bug.cgi?id=106
      return TEMP_FACTORY;
    }
    throw new IllegalStateException("Unreachable code");
  }

 private final static void performInitialization() {
    bind();
    versionSanityCheck();
    singleImplementationSanityCheck();

  }

这里的bind很关键,这里动态的绑定了slf4j-api的实现机制

 

static {
    SINGLETON.init();
  }

  /**
   * Package access for testing purposes.
   */
  void init() {
    try {
      try {
        new ContextInitializer(defaultLoggerContext).autoConfig();
      } catch (JoranException je) {
        Util.reportFailure("Failed to auto configure default logger context",
            je);
      }
      StatusPrinter.printInCaseOfErrorsOrWarnings(defaultLoggerContext);
      contextSelectorBinder.init(defaultLoggerContext, KEY);
      initialized = true;
    } catch (Throwable t) {
      // we should never get here
      Util.reportFailure("Failed to instantiate ["
          + LoggerContext.class.getName() + "]", t);
    }
  }
 

获取配置信息初始化

 

autoConfig ….
public URL findURLOfDefaultConfigurationFile(boolean updateStatus) {
    ClassLoader myClassLoader = Loader.getClassLoaderOfObject(this);
    URL url = findConfigFileURLFromSystemProperties(myClassLoader, updateStatus);
    if (url != null) {
      return url;
    }

    url = Loader.getResource(TEST_AUTOCONFIG_FILE, myClassLoader);
    if (updateStatus) {
      statusOnResourceSearch(TEST_AUTOCONFIG_FILE, myClassLoader, url);
    }
    if (url != null) {
      return url;
    }

    url = Loader.getResource(AUTOCONFIG_FILE, myClassLoader);
    if (updateStatus) {
      statusOnResourceSearch(AUTOCONFIG_FILE, myClassLoader, url);
    }
    return url;
  }

  public void autoConfig() throws JoranException {
    StatusListenerConfigHelper.installIfAsked(loggerContext);
    URL url = findURLOfDefaultConfigurationFile(true);
    if (url != null) {
      configureByResource(url);
    } else {
      BasicConfigurator.configure(loggerContext);
    }
  }

 

最后画张流程图总结下,^_^


 

 

总结: log框架应该很好的诠释了 facade , adapter , 实现上还是比较简单的,很好的做到了接口和实现的分离,对今后的代码组织有一定的启发

  • 大小: 18.8 KB
  • 大小: 46.1 KB
  • 大小: 43.8 KB
  • 大小: 37.9 KB
分享到:
评论

相关推荐

    log4j日志框架

    **Log4j日志框架详解** Log4j是Apache组织开发的一个开源的日志记录框架,广泛应用于Java应用程序中。作为一款强大的日志处理工具,它提供了灵活的日志配置,允许开发者根据需求调整日志级别、格式和输出位置,极大...

    log4qt 日志管理 log4qt 日志管理log4qt 日志管理log4qt 日志管理log4qt 日志管理log4qt 日志管理

    Log4Qt是Qt框架下的一款日志记录库,它基于流行的Java日志库log4j设计,为C++开发者提供了一套强大、灵活的日志处理机制。本文将深入探讨Log4Qt日志管理的核心概念、功能特性以及如何在实际项目中有效应用。 一、...

    采用jdk实现的日志框架

    "采用JDK实现的日志框架"是一个基于Java Development Kit(JDK)1.4中的`java.util.logging`包构建的日志系统,它旨在提供与流行的Log4j框架类似的灵活性和功能。 `java.util.logging`是Java平台的标准日志API,自...

    用c++写的 log 日志文件

    此外,C++标准库并没有提供内置的日志框架,但在实际开发中,很多开发者会使用第三方库,如Glog、spdlog等,它们提供了更强大、更灵活的功能,例如异步日志处理、自定义格式化和日志过滤等。 总之,通过理解日志...

    [SSH+Maven+Bootstrap视频教程]_18. 测试 log4j 日志框架.zip

    【SSH+Maven+Bootstrap视频教程】第18章主要讲解了如何测试并应用Log4j日志框架,这是Java开发中的一个关键组件,尤其在系统监控、调试和错误跟踪方面发挥着重要作用。Log4j是Apache软件基金会的一个开放源代码项目...

    android日志框架jar包。log4j android版

    Log4j是一个广泛使用的Java日志框架,在服务器端和桌面应用中非常常见。不过,Log4j原生并不直接支持Android平台,因为它依赖于一些Android系统不包含的库。但有一些开发者社区提供了对Android的适配版本,让Log4j...

    Log4net日志管理框架.pdf

    Log4net是一个强大的日志管理框架,广泛应用于各种软件项目中,主要用于诊断和修复配置问题。该框架提供了丰富的功能,确保开发人员能够有效地记录、管理和分析应用中的日志信息。 **日志分级功能**是Log4net的核心...

    SSM框架log4j.properties日志打印必备包

    SSM框架log4j.properties日志打印必备包SSM框架log4j.properties日志打印必备包SSM框架log4j.properties日志打印必备包SSM框架log4j.properties日志打印必备包

    Android下的自定义日志框架。移动开发一般没有必要引入第三方日志框架,可以自己编写

    `LogDemo`则可能是一个示例应用,展示了如何在实际项目中使用这个自定义的日志框架。 总之,自定义日志框架是Android开发中的一个重要实践,它能提供更高效、安全、可定制的日志管理方案。通过阅读和学习提供的源码...

    log日志组件总结

    本文将深入探讨Java中的log日志组件,包括JDK内置的日志(jdkLog)、Apache的Commons Logging(commonLog)以及流行的log4j。了解这些组件的特点和用法,将提升你对Java日志处理的理解。 首先,我们来看看JDK内置的...

    tomcat8更换log4j记录日志

    此压缩包提供的资源是针对Tomcat8及其以下版本的日志管理解决方案,主要涉及Log4j这个流行的Java日志框架。下面将详细介绍如何在Tomcat8中替换或更新Log4j来记录日志。 首先,让我们了解一下Log4j。Log4j是Apache...

    日志框架学习之一:commons-logging+log4j

    标题中的“日志框架学习之一:commons-logging+log4j”揭示了本文将探讨的是在Java开发中常用的两个日志处理工具——Apache Commons Logging和Log4j。这两个框架是日志记录的基础,广泛应用于各种Java应用程序,为...

    log4cplus开源的C++日志框架

    **log4cplus** 是一个基于C++的开源日志框架,它的设计灵感来源于Java社区中的log4j,旨在提供一种高效、灵活且易于使用的日志记录解决方案。这个框架允许开发者在C++程序中方便地记录调试信息,帮助追踪代码问题、...

    Android下自定义日志框架

    这就是自定义日志框架的意义所在。下面,我们将深入探讨如何在Android中创建一个自定义日志框架。 首先,理解Android系统内置的`Log`类。`Log`类提供了`d()`, `i()`, `w()`, `e()`等方法,用于输出不同级别的日志,...

    log日志的实现

    在IT行业中,日志(log)是至...综上所述,"log日志的实现"涉及了如何在Struts和iBatis等框架中配置和使用日志,以及如何通过最佳实践来提升日志的价值。通过对日志的合理管理,可以大大提高开发效率和系统的可维护性。

    Java日志框架整合详情

    这些框架各有特点,Log4j是早期广泛使用的日志框架,Logback由Log4j的作者设计,提供了更好的性能和配置灵活性;SLF4J是一个抽象层,允许开发者选择底层的日志实现;JUL则是Java内置的日志系统。 2. **SLF4J与...

    Log 日志配置

    本文将深入探讨"Log日志配置"的相关知识点,包括日志的重要性、常用日志框架、配置细节以及如何通过日志记录运行结果和参数。 一、日志的重要性 1. 错误排查:当程序出现异常时,日志记录可以帮助开发者快速定位...

    log4j.rar java写LOG日志的驱动

    **Java日志框架Log4j详解** 在Java编程中,日志记录是不可或缺的一部分,它帮助开发者追踪程序运行状态,定位错误,以及进行性能分析。Log4j是Apache组织开发的一个开源日志框架,它是Java日志处理领域的经典工具,...

    Android-AndroidLog日志打印输出到文件方便查看和上传到服务器

    标题"Android-AndroidLog日志打印输出到文件方便查看和上传到服务器"所描述的,就是一种将Android应用的日志信息写入到本地文件的方法,以便后续分析或上传到远程服务器。这个方法能够帮助开发者在无法直接访问设备...

    JAVA日志框架适配-冲突解决方案.docx

    例如,在SpringBoot+Dubbo项目中,可能会出现log4j和logback的冲突,因为Dubbo依赖了zkclient,而zkclient又依赖了log4j,这样如果项目中还有其他日志框架存在并有使用,就会导致多套共存。解决方案是使用slf4j+...

Global site tag (gtag.js) - Google Analytics