Java 日志组件(二)

3、log4j2

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

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

  3.1、maven依赖

 1 <dependency>
 2     <groupId>org.apache.logging.log4j</groupId>
 3     <artifactId>log4j-api</artifactId>
 4     <version>2.2</version>
 5 </dependency>
 6 <dependency>
 7     <groupId>org.apache.logging.log4j</groupId>
 8     <artifactId>log4j-core</artifactId>
 9     <version>2.2</version>
10 </dependency>

  3.2、使用方式

    • 编写log4j2.xml配置文件(目前log4j2只支持xml、json、yuml,不再支持properties)
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <Configuration status="WARN">
 3   <Appenders>
 4     <Console name="Console" target="SYSTEM_OUT">
 5       <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
 6     </Console>
 7   </Appenders>
 8   <Loggers>
 9     <Root level="debug">
10       <AppenderRef ref="Console"/>
11     </Root>
12   </Loggers>
13 </Configuration>
    • 使用
 1 private static final Logger logger=LogManager.getLogger(Log4j2Test.class);
 2
 3 public static void main(String[] args){
 4     if(logger.isTraceEnabled()){
 5         logger.debug("log4j trace message");
 6     }
 7     if(logger.isDebugEnabled()){
 8         logger.debug("log4j debug message");
 9     }
10     if(logger.isInfoEnabled()){
11         logger.debug("log4j info message");
12     }
13 }

    和log4j不同的是此时的Logger是log4j-api中定义的接口,而log4j中的Logger是类

  3.3、使用过程简单分析

    • 获取底层使用的LoggerContextFactory

        同样LogManager的类加载会去寻找log4j-api定义的LoggerContextFactory接口的底层实现,获取方式有三种

      • 尝试从jar中寻找log4j2.component.properties文件,如果配置了log4j2.loggerContextFactory则使用该LoggerContextFactory。
      • 如果没找到,尝试从jar包中寻找META-INF/log4j-provider.properties文件,如log4j-core-2.2中就有该文件。
      • 如果找到多个,取优先级最高的(该文件中指定了LoggerContextFactory,同时指定了优先级FactoryPriority),如log4j-core-2.2中log4j-provider.properties的文件内容如下 
1 LoggerContextFactory = org.apache.logging.log4j.core.impl.Log4jContextFactory
2 Log4jAPIVersion = 2.1.0
3 FactoryPriority= 10
      • 上述方式还没找到,就使用默认的SimpleLoggerContextFactory
    • 使用LoggerContextFactory获取LoggerContext
    • 根据LoggerContext获取Logger
      • 会首先判断LoggerContext是否被初始化过了,没有则进行初始化
      • 获取ConfigurationFactory,从配置中获取和插件中获取(log4j-core核心包中有三个YamlConfigurationFactory、JsonConfigurationFactory、XmlConfigurationFactory)
      • 以上文的案例中,会使用XmlConfigurationFactory来加载log4j2.xml配置文件
      • LoggerContext初始化后,就可以获取或者创建Logger了

  3.4、主要对象总结

    • LogManager: 它的类加载会去寻找LoggerContextFactory接口的底层实现,会从jar包中的配置文件中寻找,如上面所述
    • LoggerContextFactory : 用于创建LoggerContext,不同的日志实现系统会有不同的实现,如log4j-core中的实现为Log4jContextFactory
    • PropertyConfigurator: 用于解析log4j.properties文件
    • LoggerContext : 它包含了配置信息,并能创建log4j-api定义的Logger接口实例,并缓存这些实例
    • ConfigurationFactory:上述LoggerContext解析配置文件,需要用到ConfigurationFactory,目前有三个YamlConfigurationFactory、JsonConfigurationFactory、XmlConfigurationFactory,分别解析yuml json xml形式的配置文件

4、logback

    • logback-core
    • logback-classic
    • slf4j-api

  4.1、对应maven的依赖

 1 <dependency>
 2     <groupId>ch.qos.logback</groupId>
 3     <artifactId>logback-core</artifactId>
 4     <version>1.1.3</version>
 5 </dependency>
 6 <dependency>
 7     <groupId>ch.qos.logback</groupId>
 8     <artifactId>logback-classic</artifactId>
 9     <version>1.1.3</version>
10 </dependency>
11 <dependency>
12     <groupId>org.slf4j</groupId>
13     <artifactId>slf4j-api</artifactId>
14     <version>1.7.12</version>
15 </dependency>

  4.2、使用

 1 private static final Logger logger=LoggerFactory.getLogger(LogbackTest.class);
 2
 3 public static void main(String[] args){
 4     if(logger.isDebugEnabled()){
 5         logger.debug("slf4j-logback debug message");
 6     }
 7     if(logger.isInfoEnabled()){
 8         logger.debug("slf4j-logback info message");
 9     }
10     if(logger.isTraceEnabled()){
11         logger.debug("slf4j-logback trace message");
12     }
13
14     LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
15     StatusPrinter.print(lc);
16 }
    • 官方使用方式,其实就和slf4j集成了起来

      上述的Logger、LoggerFactory都是slf4j自己的接口与类

    • 没有配置文件的情况下,使用的是默认配置。搜寻配置文件的过程如下:
1 Logback tries to find a file called logback.groovy in the classpath.
2 If no such file is found, logback tries to find a file called logback-test.xml in the classpath.
3 If no such file is found, it checks for the file logback.xml in the classpath..
4 If no such file is found, and the executing JVM has the ServiceLoader (JDK 6 and above) the ServiceLoader will be used to resolve an implementation of com.qos.logback.classic.spi.Configurator. The first implementation found will be used. See ServiceLoader documentation for more details
5 If none of the above succeeds, logback configures itself automatically using the BasicConfigurator which will cause logging output to be directed to the console.
6 The fourth and last step is meant to provide a default (but very basic) logging functionality in the absence of a configuration file

  也可以在类路径上加一个类似如下的logback.xml的配置文件,logback则会去解析对应的配置文件。

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <configuration>
 3
 4   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
 5     <encoder>
 6       <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
 7     </encoder>
 8   </appender>
 9
10   <root level="DEBUG">
11     <appender-ref ref="STDOUT" />
12   </root>
13
14 </configuration>

  4.3、使用过程简单分析

    • slf4j与底层的日志系统进行绑定在jar包中寻找org/slf4j/impl/StaticLoggerBinder.class 这个类,如在logback-classic中就含有这个类,如果找到多个StaticLoggerBinder,则表明目前底层有多个实际的日志框架,slf4j会随机选择一个。
    • 使用上述找到的StaticLoggerBinder创建一个实例,并返回一个LoggerFactory实例:
1 return StaticLoggerBinder.getSingleton().getLoggerFactory()

      以logback-classic中的StaticLoggerBinder为例,在StaticLoggerBinder.getSingleton()过程中:会去加载解析配置文件 源码如下

 1 public URL findURLOfDefaultConfigurationFile(boolean updateStatus) {
 2     ClassLoader myClassLoader = Loader.getClassLoaderOfObject(this);
 3     //寻找logback.configurationFile的系统属性
 4     URL url = findConfigFileURLFromSystemProperties(myClassLoader, updateStatus);
 5     if (url != null) {
 6       return url;
 7     }
 8     //寻找logback.groovy
 9     url = getResource(GROOVY_AUTOCONFIG_FILE, myClassLoader, updateStatus);
10     if (url != null) {
11       return url;
12     }
13     //寻找logback-test.xml
14     url = getResource(TEST_AUTOCONFIG_FILE, myClassLoader, updateStatus);
15     if (url != null) {
16       return url;
17     }
18     //寻找logback.xml
19     return getResource(AUTOCONFIG_FILE, myClassLoader, updateStatus);
20 }

    目前路径都是定死的,只有logback.configurationFile的系统属性是可以更改的,所以如果我们想更改配置文件的位置(不想放在类路径下),则需要设置这个系统属性:

1 System.setProperty("logback.configurationFile", "/path/to/config.xml");

    解析完配置文件后,返回的LoggerFactory实例的类型是LoggerContext(它包含了配置信息)

    • 根据返回的LoggerFactory实例,来获取Logger就是根据上述的LoggerContext来创建一个Logger,每个logger与LoggerContext建立了关系,并放到LoggerContext的缓存中,就是LoggerContext的如下属性:
1 private Map<String, Logger> loggerCache;

    其实上述过程就是slf4j与其他日志系统的绑定过程。不同的日志系统与slf4j集成,都会有一个StaticLoggerBinder类,并会拥有一个LoggerFactory的实现。

    

原文地址:https://www.cnblogs.com/ouhouki/p/10103987.html

时间: 2024-12-17 22:39:49

Java 日志组件(二)的相关文章

Java日志组件logback使用:加载非类路径下的配置文件并设置定时更新

Java日志组件logback使用:加载非类路径下的配置文件并设置定时更新 摘自: https://blog.csdn.net/johnson_moon/article/details/78874499 2017年12月22日 16:20:29 阅读数:868 标签: javalogback日志配置文件logback-xm 更多 个人分类: Java日志 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/johnson_moon/article/d

2015第30周四Java日志组件

Java 日志 API 从功能上来说,日志 API 本身所需求的功能非常简单,只需要能够记录一段文本即可.API 的使用者在需要进行记录时,根据当前的上下文信息构造出相应的文本信息,调用 API 完成记录.一般来说,日志 API 由下面几个部分组成: 记录器(Logger):日志 API 的使用者通过记录器来发出日志记录请求,并提供日志的内容.在记录日志时,需要指定日志的严重性级别.当 程序中需要记录日志时,首先需要获取一个日志记录器对象.一般的日志记录 API 都提供相应的工厂方法来创建记录器

【转】java日志组件介绍(common-logging,log4j,slf4j,logback )

common-logging common-logging是apache提供的一个通用的日志接口.用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的logging, common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库.当然,common-logging内部有一个Simple logger的简单实现,但是功能很弱.所以使用common-logging,通常都是配合着log4j来使用.使用它的好处就是,代码依赖是common-loggin

java日志组件介绍(common-logging,log4j,slf4j,logback )

common-logging common-logging是 apache提供的一个通用的日志接口.用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的logging, common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库.当然,common-logging内部有一个Simple logger的简单实现,但是功能很弱.所以使用common-logging,通常都是配合着log4j来使用.使用它的好处就是,代码依赖是 common-logg

java日志组件介绍(common-logging,log4j,slf4j,logback)

common-logging common-logging是apache提供的一个通用的日志接口.用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的logging, common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库.当然,common-logging内部有一个Simple logger的简单实现,但是功能很弱.所以使用common-logging,通常都是配合着log4j来使用.使用它的好处就是,代码依赖是common-loggin

转:java日志组件介绍(common-logging,log4j,slf4j,logback )

原网址:http://www.blogjava.net/daiyongzhi/archive/2014/04/13/412364.html common-logging common-logging是apache提供的一个通用的日志接口.用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的logging, common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库.当然,common-logging内部有一个Simple logger的简单实现

java日志组件的那些破事

由于现在开源框架日益丰富,好多开源框架使用的日志组件不尽相同.存在着在一个项目中,不同的版本,不同的框架共存.     其中有一些标准通用接口,标准实现,各种桥接器的存在,下面就让笔者树立一下这些框架之间的关系.  slf4J与旧日志框架的关系 slf4j等于commons-logging,是各种日志实现的通用入口,会根据classpath中存在下面哪一个Jar来决定具体的日志实现库. logback-classic(默认的logback实现) slf4j-jcl.jar(apache comm

JAVA日志库

一.常用日志Jar关系 2015第30周四Java日志组件 接口:将所有日志实现适配到了一起,用统一的接口调用. 实现:目前主流的日志实现 旧日志到slf4j的适配器:如果使用了slf4j,但是只想用一种实现,想把log4j的日志体系也从logback输出,这个是很有用的. slf4j到实现的适配器:如果想制定slf4j的具体实现,需要这些包. slf4J与旧日志框架的关系 slf4j等于commons-logging,是各种日志实现的通用入口,会根据classpath中存在下面哪一个Jar来决

Java日志记录的事儿

一.java日志组件 1.common-logging common-logging是apache提供的一个通用的日志接口.用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的logging, common-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库.但由于它使用了ClassLoader寻找和载入底层的日 志库, 导致了象OSGI这样的框架无法正常工作,由于其不同的插件使用自己的ClassLoader. OSGI的这种机制保证了插件互相独立,