log4j2的简单学习:

package com.book.web.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

//import org.apache.commons.logging.Log;
//import org.apache.commons.logging.LogFactory;
//import org.apache.logging.log4j.LogManager;
//import org.apache.logging.log4j.Logger;


/**
 * log4j2测试
 * @author liweihan
 *
 */
public class TestLog4j2Log {
	
	/**
	 	1.
		<dependency>
		  <groupId>org.apache.logging.log4j</groupId>
		  <artifactId>log4j-api</artifactId>
		  <version>2.5</version>
		</dependency>
		<dependency>
		  <groupId>org.apache.logging.log4j</groupId>
		  <artifactId>log4j-core</artifactId>
		  <version>2.5</version>
		</dependency>
		
		如果是web环境可以加入:因为会提示:
		Log4j appears to be running in a Servlet environment,
		 but there's no log4j-web module available. 
		 If you want better web container support,
		 please add the log4j-web JAR to your web archive or server lib directory.
		<dependency>
		  <groupId>org.apache.logging.log4j</groupId>
		  <artifactId>log4j-web</artifactId>
		  <version>2.2</version>
		</dependency>
	 	
	 	2.
	 	log4j2与log4j1发生了很大的变化,不兼容。
	 	log4j1仅仅作为一个实际的日志框架,
	 	slf4j、commons-logging作为门面,统一各种日志框架的混乱格局,
	 	现在log4j2也想跳出来充当门面了,也想统一大家了!!
	 	
		3.log4j2分成2个部分:

			log4j-api: 作为日志接口层,用于统一底层日志系统
			log4j-core : 作为上述日志接口的实现,是一个实际的日志框架
			
		4.log4j 2.x版本不再支持像1.x中的.properties后缀的文件配置方式,
		  2.x版本配置文件后缀名只能为”.xml”,”.json”或者”.jsn”。
		  
		  log4j2默认会在classpath目录下寻找:
		  <1.>log4j2-test.json 或者log4j2-test.jsn的文件
		  <2.>log4j2-test.xml的文件.
		  <3.>log4j2.json 或者log4j2.jsn的文件.
		  <4.>log4j2.xml的文件.
		     
		      如果都没有找到,则会按默认配置输出,也就是输出到控制台
		
		5.和log4j1是不同的。此时Logger是log4j-api中定义的接口,而log4j1中的Logger则是类
		
		6.如果要log4j2与commons-logging集成,还需要引入jar包:
		<dependency>
		  <groupId>commons-logging</groupId>
		  <artifactId>commons-logging</artifactId>
		  <version>1.2</version>
		</dependency>	
		<dependency>
		  <groupId>org.apache.logging.log4j</groupId>
		  <artifactId>log4j-jcl</artifactId>
		  <version>2.2</version>
		</dependency>
		
			commons-logging
			log4j-api (log4j2的API包)
			log4j-core (log4j2的API实现包)
			log4j-jcl (log4j2与commons-logging的集成包)
			
		private static Log logger = LogFactory.getLog(TestLog4j2Log.class);
		使用commons-logging的Log接口和LogFactory来进行编写,看不到log4j2的影子。
		但是这时候含有上述几个jar包,log4j2就与commons-logging集成了起来。
		
		common-logging貌似不支持占位符!
		
		7.如果log4j2与slf4j集成,还需要引入jar包:
		<!-- log4j2与slf4j集成 -->
		<dependency>
		  <groupId>org.slf4j</groupId>
		  <artifactId>slf4j-api</artifactId>
		  <version>1.7.7</version>
		</dependency>
		<dependency>
		  <groupId>org.apache.logging.log4j</groupId>
		  <artifactId>log4j-slf4j-impl</artifactId>
		  <version>2.5</version>
		</dependency>
		
		
		log4j-slf4j-impl : 用于log4j2与slf4j集成
		获取logger的方式:
		private static Logger logger=LoggerFactory.getLogger(Log4j2Slf4jTest.class);
	 */
	
//	private static final Logger logger  = LogManager.getLogger(TestLog4j2Log.class);
//	private static Log logger = LogFactory.getLog(TestLog4j2Log.class);
	private static Logger logger = LoggerFactory.getLogger(TestLog4j2Log.class);
	
	public static void main(String[] args) {
		
		if (logger.isTraceEnabled()) {
			logger.trace(" ===== log4j2 trace meassge");
		}
		if (logger.isDebugEnabled()) {
			logger.debug(" ===== log4j2 debug message");
			logger.debug(" ------ test log4j2:{},{}","Hello ","HANCHo");
		}
		if (logger.isInfoEnabled()) {
			logger.info(" ===== log4j2 info message");
		}
		if (logger.isErrorEnabled()) {
			logger.error(" ===== log4j2 error message ");
		}
		
		//
		Object[] params = {"HAN",1,"CHAO"};
		logger.info(" ===== test:{}, 加班 {} 天, {}要回家了!",params);
	}

}


配置文件:log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>  
<Configuration status="info" monitorInterval="300">  
	<Properties>
		<Property name="log.pattern">
		<!--%d %-5p [%t] %C{2} (%F:%L) - %m%n-->
		 %date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n
		</Property>
	</Properties>

  <Appenders>  
  	
  	<!-- 控制台 -->
    <Console name="Console" target="SYSTEM_OUT" >  
      <ThresholdFilter level="debug"/> 
       <PatternLayout pattern="${log.pattern}"/>
      <!-- 本地测试可以用这个 
      <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
      --> 
      <!-- 
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] [%-5level] %class{36} %L %M - %msg%n"/>  
       -->
      <!--
          %d{yyyy-MM-dd HH:mm:ss, SSS} : 日志生产时间
          %p : 日志输出格式
          %c : logger的名称
          %m : 日志内容,即 logger.info("message")
          %n : 换行符
          %C : Java类名
          %L : 日志输出所在行数
          %M : 日志输出所在方法名
          hostName : 本地机器名
          hostAddress : 本地ip地址
       -->
    </Console>  
    
    <!-- 文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用  
    	append为TRUE表示消息增加到指定文件中,false表示消息覆盖指定的文件内容,默认值是true -->
    <File name="log" fileName="./logs/test.log" append="false">  
      <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>  
    </File>
    
    <!-- 打印所有的日志到stdout.log文件 -->
    <RollingFile name="Stdout" fileName="./logs/stdout.log"  
                 filePattern="./logs/stdout.log.%d{yyyy-MM-dd}-%i">  
      <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{36} %L %M - %msg%xEx%n"/>  
      <Policies>
      <!-- 基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour。
      	    modulate=true用来调整时间:比如现在是早上3am,interval是4,
      	    那么第一次滚动是在4am,接着是8am,12am...而不是7am. 
      -->
        <!-- 时间触发,一天一个日志 -->
        <TimeBasedTriggeringPolicy interval="24" modulate="true"/>
        <!-- 大小触发,达到50M的时候进行分割 -->
        <SizeBasedTriggeringPolicy size="50 MB" />  
      </Policies>
      <!-- 用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的 -->
      <!-- DefaultRolloverStrategy属性如不设置,
      	         则默认为最多同一文件夹下7个文件,这里设置了20 -->
      <DefaultRolloverStrategy max="30" />
    </RollingFile>
    
    <!-- 只打印error以及以上级别的日志到stderr.log -->
    <RollingFile name="Error" fileName="./logs/stderr.log"  
                 filePattern="./logs/stderr.log.%d{yyyy-MM-dd}-%i">
      <!--  控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
      <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>  
      <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{36} %L %M - %msg%xEx%n"/>  
      <Policies>
        <!-- 时间触发,一天一个日志 -->
        <TimeBasedTriggeringPolicy interval="24" modulate="true"/>
        <!-- 大小触发,达到50M的时候进行分割 -->
        <SizeBasedTriggeringPolicy size="50 MB" />  
      </Policies>
      <!-- 用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的 -->
      <DefaultRolloverStrategy max="30" />  
    </RollingFile>
    
  </Appenders>  
  <Loggers> 
  	<!--过滤掉spring和mybatis的一些无用的DEBUG信息--> 
    <Logger name="org.mybatis" level="INFO"></Logger>
    <Logger name="org.springframework" level="INFO"></Logger>
    
    <Root level="debug">  
      <Appender-ref ref="Stdout"/>  
      <Appender-ref ref="Console"/>  
      <Appender-ref ref="Error"/>
      
      <!-- just for test temp -->
      <Appender-ref ref="log"/>
    </Root>  
  </Loggers>  
</Configuration>
===============================================================================


一、Configuration

有两个属性:status和monitorinterval,有两个子节点:Appenders和Loggers(表明可以定义多个Appender和Logger).

status : 用来指定log4j本身的打印日志的级别.

monitorinterval : 用于指定log4j自动重新配置的监测间隔时间,单位是s,最小是5s.


二、Appenders节点

常见的有三种子节点:Console、RollingFile、File.

1.Console:  Console节点用来定义输出到控制台的Appender.

        name:指定Appender的名字.

        target:SYSTEM_OUT 或 SYSTEM_ERR,一般只设置默认:SYSTEM_OUT.

        PatternLayout:输出格式,不设置默认为:%m%n.


2.File:   File节点用来定义输出到指定位置的文件的Appender.

        name:指定Appender的名字.

        fileName:指定输出日志的目的文件带全路径的文件名.

        PatternLayout:输出格式,不设置默认为:%m%n.

3.RollingFile: RollingFile节点用来定义超过指定大小自动删除旧的创建新的的Appender.

        name:指定Appender的名字.

        fileName:指定输出日志的目的文件带全路径的文件名.

        PatternLayout:输出格式,不设置默认为:%m%n.

        filePattern:指定新建日志文件的名称格式.

        Policies:指定滚动日志的策略,就是什么时候进行新建日志文件输出日志.

                                          TimeBasedTriggeringPolicy:Policies子节点,基于时间的滚动策略,interval属性用来指定多久滚动一次,默认是1 hour。modulate=true用来调整时间:比如现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am…而不是7am.

                           SizeBasedTriggeringPolicy:Policies子节点,基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小.

        DefaultRolloverStrategy:用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的,创建新的(通过max)


三、Loggers节点

常见子节点的有两种:Root和Logger.

1.Root:

  Root节点用来指定项目的根日志,如果没有单独指定Logger,那么就会默认使用该Root日志输出   


      level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.

     AppenderRef:Root的子节点,用来指定该日志输出到哪个Appender.


2.Logger:

               Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。

     level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.

     name:用来指定该Logger所适用的类或者类所在的包全路径,继承自Root节点.

     AppenderRef:Logger的子节点,用来指定该日志输出到哪个Appender,如果没有指定,就会默认继承自Root.如果指定了,那么会在指定的这个Appender和Root的Appender中都会输出,此时我们可以设置Logger的additivity=”false”只在自定义的Appender中进行输出。


四、关于日志level

              共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.

      All:最低等级的,用于打开所有日志记录.

      Trace:是追踪,就是程序推进以下,你就可以写个trace输出,所以trace应该会特别多,不过没关系,我们可以设置最低日志级别不让他输出.

      Debug:指出细粒度信息事件对调试应用程序是非常有帮助的.

      Info:消息在粗粒度级别上突出强调应用程序的运行过程.

      Warn:输出警告及warn以下级别的日志.

      Error:输出错误信息日志.

      Fatal:输出每个严重的错误事件将会导致应用程序的退出的日志.

      OFF:最高等级的,用于关闭所有日志记录.

      程序会打印高于或等于所设置级别的日志,设置的日志等级越高,打印出来的日志就越少

五、参考


log4j2:

http://blog.csdn.net/vergilgeekopen/article/details/61417342

http://www.cnblogs.com/hanfight/p/5721855.html


性能对比:

https://my.oschina.net/OutOfMemory/blog/789267

http://blog.csdn.net/yjh1271845364/article/details/70888262


其他日志系统了解:

http://blog.csdn.net/xudan1010/article/details/52890102

http://www.cnblogs.com/Leo_wl/p/3417215.html

https://my.oschina.net/pingpangkuangmo/blog/406618



六、遇到的一个问题

日志突然不打印了。查看日志,发现log4j2本身的日志显示:在加载log4j2.xml文件时发生错误。

log4j2使用自己默认的log4j2的配置,只能打印error日志。

wKiom1mWuiSxZ0DMAAFGsqRvD2Q404.jpg

默认配置:

<?xml version="1.0" encoding="UTF-8"?>
  <Configuration status="WARN">
    <Appenders>
      <Console name="Console" target="SYSTEM_OUT">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
      </Console>
    </Appenders>
    <Loggers>
      <Root level="error">
       <AppenderRef ref="Console"/>
     </Root>
   </Loggers>
 </Configuration>

分析原因:

wKiom1maRxDSgCO0AACrYMNidzE170.jpg