Log4j 2.x使用注意事项

来源:互联网 发布:肌研洁面泡沫知乎 编辑:程序博客网 时间:2024/05/24 05:35


目录(?)[+]

1、主要组件


a) Logger Hierarchy

log4j 1.x中,各个Logger的层级关系都是通过多个Logger来维护的。在log4j 2.x中这种关系将不复存在,取而代之的LoggerConfig对象之间的关系。Logger和LoggerConfig都是一些被命名了的实体,Logger的名称是大小写区分的,同时遵从如下命名规则:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. 如果一个LoggerConfig的名称加上一个点,是另一个LoggerConfig的名称前缀,那么就说这个LoggerConfig是另一个LoggerConfig的祖先;如果一个LoggerConfig与另一个LoggerConfig之间不存在其它祖先LoggerConfig,那么就说这个LoggerConfig是另一个LoggerConfig的父级。  

举例来说,名称为com.foo的LoggerConfig就是名称为com.foo.Bar的LoggerConfig的父级。类似的,java是java.util的父级,是java.util.Vector的祖先。这种命名模式对大部分开发者来说是相当熟悉的。

但是有一个例外,那就是Root LoggerConfig,在存在于任何一个LoggerConfig层级的顶端。如下代码可以将一个LoggerConfig设置为Root LoggerConfig:
[javascript] view plaincopy在CODE上查看代码片派生到我的代码片
  1. Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);  
  2.   
  3. // 或者  
  4. Logger logger = LogManager.getRootLogger();  

所有的日志器都可以用LogManager.getLogger静态方法通过传递的Logger名称来获取。

b) LoggerContext

在日志系统中,LoggerContext扮演者重要的角色。然而,根据实际情况,一个应用中可能存在多个有效的LoggerContext。

c) Configuaration

每一个LoggerContext都有一个有效的Configuaration,它包含了Appenders、context-wide Filters、LoggerConfigs以及对StrSubstitutor的引用。在重新配置期间,两个Configuaration会同时存在;一旦日志器被重新赋予新的Configuaration,旧的Configuaration就会停止工作并丢弃。具体参见第3部分:配置文件

d) Logger

如前所述,日志器(Logger)通过调用LogManager.getLogger静态方法创建。日志器只是简单的有一个名词,并且与一个LoggerConfig关联。以相同的名称调用LogManager.getLogger方法将得到同一个日志器的引用。例如:
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. Logger x = LogManager.getLogger("wombat");  
  2. Logger y = LogManager.getLogger("wombat");  
  3. System.out.println(x == y); // 打印true  

e) LoggerConfig

f) Filter

g) Appender

h) Layout

i) StrSubstitutor 、StrLookUp

2、jar包引入

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package guwen;  
  2.   
  3. import org.apache.logging.log4j.LogManager;  
  4. import org.apache.logging.log4j.Logger;  
  5.   
  6. public class LogTest {  
  7.       
  8.     private static final Logger log = LogManager.getLogger(LogTest.class);  
  9.       
  10.     public static void main(String[] args) {  
  11.         log.error("Hello, Log4j.");  
  12.         log.info("Hello, Log4j.");}}  
log.debug("Hello, Log4j.") } }

log4j 2.x需要引入两个jar包,分别是log4j-api.jar和log4j-core.jar。执行上面的代码,结果如下:

ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.

15:11:52.731 [main] ERROR guwen.LogTest - Hello, Log4j.

如果没有引入log4j-core.jar,也可以运行,但结果如下:

ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...

ERROR LogTest Hello, Log4j.

3、配置文件

从上面的提示可以看出,只需要引入jar包,即使没有任何配置文件,log4j也能正常工作。但红色部分提示:在没有提供配置的情况下,只会打印错误信息到控制台。

log4j 2.x能够在初始化的时候自动加载配置文件,Log4j2提供了三种ConfiguarationFactory的实现:JSON、YAML、XML。

log4j 2.x的初始化过程为:

(1)log4j会检查log4j.configuarationFile系统属性,如果设置了这个属性,它就会试着去使用与文件扩展对应的ConfiguarationFactory去加载配置。

(2)如果没有log4j.configuarationFile系统属性,YAML ConfiguarationFactory就会试着在classpath中查找log4j2-test.yaml或者log4j2-test.yml;

(3)如果没有找到yaml配置文件,JSON ConfiguarationFactory就会试着在classpath中查找log4j2-test.json或者log4j2-test.jsn;

(4)如果没有找到json配置文件,XML ConfiguarationFactory就会试着在classpath中查找log4j2-test.xml;

(5)如果以上测试环境配置文件都无法找到,YAML ConfiguarationFactory就会试着在classpath中查找log4j2.yaml或者log4j2.yml;

(6)如果没有找到yaml配置文件,JSON ConfiguarationFactory就会试着在classpath中查找log4j2.json或者log4j2.jsn;

(7)如果没有找到json配置文件,XML ConfiguarationFactory就会试着在classpath中查找log4j2.xml;

(8)如果没有找到任何配置文件,log4j将会使用DefaultConfiguaration,这会导致日志被输出到控制台。

经过测试,所谓的log4j.configuarationFile属性,以键值对的方式保存在classpath下的log4j2.component.properties属性文件中,它的取值是指定的配置文件名。

4、日志级别

在第2部分就已经看到,不提供任何配置时,log4j也能以默认的配置输出正常日志信息。以xml配置为例,实际上默认的配置等价于以下配置文件的配置:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  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="error">  
  10.       <AppenderRef ref="Console"/>  
  11.     </Root>  
  12.   </Loggers>  
  13. </Configuration>  

将这个文件以log4j2.xml命名,并放置于src目录下,再次执行上面的代码,得到如下结果:

19:53:14.646 [main] ERROR guwen.LogTest - Hello, Log4j.

可以看出,打印结果并没有太大的变化,只是没有了找不到配置文件的提示信息。但是因为默认配置中日志级别是ERROR,所以还是只打印了Logger.error的执行结果。修改配置中的Root节点的level属性为info,再次执行代码,得到结果如下:

19:56:33.904 [main] ERROR guwen.LogTest - Hello, Log4j.19:56:33.905 [main] INFO  guwen.LogTest - Hello, Log4j.

再次修改level属性为debug,执行代码,得到结果如下:

19:57:38.704 [main] ERROR guwen.LogTest - Hello, Log4j.19:57:38.705 [main] DEBUG guwen.LogTest - Hello, Log4j.19:57:38.705 [main] INFO  guwen.LogTest - Hello, Log4j.

实际上log4j包含7个日志级别:

  1. 关闭:OFF(0)
  2. 致命:FATAL(100),对应Logger.fatal方法
  3. 错误:ERROR(200),对应Logger.error方法
  4. 警告:WARN(300),对应Logger.warn方法
  5. 信息:INFO(400),对应Logger.info方法
  6. 调试:DEBUG(500),对应Logger.debug方法
  7. 跟踪:TRACE(600),对应Logger.trace方法
  8. 全部:ALL(Integer.MAX_VALUE)
当指定某一个级别时,比如DEBUG,那么所有低于这个级别的其它级别日志,都会被打印。当指定级别为DEBUG时,Logger.debug、Logger.info、Logger.warn、Logger.error以及Logger.fatal等方法都能输出日志,但Logger.trace无法输出日志。

目录(?)[+]

1、主要组件

a) Logger Hierarchy

log4j 1.x中,各个Logger的层级关系都是通过多个Logger来维护的。在log4j 2.x中这种关系将不复存在,取而代之的LoggerConfig对象之间的关系。Logger和LoggerConfig都是一些被命名了的实体,Logger的名称是大小写区分的,同时遵从如下命名规则:
[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. 如果一个LoggerConfig的名称加上一个点,是另一个LoggerConfig的名称前缀,那么就说这个LoggerConfig是另一个LoggerConfig的祖先;如果一个LoggerConfig与另一个LoggerConfig之间不存在其它祖先LoggerConfig,那么就说这个LoggerConfig是另一个LoggerConfig的父级。  
举例来说,名称为com.foo的LoggerConfig就是名称为com.foo.Bar的LoggerConfig的父级。类似的,java是java.util的父级,是java.util.Vector的祖先。这种命名模式对大部分开发者来说是相当熟悉的。
但是有一个例外,那就是Root LoggerConfig,在存在于任何一个LoggerConfig层级的顶端。如下代码可以将一个LoggerConfig设置为Root LoggerConfig:
[javascript] view plaincopy在CODE上查看代码片派生到我的代码片
  1. Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);  
  2.   
  3. // 或者  
  4. Logger logger = LogManager.getRootLogger();  
所有的日志器都可以用LogManager.getLogger静态方法通过传递的Logger名称来获取。

b) LoggerContext

在日志系统中,LoggerContext扮演者重要的角色。然而,根据实际情况,一个应用中可能存在多个有效的LoggerContext。

c) Configuaration

每一个LoggerContext都有一个有效的Configuaration,它包含了Appenders、context-wide Filters、LoggerConfigs以及对StrSubstitutor的引用。在重新配置期间,两个Configuaration会同时存在;一旦日志器被重新赋予新的Configuaration,旧的Configuaration就会停止工作并丢弃。具体参见第3部分:配置文件

d) Logger

如前所述,日志器(Logger)通过调用LogManager.getLogger静态方法创建。日志器只是简单的有一个名词,并且与一个LoggerConfig关联。以相同的名称调用LogManager.getLogger方法将得到同一个日志器的引用。例如:
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. Logger x = LogManager.getLogger("wombat");  
  2. Logger y = LogManager.getLogger("wombat");  
  3. System.out.println(x == y); // 打印true  

e) LoggerConfig

f) Filter

g) Appender

h) Layout

i) StrSubstitutor 、StrLookUp

2、jar包引入

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package guwen;  
  2.   
  3. import org.apache.logging.log4j.LogManager;  
  4. import org.apache.logging.log4j.Logger;  
  5.   
  6. public class LogTest {  
  7.       
  8.     private static final Logger log = LogManager.getLogger(LogTest.class);  
  9.       
  10.     public static void main(String[] args) {  
  11.         log.error("Hello, Log4j.");  
  12.         log.info("Hello, Log4j.");}}  
log.debug("Hello, Log4j.") } }

log4j 2.x需要引入两个jar包,分别是log4j-api.jar和log4j-core.jar。执行上面的代码,结果如下:

ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.

15:11:52.731 [main] ERROR guwen.LogTest - Hello, Log4j.

如果没有引入log4j-core.jar,也可以运行,但结果如下:

ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...

ERROR LogTest Hello, Log4j.

3、配置文件

从上面的提示可以看出,只需要引入jar包,即使没有任何配置文件,log4j也能正常工作。但红色部分提示:在没有提供配置的情况下,只会打印错误信息到控制台。

log4j 2.x能够在初始化的时候自动加载配置文件,Log4j2提供了三种ConfiguarationFactory的实现:JSON、YAML、XML。

log4j 2.x的初始化过程为:

(1)log4j会检查log4j.configuarationFile系统属性,如果设置了这个属性,它就会试着去使用与文件扩展对应的ConfiguarationFactory去加载配置。

(2)如果没有log4j.configuarationFile系统属性,YAML ConfiguarationFactory就会试着在classpath中查找log4j2-test.yaml或者log4j2-test.yml;

(3)如果没有找到yaml配置文件,JSON ConfiguarationFactory就会试着在classpath中查找log4j2-test.json或者log4j2-test.jsn;

(4)如果没有找到json配置文件,XML ConfiguarationFactory就会试着在classpath中查找log4j2-test.xml;

(5)如果以上测试环境配置文件都无法找到,YAML ConfiguarationFactory就会试着在classpath中查找log4j2.yaml或者log4j2.yml;

(6)如果没有找到yaml配置文件,JSON ConfiguarationFactory就会试着在classpath中查找log4j2.json或者log4j2.jsn;

(7)如果没有找到json配置文件,XML ConfiguarationFactory就会试着在classpath中查找log4j2.xml;

(8)如果没有找到任何配置文件,log4j将会使用DefaultConfiguaration,这会导致日志被输出到控制台。

经过测试,所谓的log4j.configuarationFile属性,以键值对的方式保存在classpath下的log4j2.component.properties属性文件中,它的取值是指定的配置文件名。

4、日志级别

在第2部分就已经看到,不提供任何配置时,log4j也能以默认的配置输出正常日志信息。以xml配置为例,实际上默认的配置等价于以下配置文件的配置:

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  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="error">  
  10.       <AppenderRef ref="Console"/>  
  11.     </Root>  
  12.   </Loggers>  
  13. </Configuration>  

将这个文件以log4j2.xml命名,并放置于src目录下,再次执行上面的代码,得到如下结果:

19:53:14.646 [main] ERROR guwen.LogTest - Hello, Log4j.

可以看出,打印结果并没有太大的变化,只是没有了找不到配置文件的提示信息。但是因为默认配置中日志级别是ERROR,所以还是只打印了Logger.error的执行结果。修改配置中的Root节点的level属性为info,再次执行代码,得到结果如下:

19:56:33.904 [main] ERROR guwen.LogTest - Hello, Log4j.
19:56:33.905 [main] INFO  guwen.LogTest - Hello, Log4j.

再次修改level属性为debug,执行代码,得到结果如下:

19:57:38.704 [main] ERROR guwen.LogTest - Hello, Log4j.
19:57:38.705 [main] DEBUG guwen.LogTest - Hello, Log4j.
19:57:38.705 [main] INFO  guwen.LogTest - Hello, Log4j.

实际上log4j包含7个日志级别:

  1. 关闭:OFF(0)
  2. 致命:FATAL(100),对应Logger.fatal方法
  3. 错误:ERROR(200),对应Logger.error方法
  4. 警告:WARN(300),对应Logger.warn方法
  5. 信息:INFO(400),对应Logger.info方法
  6. 调试:DEBUG(500),对应Logger.debug方法
  7. 跟踪:TRACE(600),对应Logger.trace方法
  8. 全部:ALL(Integer.MAX_VALUE)
当指定某一个级别时,比如DEBUG,那么所有低于这个级别的其它级别日志,都会被打印。当指定级别为DEBUG时,Logger.debug、Logger.info、Logger.warn、Logger.error以及Logger.fatal等方法都能输出日志,但Logger.trace无法输出日志。


0 0
原创粉丝点击