以前用过log4j,只知道简单的使用,是在多人开发的项目中,看到别人使用了,自己才copy过来使用的,但没有深入了解过。前两天开始接触slf4j,据说是一个可以将原有项目中的日志输出框架转换成另外一种新的日志输出框架的第三方开源工具,可以把多个不同项目中的不同日志输出框架通过它转换成同一种输出框架,看了下源码,官网上给了一幅图,如下:
目前它支持过渡的日志框架有jcl、jul和log4j,最终的日志输出框架支持jcl、jul、log4j、logback。
如果你项目中以前是用的log4j作为日志输出框架,想转换成jul,则需要将classpath中原来引用的log4j的jar文件移除,然后添加log4j-over-slf4j-xxx.jar、slf4j-api-xxx.jar、slf4j-jdk14-xxx.jar(xxx指版本号)等三个jar文件即可,项目中的原来的代码都不需要改动,下面简要说一下这三个包的作用:
log4j-over-slf4j-xxx.jar 此包重新实现了log4j.jar包的一些接口,作为桥接器
slf4j-api-xxx.jar 此包是slf4j的api
slf4j-jdk14-xxx.jar 此包是最终选择的日志输出框架
如果原项目中使用的是log4j输出,则使用slf4j桥接之后的最终日志输出框架不能是log4j,源代码中有限制,代码如下:
static { try { Class.forName("org.slf4j.impl.Log4jLoggerFactory"); String part1 = "Detected both log4j-over-slf4j.jar AND slf4j-log4j12.jar on the class path, preempting StackOverflowError. "; String part2 = "See also " + LOG4J_DELEGATION_LOOP_URL + " for more details."; Util.report(part1); Util.report(part2); throw new IllegalStateException(part1 + part2); } catch (ClassNotFoundException e) { // this is the good case } }
slf4j是通过静态绑定来确定最终是由哪个框架进行日志输出(每个框架都实现了org/slf4j/impl/StaticLoggerBinder.class),如果出现多个,则会将第一个加载的类作为日志输出,代码如下:
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; }
它也会报告有哪些被绑定,以及实际被绑定的输出框架
private static void reportMultipleBindingAmbiguity(Set staticLoggerBinderPathSet) { if (isAmbiguousStaticLoggerBinderPathSet(staticLoggerBinderPathSet)) { Util.report("Class path contains multiple SLF4J bindings."); Iterator iterator = staticLoggerBinderPathSet.iterator(); while (iterator.hasNext()) { URL path = (URL) iterator.next(); Util.report("Found binding in [" + path + "]"); } Util.report("See " + MULTIPLE_BINDINGS_URL + " for an explanation."); } } private static void reportActualBinding(Set staticLoggerBinderPathSet) { if (isAmbiguousStaticLoggerBinderPathSet(staticLoggerBinderPathSet)) { Util.report("Actual binding is of type ["+StaticLoggerBinder.getSingleton().getLoggerFactoryClassStr()+"]"); } }
最后会检查版本的兼容性,代码如下:
private final static void versionSanityCheck() { try { String requested = StaticLoggerBinder.REQUESTED_API_VERSION; boolean match = false; for (int i = 0; i < API_COMPATIBILITY_LIST.length; i++) { if (requested.startsWith(API_COMPATIBILITY_LIST[i])) { match = true; } } if (!match) { Util.report("The requested version " + requested + " by your slf4j binding is not compatible with " + Arrays.asList(API_COMPATIBILITY_LIST).toString()); Util.report("See " + VERSION_MISMATCH + " for further details."); } } catch (java.lang.NoSuchFieldError nsfe) { // given our large user base and SLF4J's commitment to backward // compatibility, we cannot cry here. Only for implementations // which willingly declare a REQUESTED_API_VERSION field do we // emit compatibility warnings. } catch (Throwable e) { // we should never reach here Util.report("Unexpected problem occured during version sanity check", e); } }
相关推荐
slf4j-log4j12-1.7.32.jar:用于绑定 1.2版的log4j , 这是一个广泛使用的日志系统,当然你还要把log4j包加到classpath中slf4j-jdk14-1.7.32.jar:用于绑定 java.util.logging, 作为JDK 1.4 的loggingslf4j-simple-...
slf4j:Simple Logging Facade for Java,为java提供的简单日志Facade。Facade:门面,更底层一点说就是接口。他允许用户以自己的喜好,在工程中通过slf4j接入不同的日志系统。更直观一点,slf4j是个数据线,一端...
The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired...
Simple Logging Facade for Java (SLF4J) slf4j-1.5.6.zip
SLF4J(Simple Logging Facade for Java)作为commons-logging的替代,为各种logging APIs提供了一个简单的统一接口,使得最终用户能够在部署的时候配置所希望的logging APIs的实现。
Simple Logging Facade for Java,为java提供的简单日志Facade
SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统。按照官方的说法,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所...
为解决这些问题,SLF4J(Simple Logging Facade for Java)应运而生。它不仅提供了一个更为简洁高效的日志门面,还通过各种适配器支持了众多日志实现,如log4j、logback等。SLF4J通过解耦日志API和具体实现,提高了...
Simple Logging Facade for Java(SLF4J) ,它为多个日志框架提供了一个封装好的调用方式。SLF4J 允许用户在部署时插入所需的日志框架。
more jars for Simple Logging Facade for Java (SLF4J) to your CLASSPATH. - To use the X DevAPI features in Connector/J, you also need the external library protobuf-java, which you can download ...
Hibernate中使用slf4j技术,即简单日志门面(Simple Logging Facade for Java),它服务于各种各样的日志系统,用于整合其他日志系统。此资源就是整合log4j的日志。
SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统。按照官方的说法,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所...
more jars for Simple Logging Facade for Java (SLF4J) to your CLASSPATH. - To use the X DevAPI features in Connector/J, you also need the external library protobuf-java, which you can download ...
slf4j(Simple Loging Facade For Java)是 Java 程序提供日志输出的统一接口,它对日志相关功能进行限制,不提供具体实现,只是告诉其他具体日志实现方案应该满足什么功能、实现什么接口 所以单独的slf4j是不能工作...