文档章节

slf4j查看

dxbj1010
 dxbj1010
发布于 2015/10/10 10:20
字数 517
阅读 37
收藏 0

###slf4j查看

  1. 先从LoggerFactory这个类入手,起始于getLogger方法

    public static Logger getLogger(String name) {
    	ILoggerFactory iLoggerFactory = getILoggerFactory();
    	return iLoggerFactory.getLogger(name);
    }
    

getILoggerFactory调用后找寻的是类路中StaticLoggerBinder的实现类。

	private final static void bind() {
	    try {
	      Set staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
	      reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
	      // the next line does the binding
	      StaticLoggerBinder.getSingleton();
	      INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
	      reportActualBinding(staticLoggerBinderPathSet);
	      emitSubstituteLoggerWarning();
	    } catch (NoClassDefFoundError ncde) {
	      String msg = ncde.getMessage();
	      if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
	        INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
	        Util.report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
	        Util.report("Defaulting to no-operation (NOP) logger implementation");
	        Util.report("See " + NO_STATICLOGGERBINDER_URL
	                + " for further details.");
	      } else {
	        failedBinding(ncde);
	        throw ncde;
	      }
	    } catch (java.lang.NoSuchMethodError nsme) {
	      String msg = nsme.getMessage();
	      if (msg != null && msg.indexOf("org.slf4j.impl.StaticLoggerBinder.getSingleton()") != -1) {
	        INITIALIZATION_STATE = FAILED_INITIALIZATION;
	        Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");
	        Util.report("Your binding is version 1.5.5 or earlier.");
	        Util.report("Upgrade your binding to version 1.6.x.");
	      }
	      throw nsme;
	    } catch (Exception e) {
	      failedBinding(e);
	      throw new IllegalStateException("Unexpected initialization failure", e);
	    }
	  }

进入到findPossibleStaticLoggerBinderPathSet方法:

	private static Set findPossibleStaticLoggerBinderPathSet() {
	    // use Set instead of list in order to deal with  bug #138
	    // LinkedHashSet appropriate here because it preserves insertion order during iteration
	    Set staticLoggerBinderPathSet = new LinkedHashSet();
	    try {
	      ClassLoader loggerFactoryClassLoader = LoggerFactory.class
	              .getClassLoader();
	      Enumeration paths;
	      if (loggerFactoryClassLoader == null) {
	        paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
	      } else {
	        paths = loggerFactoryClassLoader
	                .getResources(STATIC_LOGGER_BINDER_PATH);
	      }
	      while (paths.hasMoreElements()) {
	        URL path = (URL) paths.nextElement();
	        staticLoggerBinderPathSet.add(path);
	      }
	    } catch (IOException ioe) {
	      Util.report("Error getting resources from path", ioe);
	    }
	    return staticLoggerBinderPathSet;
	  }

通过classLoader加载的类是org/slf4j/impl/StaticLoggerBinder.class是否在类路径存在。如果有多个会或者0个会提示报错信息。

最后间接使用的loggerFactory是Log4jLoggerFactory

private StaticLoggerBinder() {
    loggerFactory = new Log4jLoggerFactory();
    try {
        @SuppressWarnings("unused")
        Level level = Level.TRACE;
    } catch (NoSuchFieldError nsfe) {
        Util.report("This version of SLF4J requires log4j version 1.2.12 or later. See also http://www.slf4j.org/codes.html#log4j_version");
    }
}

通过getLogger方法得到是log4j jar包里面的org.apache.log4j.Logger log4jLogger

public Logger getLogger(String name) {
    Logger slf4jLogger = loggerMap.get(name);
    if (slf4jLogger != null) {
        return slf4jLogger;
    } else {
        org.apache.log4j.Logger log4jLogger;
        if (name.equalsIgnoreCase(Logger.ROOT_LOGGER_NAME))
            log4jLogger = LogManager.getRootLogger();
        else
            log4jLogger = LogManager.getLogger(name);

        Logger newInstance = new Log4jLoggerAdapter(log4jLogger);
        Logger oldInstance = loggerMap.putIfAbsent(name, newInstance);
        return oldInstance == null ? newInstance : oldInstance;
    }
}

ConcurrentMap会多一个方法putIfAbsent相对于普通map。不存在的时候插入,存在的时候不改变。--相对也是线程安全的。

logger返回时候 还是要包装一下成org.slf4j.Logger接口,方便通用。

public void debug(String format, Object arg) {
    if (logger.isDebugEnabled()) {
        FormattingTuple ft = MessageFormatter.format(format, arg);
        logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable());
    }
}

举出其中一个的例子,logger.isDebugEnabled代替了以前代码里面很繁琐的判断过程。使用装饰器对log4j的logger进行了加强。还支持message占位符支持。也算是一个不错的优点了。

© 著作权归作者所有

共有 人打赏支持
dxbj1010
粉丝 5
博文 12
码字总数 7474
作品 0
武汉
程序员
SLF4J: Multiple bindings were found on the class path

众所周知,SLF4J是一个日志门面框架,它的作用是用于定义统一的日志接口,而具体的日志实现是由各个日志框架实现的,比如log4j,logback等。 问题 在使用SLF4J时,当class path同时包含了多个...

勇敢的飞石
05/17
0
0
NoClassDefFoundError: ch/qos/logback/classic/spi/ThrowableProxy

报错日志: 解决方案: 解决冲突。 附: SLF4J warning or error messages and their meanings No SLF4J providers were found. This warning, i.e. not an error, message is reported whe......

程序员诗人
05/17
0
0
slf4j、jcl、jul、log4j1、log4j2、logback大总结

1 系列目录 - jdk-logging、log4j、logback日志介绍及原理- commons-logging与jdk-logging、log4j1、log4j2、logback的集成原理- slf4j与jdk-logging、log4j1、log4j2、logback的集成原理- s...

乒乓狂魔
2015/05/04
0
33
spring3,unitils 与dbunit整合问题记录

unitils 3.3版本,spring3.2.4 1.Caused by: java.lang.IllegalStateException: org.slf4j.LoggerFactory could not be successfully initialized. See also http://www.slf4j.org/codes.htm......

听风雨
2013/10/07
0
0
slf4j与jul、log4j1、log4j2、logback的集成原理

1 系列目录 - jdk-logging、log4j、logback日志介绍及原理- commons-logging与jdk-logging、log4j1、log4j2、logback的集成原理- slf4j与jdk-logging、log4j1、log4j2、logback的集成原理- s...

乒乓狂魔
2015/04/30
0
5

没有更多内容

加载失败,请刷新页面

加载更多

Web系统大规模并发:电商秒杀与抢购

一、大规模并发带来的挑战 在过去的工作中,我曾经面对过5w每秒的高并发秒杀功能,在这个过程中,整个Web系统遇到了很多的问题和挑战。如果Web系统不做针对性的优化,会轻而易举地陷入到异常...

xtof
今天
1
0
代码质量管理平台-sonarqube

在工作中,往往开发的时候会不怎么注重代码质量的人很多,存在着很多的漏洞和隐患等问题,sonarqube可以进行代码质量的审核,而且十分的残酷。。。。。接下来我们说下怎么安装 进入官网下载:...

落叶清风
今天
6
0
在Ubuntu安装和配置Sphinx

Ubuntu系统默认是配置有sphinx的,先检查一下,别多此一举。。。。。 在开始本指南之前,您需要: 一个Ubuntu 16.04服务器。 sudo的一个非root用户,您可以通过以下设置本教程 。 安装在服务...

阿锋zxf
今天
1
0
Qt编写输入法V2018超级终结版

对于qt嵌入式linux开发人员来说,输入法一直是个鸡肋问题,要么不支持实体键盘同步,要么不能汉字输入,要么不支持网页输入等,这几年通过陆续接触大量的各种输入法应用场景客户,得到真实需...

飞扬青云
今天
2
0
TypeScript基础入门之高级类型的多态的 this类型

转发 TypeScript基础入门之高级类型的多态的 this类型 高级类型 多态的this类型 多态的this类型表示的是某个包含类或接口的子类型。 这被称做F-bounded多态性。 它能很容易的表现连贯接口间的...

durban
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部