文章目录
  1. 1. 各种log框架
    1. 1.1. log4j1和log4j2
    2. 1.2. 各种jar包总结
  2. 2. jcl与日志框架的集成
    1. 2.1. jul
    2. 2.2. log4j1
    3. 2.3. log4j2
    4. 2.4. logback
  3. 3. slf4j与日志框架的集成
    1. 3.1. jul
    2. 3.2. log4j1
    3. 3.3. log4j2
    4. 3.4. logback
  4. 4. 总结
    1. 4.1. 问题
  5. 5. 日志最佳实践
  6. 6. 参考

虽然之前已经介绍过Java中的log,但是目前使用的过程中依然傻傻分不清,决定再次整理和介绍一下。

各种log框架

实际项目中我们经常可以看到log4j、logback、slf4j等框架的身影,对于这些乱七八糟的log框架大致可以分为两个种类:

日志框架:jdk自带的logging(jul),log4j1、log4j2、logback

用于实现日志统一的框架: apache的commons-logging(jcl)、slf4j

log4j1和log4j2

log4j2与log4j1发生了很大的变化,不兼容。log4j1仅仅作为一个实际的日志框架,slf4j、commons-logging作为门面,统一各种日志框架的混乱格局,现在log4j2也想跳出来充当门面了,也想统一大家了。

log4j2分成2个部分:

  1. log4j-api: 作为日志接口层,用于统一底层日志系统
  2. log4j-core : 作为上述日志接口的实现,是一个实际的日志框架

各种jar包总结

log4j1:

  1. log4j:log4j1的全部内容

log4j2:

  1. log4j-api:log4j2定义的API
  2. log4j-core:log4j2上述API的实现

logback:

  1. logback-core:logback的核心包
  2. logback-classic:logback实现了slf4j的API

commons-logging:

  1. commons-logging:commons-logging的原生全部内容
  2. log4j-jcl:commons-logging到log4j2的桥梁
  3. jcl-over-slf4j:commons-logging到slf4j的桥梁

slf4j转向某个实际的日志框架:

场景介绍:如 使用slf4j的API进行编程,底层想使用log4j1来进行实际的日志输出,这就是slf4j-log4j12干的事。

  1. slf4j-jdk14:slf4j到jdk-logging的桥梁
  2. slf4j-log4j12:slf4j到log4j1的桥梁
  3. log4j-slf4j-impl:slf4j到log4j2的桥梁
  4. logback-classic:slf4j到logback的桥梁
  5. slf4j-jcl:slf4j到commons-logging的桥梁

某个实际的日志框架转向slf4j

场景介绍:如 使用log4j1的API进行编程,但是想最终通过logback来进行输出,所以就需要先将log4j1的日志输出转交给slf4j来输出,slf4j再交给logback来输出。将log4j1的输出转给slf4j,这就是log4j-over-slf4j做的事。这一部分主要用来进行实际的日志框架之间的切换。

  1. jul-to-slf4j:jdk-logging到slf4j的桥梁
  2. log4j-over-slf4j:log4j1到slf4j的桥梁
  3. jcl-over-slf4j:commons-logging到slf4j的桥梁

jcl与日志框架的集成

private static Log logger=LogFactory.getLog(Test.class);

jul

需要jar包

  1. commons-logging

log4j1

需要jar包

  1. commons-logging
  2. log4j

log4j2

需要jar包

  1. commons-logging
  2. log4j-api (log4j2的API包)
  3. log4j-core (log4j2的API实现包)
  4. log4j-jcl (log4j2与commons-logging的集成包)

logback

需要jar包

  1. jcl-over-slf4j (替代了commons-logging)
  2. slf4j-api
  3. logback-core
  4. logback-classic

logback本身的使用其实就和slf4j绑定了起来,现在要想指定commons-logging的底层log实现是logback,则需要2步走

  1. 先将commons-logging底层的log实现转向slf4j (jcl-over-slf4j干的事)
  2. 再根据slf4j的选择底层日志原理,我们使之选择上logback

slf4j与日志框架的集成

private static Logger logger=LoggerFactory.getLogger(Test.class);

jul

需要jar包

  1. slf4j-api
  2. slf4j-jdk14

log4j1

需要jar包

  1. slf4j-api
  2. slf4j-log4j12
  3. log4j

log4j2

需要jar包

  1. slf4j-api
  2. log4j-api
  3. log4j-core
  4. log4j-slf4j-impl (用于log4j2与slf4j集成)

logback

需要jar包

  1. slf4j-api
  2. logback-core
  3. logback-classic(已含有对slf4j的集成包)

总结

由上面我们可以发现一个完整的Log日志主要包括如下三个部分:

  1. 接口:sfl4j-api-xxx.jar
  2. 实现,也就是具体的日志框架:log4-xxx.jar、logback等
  3. 适配层:slf4j-log4j12-xxx.jar

问题

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

如果启动应用/程序的时候,报这样的错。那说明上面提到的sfl4j-log4j12没有依赖。需要在pom.xml显式的引入。

日志最佳实践

  1. 检查日志是否可以被记录

     if (LOGGER.isDebugEnabled()) { 
            LOGGER.debug("This is a message."); 
        }
    作用在于避免了构造日志记录消息所带来的开销。日志消息中通常包含与当前上下文相关的信息。为了获取这些信息并构造相应的消息文本,不可避免会产生额外的开销。因此在记录 INFO、DEBUG 和 TRACE 级别的日志时,首先进行相应的检查是一个好的实践。而 WARN 及其以上级别的日志则一般不需要进行检查。
    
  2. 日志中包含充分的信息。保证可读性,需记录现场信息,如当前处理id等

  3. 绝不要打印没有用的日志,防止无用日志淹没重要信息
  4. 日志格式要统一规范
  5. 用log.error表示系统级错误(不可预测);用log.warn表示应用级错误(可预测);服务初始化或结束用log.info;用log.warn(“”,e)替代e.printstack

参考

  1. jdk-logging、log4j、logback日志介绍及原理
  2. java日志系统指南
  3. Java 日志管理最佳实践
  4. 王健:最佳日志实践
文章目录
  1. 1. 各种log框架
    1. 1.1. log4j1和log4j2
    2. 1.2. 各种jar包总结
  2. 2. jcl与日志框架的集成
    1. 2.1. jul
    2. 2.2. log4j1
    3. 2.3. log4j2
    4. 2.4. logback
  3. 3. slf4j与日志框架的集成
    1. 3.1. jul
    2. 3.2. log4j1
    3. 3.3. log4j2
    4. 3.4. logback
  4. 4. 总结
    1. 4.1. 问题
  5. 5. 日志最佳实践
  6. 6. 参考