log4j2的详解和使用

使用log4j 2基本只需导入两个jar包:

log4j-core-xx.jar     log4j-api-xx.jar

 

log4j 2.0与以往的1.x有一个明显的不同,其配置文件只能采用.xml, .json或者 .jsn。在默认情况下,系统选择configuration文件的优先级如下:(classpath为scr文件夹)

1.classpath下名为 log4j-test.json 或者log4j-test.jsn文件

2.classpath下名为 log4j2-test.xml

3.classpath下名为 log4j.json 或者 log4j.jsn文件

4.classpath下名为 log4j2.xml

必须注意.xml 文件的文件名为log4j2
使用log4j 2.0,需要用LogManager的getLogger函数获取一个logger,就可以使用logger记录日志。
Xml代码   收藏代码
  1. xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <Configuration status="off" monitorInterval="1800">  
  4.   
  5.     <properties>  
  6.         <property name="LOG_HOME">logs/sampleproperty>  
  7.         <property name="FILE_NAME">mylogproperty>  
  8.     properties>  
  9.   
  10.     <Appenders>  
  11.           
  12.         <Console name="Console" target="SYSTEM_OUT">  
  13.             <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />  
  14.         Console>  
  15.   
  16.         <RollingRandomAccessFile name="running-log"  
  17.             fileName="${LOG_HOME}/${FILE_NAME}.log" filePattern="${LOG_HOME}/  
  18.                            $${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd}-%i.log.gz">  
  19.             <PatternLayout  
  20.                 pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] -   
  21.                            %msg%n" />  
  22.             <Policies>  
  23.                   
  24.                 <TimeBasedTriggeringPolicy interval="1" modulate="true"/>  
  25.                   
  26.                 <SizeBasedTriggeringPolicy size="10 MB" />  
  27.             Policies>  
  28.               
  29.             <DefaultRolloverStrategy max="20" />  
  30.         RollingRandomAccessFile>  
  31.   
  32.           
  33.           
  34.         <File name="log" fileName="log/test.log" append="false">  
  35.             <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M -   
  36.                     %msg%xEx%n"/>  
  37.         File>  
  38.   
  39.           
  40.           
  41.         <RollingFile name="RollingFile" fileName="logs/app.log"  
  42.                      filePattern="log/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">  
  43.             <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36}   
  44.                      %L %M - %msg%xEx%n"/>  
  45.             <SizeBasedTriggeringPolicy size="50MB"/>  
  46.         RollingFile>  
  47.   
  48.     Appenders>  
  49.       
  50.     <Loggers>  
  51.         <Logger name="com.cnblogs.yjmyzz.App2" level="trace"  
  52.             additivity="true">  
  53.             <AppenderRef ref="running-log" />  
  54.         Logger>  
  55.         <Root level="error">  
  56.             <AppenderRef ref="Console" />  
  57.         Root>  
  58.     Loggers>  
  59. Configuration>  
解释一下:
第3行中的 monitorInterval="1800"指log4j2每隔1800秒(半小时),自动监控该配置文件是否有变化,如果变化,则自动根据文件内容重新配置。

5-8行定义了一些属性(可以根据需要自己随便添加),主要是为了后面引用起来方便。

16行 RollingRandomAccessFile 即表示以文件方式记录,注意一下filePattern的设置,它与24行的SizeBasedTriggeringPolicy(表示单个文件最大多少容量)结合在一起,非常有用,以这段配置为例,当单个文件达到10M后,会自动将以前的内容,先创建类似 2014-09(年-月)的目录,然后按 "xxx-年-月-日-序号"命名,打成压缩包。

27行DefaultRolloverStrategy max="20"表示压缩包,最多保留20个。

45-48行,定义了一个新logger,它的级别是trace,使用文件方式来记录日志,additivity="true"这里注意一下,因为下面还有一个root logger,任何其它的logger最终都相当于继承自root logger,所以“com.cnblogs.yjmyzz.App2”这个logger中,如果记录了error及以上级别的日志,除了文件里会记录外,root logger也会生效,即:控制台也会输出一次。如果把additivity="true" 中的true,改成false,root logger就不会再起作用,即只会记录在文件里,控制台无输出。

TimeBasedTriggeringPolicy 基于时间的触发策略。该策略主要是完成周期性的log文件封存工作。有两个参数:

interval,integer型,指定两次封存动作之间的时间间隔。单位:以日志的命名精度来确定单位,比如yyyy-MM-dd-HH 单位为小时,yyyy-MM-dd-HH-mm 单位为分钟

modulate,boolean型,说明是否对封存时间进行调制。若modulate=true,则封存时间将以0点为边界进行偏移计算。比如,modulate=true,interval=4hours,那么假设上次封存日志的时间为03:00,则下次封存日志的时间为04:00,之后的封存时间依次为08:00,12:00,16:00,。。。

 

 

loggers标签,用于定义logger的lever和所采用的appender,其中appender-ref必须为先前定义的appenders的名称,例如,此处为Console。那么log就会以appender所定义的输出格式来输出log。

root标签为log的默认输出形式,如果一个类的log没有在loggers中明确指定其输出lever与格式,那么就会采用root中定义的格式。

Appenders标签,其实就是输出,有各种扩展组件,主要类型有:

ConsoleAppender   输出结果到控制台

FileAppender  输出结果到指定文件

RollingFileAppender   同样输出结果到文件,区别是用一个buffer,因此速度会快点

 

这里介绍下RollingRandomessFile  的相关属性:
name:表示该appender的名称
fileName:表示输出的文件的路径
append:是否追加,true表示追加内容到所在的日志,false表示每次都覆盖
filePattern:表示当日志到达指定的大小或者时间,产生新日志时,旧日志的命名路径。
PatternLayout:和log4j1一样,指定输出日志的格式
Policies:策略,表示日志什么时候应该产生新日志,可以有时间策略和大小策略等
ThresholdFilter :过滤器, 如果你要选择控制台只能输出ERROR以上的类别,你就用ThresholdFilter,把level设置成ERROR,onMatch="ACCEPT" onMismatch="DENY" 的意思是匹配就接受,否则直接拒绝

另外关于logger的命名,很有讲究的,这里我们命名为com.cnblogs.yjmyzz.App2,如果正好有这样一个类:

Java代码   收藏代码
  1. package com.cnblogs.yjmyzz;  
  2.   
  3. import org.apache.logging.log4j.LogManager;  
  4. import org.apache.logging.log4j.Logger;  
  5.   
  6. public class App2 {  
  7.   
  8.     static Logger logger = LogManager.getLogger();  
  9.   
  10.     public static void main(String[] args) {  
  11.         for (int i = 0; i < 10; i++) {  
  12.             logger.trace("trace message " + i);  
  13.             logger.debug("debug message " + i);  
  14.             logger.info("info message " + i);  
  15.             logger.warn("warn message " + i);  
  16.             logger.error("error message " + i);  
  17.             logger.fatal("fatal message " + i);  
  18.         }          
  19.         System.out.println("Hello World! 2");  
  20.     }  
  21. }  

 log4j2是根据名称来用哪个logger的,第8行没有传任何参数,默认这个logger的name就是当前类的全称,即 com.cnblogs.yjmyzz.App2,这样就跟配置对应上了,所以刚才配置中的 nam="com.cnblogs.yjmyzz.App2"的logger,相当于只对App2这一个类起作用。

 

一个实用的配置文件

1)我正在调试某个类,所以,我不想让其他的类或者包的日志输出,否则会很多内容,所以,你可以修改上面root的级别为最高(或者谨慎起见就用ERROR),然后,加一个针对该类的logger配置,给appender-ref定义那个File appender,这个appender的好处是有一个append为false的属性,这样,每次运行都会清空上次的日志,这样就不会因为一直在调试而增加这个文件的内容,查起来也方便,这个和输出到控制台就一个效果了。

2)我已经基本上部署好程序了,然后我要长时间运行了。我需要记录下面几种日志,第一,控制台输出所有的error级别以上的信息。第二,我要有一个文件输出是所有的debug或者info以上的信息,类似做程序记录什么的。第三,我要单独为ERROR以上的信息输出到单独的文件,如果出了错,只查这个配置文件就好了,不会去处理太多的日志,怎么做呢?

>首先,在appenders下面加一个Console类型的appender,通过加一个ThresholdFilter设置level为error。(直接在配置文件的Console这个appender中修改)

>其次,增加一个File类型的appender(也可以是RollingFile或者其他文件输出类型),然后通过设置ThresholdFilter的level为error。

这里可以添加一个appender,内容如下:

 

Xml代码   收藏代码
  1. <File name="ERROR" fileName="logs/error.log">  
  2.      <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>  
  3.      <PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>  
  4. File>  
并在loggers中的某个logger(如root)中引用(root节点加入这一行作为子节点)。 
Xml代码   收藏代码
  1. <appender-ref ref="ERROR" />  

 

>然后,增加一个RollingFile的appender,设置基本上同上面的那个配置文件。

>最后,在logger中进行相应的配置。不过如果你的logger中也有日志级别的配置,如果级别都在error以上,你的appender里面也就不会输出erro以下的信息了。

 

可能存在的问题:在Eclipse下一切运行正常,如果把应用打包成jar包发布后,cmd命令行模式下,即使Console开着的情况下,也没法输出,文件输出也没有任何日志。

问题解决方案:需要在MANIFEST.MF文件里Class-Path 最前加个'.',目的是让与jar包平级的配置文件log4j2.xml加载进来。

 

有时候,为了使同一份log4j文件要支持写到不同的log中,需要在载入的时候对内容进行动态修改,比如根据server id分别生成game1.log,game2.log

可以代码进行加载log4文件

 

Java代码   收藏代码
  1. File file = new File("log4j2.xml");    
  2. BufferedInputStream in = null;    
  3. try {    
  4.     in = new BufferedInputStream(new FileInputStream(file));  
  5.     final ConfigurationSource source = new ConfigurationSource();    
  6.     source.setInputStream(in);    
  7.     Configurator.initialize(null, source);    
  8. catch (FileNotFoundException e) {    
  9.     e.printStackTrace();    
  10. }  
  官方建议一般程序员查看的日志改成异步方式,一些运营日志改成同步

 

 

Asynchronous Appenders 和 Asynchronous Loggers 区别:在 节点里添加

 

Xml代码   收藏代码
  1. <span style="font-size: 14px;"><Async name="Async">  
  2.       <AppenderRef ref="MyFile"/>  
  3. Async>span>  
Asynchronous Appenders 性能比同步快,比Asynchronous Loggers慢

 

在loggers节点添加

 

Xml代码   收藏代码
  1. <AsyncLogger name="com.foo.Bar" level="trace" includeLocation="true">  
  2.       <AppenderRef ref="RandomAccessFile"/>  
  3. AsyncLogger>  
或者添加

 

 

Xml代码   收藏代码
  1.   
  2. <asyncRoot level="DEBUG">  
  3. <appender-ref ref="DevLog" />  
  4. <appender-ref ref="Console" />  
  5. asyncRoot>  
因为logger async 用的是无锁并发技术,必须引入Disruptor

 

测试下,单线程异步比同步效率提高了1倍。线程越多性能提高越明显。

如果要加上位置信息比如哪个类,第几行,需要设置 includeLocation="true" 但默认不设置好像也是true。

log4j2的按天分日志文件

Xml代码   收藏代码
  1. <RollingFile name="error_appender" fileName="${LOG_HOME}/error.log" filePattern="${LOG_HOME}/error-%d{yyyy-MM-dd}.log">  
  2.     <PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%thread] %m%n"/>  
  3.     <Policies>  
  4.         <TimeBasedTriggeringPolicy modulate="true" interval="1"/>  
  5.     Policies>  
  6. RollingFile>  

 

按大小分日志文件

 

Xml代码   收藏代码
  1. <RollingFile name="error_appender" fileName="${LOG_HOME}/error.log" filePattern="${LOG_HOME}/error-%d{yyyy-MM-dd}-%i.log.gz">    
  2.     <PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%thread] %m%n"/>    
  3.     <SizeBasedTriggeringPolicy size="100 MB" />    
  4. RollingFile>  

按分钟分日志文件

 

Xml代码   收藏代码
  1. <RollingRandomAccessFile name="_1min_appender" fileName="${MINUTE_HOME}/minute" filePattern="${MINUTE_HOME}/minute-%d{yyyy-MM-dd-HH-mm}.log">    
  2.     <PatternLayout pattern="%m%n"/>    
  3.     <Policies>    
  4.         <TimeBasedTriggeringPolicy interval="1" modulate="true" />    
  5.     Policies>    
  6. RollingRandomAccessFile>  

关键点在于 filePattern后的日期格式,以及TimeBasedTriggeringPolicy的interval,日期格式精确到哪一位,interval也精确到哪一个单位 

log4j2 设置同一类型日志文件个数

 

Xml代码   收藏代码
  1. <Appenders>    
  2.     <Console name="Console" target="SYSTEM_OUT">    
  3.          <PatternLayout pattern="[%-5p] %d %c - %m%n" />    
  4.     Console>    
  5.     <File name="File" fileName="dist/my.log">    
  6.          <PatternLayout pattern="%m%n" />    
  7.     File>    
  8.     <RollingFile name="RollingFile" fileName="dist/my2.log"    
  9.         filePattern="dist/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">    
  10.         <PatternLayout pattern="[%-5p] %d %c - %m%n" />    
  11.         <Policies>    
  12.             <TimeBasedTriggeringPolicy />    
  13.             <SizeBasedTriggeringPolicy size="25 KB" />    
  14.         Policies>    
  15.         <DefaultRolloverStrategy max="20"/>    
  16.     RollingFile>    
  17. Appenders>  

关键在于 ,如果不做配置,默认是7,这个7指的是上面i的最大值,超过了就会覆盖之前的 

你可能感兴趣的:(log4j2)