log4j2相对于log4j 1.x有了脱胎换骨的变化,其官网宣称的优势有多线程下10几倍于log4j 1.x和logback的高吞吐量、可配置的审计型日志、基于插件架构的各种灵活配置等。如果已经掌握log4j 1.x,使用log4j2还是非常简单的。
先看一个示例
1 基础配置
普通java项目手动添加jar包
log4j-api-2.5.jar
log4j-core-2.5.jar
Maven项目pom.xml
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.10.0</version>
</dependency>
测试代码:
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger;
public class Log4jTest { static final Logger logger = LogManager.getLogger(Log4jTest.class); public static void main(String[] args) { logger.trace("Entering application"); Bar bar = new Bar(); if(!bar.doIt()){ logger.error("did't do it"); } logger.trace("Exiting application"); logger.trace("this is trace!"); logger.debug("this is debug!"); logger.info("this is info!"); logger.warn("this is warning!"); logger.error("this is error!"); logger.fatal("this is fatal!"); } }
运行后输出:import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * Created by jitpki3 on 2017/12/21. */ public class Bar { static final Logger logger = LogManager.getLogger(Bar.class); public boolean doIt(){ logger.entry(); logger.error("do it"); return logger.exit(false); } }
可以看到log4j2先发了一句牢骚,抱怨没有找到配置文件什么的,不过还是输出了error和fatal两个级别的信息。D:\jdk1.7.0_51\bin\java "-javaagent:C:\Program Files (x86)\JetBrains\IntelliJ IDEA 2017.1\lib\idea_rt.jar=59227:C:\Program Files (x86)\JetBrains\IntelliJ IDEA 2017.1\bin" -Dfile.encoding=UTF-8 -classpath D:\jdk1.7.0_51\jre\lib\charsets.jar;D:\jdk1.7.0_51\jre\lib\deploy.jar;D:\jdk1.7.0_51\jre\lib\ext\access-bridge-32.jar;D:\jdk1.7.0_51\jre\lib\ext\dnsns.jar;D:\jdk1.7.0_51\jre\lib\ext\jaccess.jar;D:\jdk1.7.0_51\jre\lib\ext\localedata.jar;D:\jdk1.7.0_51\jre\lib\ext\sunec.jar;D:\jdk1.7.0_51\jre\lib\ext\sunjce_provider.jar;D:\jdk1.7.0_51\jre\lib\ext\sunmscapi.jar;D:\jdk1.7.0_51\jre\lib\ext\sunpkcs11.jar;D:\jdk1.7.0_51\jre\lib\ext\zipfs.jar;D:\jdk1.7.0_51\jre\lib\javaws.jar;D:\jdk1.7.0_51\jre\lib\jce.jar;D:\jdk1.7.0_51\jre\lib\jfr.jar;D:\jdk1.7.0_51\jre\lib\jfxrt.jar;D:\jdk1.7.0_51\jre\lib\jsse.jar;D:\jdk1.7.0_51\jre\lib\management-agent.jar;D:\jdk1.7.0_51\jre\lib\plugin.jar;D:\jdk1.7.0_51\jre\lib\resources.jar;D:\jdk1.7.0_51\jre\lib\rt.jar;F:\zkm\ideaspace\rainbow\target\classes;F:\zkm\ideaspace\rainbow\lib\jit-pkitool-2.3.0.57-beta1.jar;F:\zkm\ideaspace\rainbow\lib\pki-core-1.0.1.2.jar;F:\zkm\ideaspace\rainbow\lib\bcmail-jdk15-140.jar;F:\zkm\ideaspace\rainbow\lib\bcprov-jdk15-143.jar;C:\Users\jitpki3\.m2\repository\org\apache\logging\log4j\log4j-core\2.10.0\log4j-core-2.10.0.jar;C:\Users\jitpki3\.m2\repository\org\apache\logging\log4j\log4j-api\2.10.0\log4j-api-2.10.0.jar cn.com.jit.zkm.Log4jTest ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console. Set system property 'log4j2.debug' to show Log4j2 internal initialization logging. 16:26:54.637 [main] ERROR cn.com.jit.zkm.Bar - do it 16:26:54.638 [main] ERROR cn.com.jit.zkm.Log4jTest - did't do it 16:26:54.639 [main] ERROR cn.com.jit.zkm.Log4jTest - this is error! 16:26:54.639 [main] FATAL cn.com.jit.zkm.Log4jTest - this is fatal! Process finished with exit code 0
log4j2默认会在classpath目录下寻找log4j.json、log4j.jsn、log4j2.xml等名称的文件,如果都没有找到,则会按默认配置输出,也就是输出到控制台。
下面我们按默认配置添加一个log4j2.xml,添加到src根目录即可
重新执行测试代码,可以看到输出结果相同,但是没有再提示找不到配置文件。<?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>
来看我们添加的配置文件log4j2.xml,以Configuration为根节点,有一个status属性,这个属性表示log4j2本身的日志信息打印级别。如果把status改为TRACE再执行测试代码,可以看到控制台中打印了一些log4j加载插件、组装logger等调试信息。
日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出。对于Loggers中level的定义同样适用。
下面是Appender配置,Appender可以理解为日志的输出目的地,这里配置了一个类型为Console的Appender,也就是输出到控制台。Console节点中的PatternLayout定义了输出日志时的格式:
%d{HH:mm:ss.SSS} 表示输出到毫秒的时间
%t 输出当前线程名称
%-5level 输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0
%logger 输出logger名称,因为Root Logger没有名称,所以没有输出
%msg 日志文本
%n 换行
其他常用的占位符有:
%F 输出所在的类文件名,如Client.java
%L 输出行号
%M 输出所在方法名
%l 输出语句所在的行数, 包括类名、方法名、文件名、行数
最后是Logger的配置,这里只配置了一个Root Logger。
实用型配置
下面配置一个按时间和文件大小滚动的RollingRandomAccessFile Appender,名字真是够长,但不光只是名字长,相比RollingFileAppender有很大的性能提升,官网宣称是20-200%。
Rolling的意思是当满足一定条件后,就重命名原日志文件用于备份,并从新生成一个新的日志文件。例如需求是每天生成一个日志文件,但是如果一天内的日志文件体积已经超过1G,就从新生成,两个条件满足一个即可。这在log4j 1.x原生功能中无法实现,在log4j2中就很简单了。
看下面的配置
<?xml version="1.0" encoding="UTF-8"?> <!-- 设置log4j2的自身log级别为warn --> <!-- OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> <configuration status="WARN" monitorInterval="30"> <appenders> <console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> </console> <!-- <File name="MyFile" fileName="D:/logs/app.log"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /> </File>--> <RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log" filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log"> <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--> <Filters> <ThresholdFilter level="INFO"/> <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/> </Filters> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="100 MB"/> </Policies> </RollingFile> <RollingFile name="RollingFileWarn" fileName="${sys:user.home}/logs/warn.log" filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log"> <Filters> <ThresholdFilter level="WARN"/> <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/> </Filters> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="100 MB"/> </Policies> </RollingFile> <RollingFile name="RollingFileError" fileName="${sys:user.home}/logs/error.log" filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log"> <ThresholdFilter level="ERROR"/> <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="100 MB"/> </Policies> </RollingFile> <RollingRandomAccessFile name="MyFile" fileName="D:/logs/app.log" filePattern="D:/logs/app%d{yyyy-MM-dd HH-mm}-%i.log"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /> <Policies> <TimeBasedTriggeringPolicy interval="10" /> <SizeBasedTriggeringPolicy size="10 KB" /> </Policies> <DefaultRolloverStrategy max="20" /> </RollingRandomAccessFile> </appenders> <loggers> <!--过滤掉spring和mybatis的一些无用的DEBUG信息--> <logger name="org.springframework" level="INFO"></logger> <logger name="org.mybatis" level="INFO"></logger> <!--<root level="all">--> <root level="ALL"> <appender-ref ref="Console"/> <appender-ref ref="MyFile"/> <appender-ref ref="RollingFileInfo"/> <appender-ref ref="RollingFileWarn"/> <appender-ref ref="RollingFileError"/> </root> </loggers> </configuration>
<properties>定义了两个常量方便后面复用
RollingRandomAccessFile的属性:
fileName 指定当前日志文件的位置和文件名称
filePattern 指定当发生Rolling时,文件的转移和重命名规则
SizeBasedTriggeringPolicy 指定当文件体积大于size指定的值时,触发Rolling
DefaultRolloverStrategy 指定最多保存的文件个数
TimeBasedTriggeringPolicy 这个配置需要和filePattern结合使用,注意filePattern中配置的文件重命名规则是${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i,最小的时间粒度是mm,即分钟,TimeBasedTriggeringPolicy指定的size是1,结合起来就是每1分钟生成一个新文件。如果改成%d{yyyy-MM-dd HH},最小粒度为小时,则每一个小时生成一个文件。
原地址:http://blog.youkuaiyun.com/autfish/article/details/51203709