Java logging framework --JCL (Jakarta Commons Logging)

JCL, called the "Jakarta Commons Logging", also known as "Apache Commons Logging", is a common log API Apache provides. JCL using design mode "adapter mode", which is a unified interface "All Java logging achieve" provided, then the class will be operating in the adaptation entrusted to specific logging framework logs, it itself It provides an implementation of a log , but is very weak ( SimpleLog ). It is generally not use it alone. It allows developers to use different tools to achieve specific log: Log4j, jdk own log (JUL)

There are two basic JCL abstract class: Log (basic recorder) and LogFactory (responsible for creating Log instances)

Log inheritance system shown in Figure 1:

LogFactory inheritance system shown in Figure 2:

Log4JLogger, Jdk14Logger and so is adaptation class.

In Log4JLogger class contains "org.apache.log4j.Logger" type, i.e. in Log4J Logger class, method of operation and thus call log Log4JLogger class will be delegated to "org.apache.log4j.Logger" Class run
in Jdk14Logger class contains "java.util.logging.Logger" categories, namely Java logging API in the Logger class, which calls for logging method of operation Jdk14Logger class will be entrusted to the "java.util.logging. Logger "class run

"Jcl and jul, log4j1, log4j2, logback integration": https://jybzjf.iteye.com/blog/2238792
"Commons-Logging Detailed existing ClassLoader problem": https://yq.aliyun.com/articles/46888

A, JCL entry

JCL + Java Logging API project to build:

1. Build maven project: JCL jar package

<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>

2. Create TestDemo: JCL interface no other logging implementations, the native jdk will automatically log (JUL)

  @Test
    public void testQuick() throws Exception{
//        获取log日志记录器对象
        Log log = LogFactory.getLog(JCLTest.class);
//        日志记录输出
        log.info("hello jcl");
    }

JCL + Log4J project to build:

1. JCL interface log4j log

First, add a jar package log4j logs implemented in the Maven project

        <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

The contents of the configuration file and log4j.properties commons-logging.properties 2. Then the two files created

log4j.properties configuration file as follows:

#配置根  Loggers控制日志的输出级别与日志是否输出
log4j.rootLogger=trace,console

#配置输出到控制台  Appenders是指定日志的输出方式
log4j.appender.console=org.apache.log4j.ConsoleAppender
#指定输出控制台
log4j.appender.console.Target = System.out
#指定布局,输出日志的格式
log4j.appender.console.layout=org.apache.log4j.PatternLayout
#指定布局的参数
log4j.appender.console.layout.ConversionPattern=[%-10p] %r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n

commons-logging.properties configuration file as follows:

org.apache.commons.logging.Log = org.apache.commons.logging.impl.Log4JLogger

3. Finally Demo test, JCL calls log4j achieve, be achieved log4j logging

  @Test
    public void testQuick() throws Exception{
//        获取log日志记录器对象
        Log log = LogFactory.getLog(JCLTest.class);
//        日志记录输出
        log.info("hello jcl");
    }

commons-logging achieve binding log

LogFactory.getLog (JclTest.class) source as follows:

public static Log getLog(Class clazz) throws LogConfigurationException {
    return getFactory().getInstance(clazz);
}

Log of the acquired process is roughly divided into two stages

  • Get LogFactory process (literally Log is the production plant). commons-logging LogFactory default implementation provided by: LogFactoryImpl
  • Log acquisition process according to LogFactory. commons-logging implementation provides a default Log: Jdk14Logger, Log4JLogger, SimpleLog.

Probably look at the contents of commons-logging package:

Second, why should we use log facade

1. for interface development, no longer dependent on a specific category. Reduce coupling code

2. project implementation class by introducing different log, the log can flexibly switch the frame

3. unified API, enabling developers to easily learn and use

4. facilitate unified configuration management project log

Three, JCL principle

1. Log implementation class dynamic loading LogFactory

2.1 LogFactory of the acquisition process

LogFactory several ways to get from below

(1) the attribute acquisition system

System.getProperty("org.apache.commons.logging.LogFactory")

(2) using the SPI mechanism java

SPI mechanism for java, the details can search on their own, will not be described here. Search paths are as follows:

META-INF/services/org.apache.commons.logging.LogFactory

Search is simply jar which contains the package contains the search file corresponding to the specified achieve LogFactory

(3) from the commons-logging configuration file

commons-logging also can have its own configuration file, named commons-logging.properties, but currently the most part, we do not have to use it. If the configuration file, attempts to read the attribute "org.apache.commons.logging.LogFactory" from a value corresponding to the configuration file

(4) 默认的 org.apache.commons.logging.impl.LogFactoryImpl

LogFactoryImpl 是 commons-logging 提供的默认实现

2.2根据 LogFactory 获取 Log 的过程

这时候就需要寻找底层是选用哪种类型的日志

就以 commons-logging 提供的默认实现为例,来详细看下这个过程:

(1) 从 commons-logging 的配置文件中寻找 Log 实现类的类名

从commons-logging.properties 配置文件中寻找属性为 "org.apache.commons.logging.Log" 对应的 Log 类名

(2) 从系统属性中寻找 Log 实现类的类名

System.getProperty("org.apache.commons.logging.Log")

(3) 如果上述方式没找到,则从 classesToDiscover 属性中寻找

classesToDiscover 属性值如下:

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"
};

3.获取具体的日志实现,通过查看源代码可以发现,执行"LogFactory.getLog(Main.class)"语句的时候,最终是执行LogFactoryImp类中的discoverLogImplementation方法,在该方法中有如下代码语句:

for(int i = 0; i < classesToDiscover.length && result == null; ++i)
 {
        result = this.createLogFromClass(classesToDiscover[i], logCategory, true);
}

它会尝试根据上述类名,依次进行创建,如果能创建成功,则使用该 Log,然后返回给用户。

发布了17 篇原创文章 · 获赞 11 · 访问量 8000

Guess you like

Origin blog.csdn.net/LOVE_Me__/article/details/104286506