java日志框架原理(一)

日志代理框架

常用的一些日志工具

一般打日志,有许多种选择,像slf4j, log4j, logback, jul(java.util.logging.Logger), SimpleLog(System.err), commons-logging等。这些大致可以分为两类,代理类和工具类,其中代理类为slf4j和commons-logging,其它的为工具类。其中代理类不负责具体的日志打印,实际打印的工作由工具类来完成,代理类负责日志框架的设计

commons-logging

可配置LogFactory的实现类,来做logger的选择,其中实现类的查找顺序为(具体可见方法LogFactory.getFactory):

  1. 环境变量中的org.apache.commons.logging.LogFactory值
  2. META-INF/services/org.apache.commons.logging.LogFactory文件中的第一行(例如jcl-over-slf4j中就是用的此种方式桥接的)
  3. commons-logging.properties配置文件中的org.apache.commons.logging.LogFactory的值

默认实现为org.apache.commons.logging.impl.LogFactoryImpl,其查找logger的顺序为(具体可见方法LogFactoryImpl.discoverLogImplementation)

  1. 查找用户自定义的log实现类,查找顺序为commons-logging.properties中的org.apache.commons.logging.Log,commons-logging.properties中的org.apache.commons.logging.log,环境变量中的org.apache.commons.logging.Log,环境变量中的org.apache.commons.logging.log
  2. 按顺序查找几个默认实现类,相关代码如下
private static final String[] classesToDiscover = {
        “org.apache.commons.logging.impl.Log4JLogger”,
        "org.apache.commons.logging.impl.Jdk14Logger",
        "org.apache.commons.logging.impl.Jdk13LumberjackLogger",
        "org.apache.commons.logging.impl.SimpleLog"
};
for(int i=0; i

其中Log4JLogger里面就是代理的log4j中的org.apache.log4j.Logger
Jdk14Logger和Jdk13LumberjackLogger就是代理的java.util.logging.Logger
其UML为
java日志框架原理(一)_第1张图片

slf4j

可定义org.slf4j.impl.StaticLoggerBinder类在桥接的jar中,来设置ILoggerFactory的实现类来配置具体的logger(系统中经常会扫描到多个StaticLoggerBinder,具体对于实现类的选择可见LoggerFactory.bind),一般把StaticLoggerBinder和ILoggerFactory实现类放在名字带jcl的jar中,而工具类作为jcl的依赖
其UML为
java日志框架原理(一)_第2张图片

使用log4j依赖组合方式(logback或者其它的方式类似)

  1. 直接用log4j的方式,这时候我们只需要引入log4j.jar即可
org.apache.log4j.Logger log4j = org.apache.log4j.LogManager.getLogger("name");
log4j.info("test");
  1. 用commons-logging代理一遍,此时需要引入log4j.jar和commons-logging.jar
org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog("name");
log.info("test");
  1. 用slf4j代理一遍,此时需要引入log4j.jar, slf4j-api.jar, slf4j-log4j12.jar
org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger("name");
logger.info("test");

当然还可以尝试由commons-logging先代理一遍再slf4j丙代理一遍,最后用log4j打印,或者反过来都得,只是需要增加几个jcl的桥接jar

你可能感兴趣的:(java,java基础)