SLF4j笔记

特性:
classes are loaded by the JVM
slf4j不需要classloader的原理(而commons-logging需要classloader,所以会内存泄漏或者别的加载问题)
Mapped Diagnostic Context (MDC)只有log4j和logback支持,slf4j也支持
支持自定义日志级别(Marker),目前只有logback对其进行了实现。
支持国际化(个人认为:有毛用啊……)
-----------------------------------------------------------
用法:
log性能:
commons-logging中,以下这种形式,不管是否log,都会损失拼接字符串的时间:
logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
以下这种形式,是对上述情况的改进,但很臃肿:
if(logger.isDebugEnabled()) {
  logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}
以下这种,在slf4j里支持,很完美:
logger.debug("The entry is {}.", entry);
多个参数的情况:
logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);
很多参数的情况(也可以利用Object...,不用显式指定Object[]):
logger.debug("Value {} was inserted between {} and {}.", new Object[] {newVal, below, above});

对{}进行转义:
以下情况不需要转移(slf4j它只认紧挨着的{}符号)
logger.debug("Set {1,2} differs from {}", "3");
以下情况也不需要转义:
logger.debug("Set {1,2} differs from {{}}", "3");
实在需要转义时可以这样:
logger.debug("Set \\{} differs from {}", "3");
实在不需要转义时可以这样:
logger.debug("File name is C:\\\\{}.", "file.zip");
打印异常对象的堆栈信息,除了这种形式:
debug(String msg, Throwable t);
还可以结合参数化(转移字符{})来使用:
logger.error("Failed to format {}", s, e);
     ——框架会发现最后一个参数是多余的,并查看其是否是一个异常对象,如果是则输出堆栈,否则忽略。
-----------------------------------------------------------
logger声明的讨论:
static和non-static各有好处:
     static的CPU和内存性能更好
     non-static对IOC更友好,而且在多个应用共用一套类库时,可以保持各自的日志环境
          (logback无论如何都是安全的,但如果在多个应用分享同一个类库,并且为static的,那log4j会出问题:所有的日志都打印到第一个加载到内存的日志对象中)
     在slf4j的1.5.3之后,non-static的logger不需要标记transient关键字,也不会被序列化(怎么做到的?)
建议的声明方式(我觉得加上static比较好,还有private):
final (static) Logger logger = LoggerFactory.getLogger(MyClass.class);
-----------------------------------------------------------
迁移工具:
http://www.slf4j.org/migrator.html
-----------------------------------------------------------
实现包:
唯一必要的包:slf4j-api.jar
slf4j-log4j12-1.6.4.jar
     Binding for log4j version 1.2, a widely used logging framework. You also need to place log4j.jar on your class path.
     需要把log4j的包也一同放进来。
slf4j-jdk14-1.6.4.jar
     Binding for java.util.logging, also referred to as JDK 1.4 logging
     绑定到jdk的日志中
slf4j-nop-1.6.4.jar
     Binding for NOP, silently discarding all logging.
     绑定到“无操作”,静默。
slf4j-simple-1.6.4.jar
     Binding for Simple implementation, which outputs all events to System.err. Only messages of level INFO and higher are printed. This binding may be useful in the context of small applications.
     最简单的实现,直接输出到控制台
slf4j-jcl-1.6.4.jar
     Binding for Jakarta Commons Logging. This binding will delegate all SLF4J logging to JCL.
     绑定到common-logging,桥接过去。
logback-classic-1.0.13.jar (requires logback-core-1.0.13.jar)
      绑定到原生实现的logback上,性能最高
SLF4j笔记_第1张图片


在maven中声明包的实现:
对于普通项目(并不是一个工具包):
     logback:
          声明对logback-classic-1.0.13.jar的依赖即可,会自动关联依赖slf4j-api-1.7.7.jar和logback-core-1.0.13.jar(显式声明这两个关联依赖也可以)
     log4j:
          声明对slf4j-log4j12-1.7.7.jar的依赖即可,会自动关联依赖slf4j-api-1.7.7.jar和log4j-1.2.17.jar
     jdk log:
          声明对slf4j-jdk14-1.7.7.jar的依赖即可,会自动关联依赖slf4j-api-1.7.7.jar
对于工具包项目:
     仅仅依赖slf4j-api即可,让用户自己决定底层用什么实现。
二进制兼容性:
     各个api绑定包,与下面的日志实现包,其版本必须对应。比如slf4j-api-1.7.7.jar应该对应slf4j-simple-1.7.7.jar.
     而上层的应用程序,与其依赖的slf4j-api是各个版本都完全兼容的。
支持MDC,同时需要底层的日志包也支持,例如logback或者log4j。

-----------------------------------------------------------
桥接包:
http://www.slf4j.org/legacy.html
1,从Jakarta Commons Logging (JCL)迁移到slf4j: 用“jcl-over-slf4j.jar”替换掉“commons-logging.jar”即可
     如果在maven中:1,明确的标记exclusion掉common-logging.jar。2,声明common-logging.jar的依赖范围为“provided”(在IED里显示不太好,注意顺序)。
2,很少见的特殊情况,想要把slf4j日志转移到JCL上:用slf4j-jcl.jar包
     ——上述两个包不能一起用,否则死循环(这很好理解)
3,从log4j迁移到slf4j(居然直接针对log4j编码,太2了):用“log4j-over-slf4j.jar”替换掉“log4j.jar”即可。
     ——上述包不能与“slf4j-log4j12.jar”一起用,否则死循环(一样的道理)。
4,从java.util.logging(JUL)迁移到slf4j——jvm自己的类不允许随便替换,所以这里比较复杂(SLF4JBridgeHandler+jul-to-slf4j.jar),而且有性能问题,很少用到,用的时候再研究。
      ——上述包不能与“slf4j-jdk14.jar”一起用,否则死循环(一样的道理)。

SLF4j笔记_第2张图片

转载自http://www.blogjava.net/watchzerg/archive/2014/07/13/415746.html

你可能感兴趣的:(Java)