Java日志体系(六)log4j2
1.1 简介
            
log4j2,一个日志的实现框架,是log4j的升级版本,于2014年7月正式亮相。与第一代log4j不同,log4j2完全重写了log4j的日志实现,并不是在原有基础上进行的升级,解决了log4j中的一些问题,例如:多线程下性能低下、api不支持占位符{}的使用、配置文件不能自动重新加载等。
为什么说log4j在多线程情况下性能低下呢?主要是synchronized锁在作怪,当我们的log4jzai 获取appender对象时,需要进行加锁处理;而接下来对appender操作(将要进行日志打印)时,也进行了加锁处理,这样一来性能自然得不到提升,从而导致整个应用的qps下降。
而在log4j2中,由于引入了异步logger,使得log4j2的性能得到了巨大的提升,相比于log4j,logback而言,提升了数10倍之多。关于异步logger的情况,我们后面进行讲解。
1.2 log4j2结构
                
LoggerContext:Logger上下文,主要负责读取log4j2的配置以及获取Logger对象的工作;
Logger:日志对象,负责日志信息的打印;跟之前的几个日志框架相同,log4j2也包含了5大日志级别,分别为TRACE,DEBUG,INFO,WARN,ERROR 以及FATAL;具体等级如下:TRACE < DEBUG < INFO < WARN < ERROR < FATAL;
LoggerConfig:Logger的配置对象,每一个Logger的配置信息就是一个LoggerConfig对象;
Configuration:log4j2配置文件的解析,当我们的配置文件是xml的格式时,具体的实现是XmlConfiguration;每一个LoggerContext都有一个Configuration对象,包含了所有的Appender、Filter、LoggerConfig
1.3 使用
首先,需要在应用的pom.xml中添加依赖:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
其次,声明测试代码:
public class log4j2Demo {
    private Logger logger = LogManager.getLogger(log4j2Demo.class);
    @Test
    public void test() throws InterruptedException {
        logger.error("Error Message!");
        logger.warn("Warn Message!");
        logger.info("Info Message!");
        logger.debug("Debug Message!");
        logger.trace("Trace Message!");
    }
}
最后,在classpath下声明配置文件:log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info" monitorInterval="30">
<Appenders>
<!--控制台-->
<Console name="Console" target="SYSTEM_OUT">-->
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console> <!--普通文件:-->
<File name="File" fileName="e:/log.out" append="true" immediateFlush="true" >
<PatternLayout>
<Pattern>%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %L- %msg%n</Pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Root level="debug" >
<AppenderRef ref="File"/>
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
通过以上步骤,log4j2就可以正常的运行了。
1.4 log4j2配置文件详解
与log4j不同的是,log4j2只支持.xml或者.json格式的配置文件,不在支持.properties格式的配置文件。那么,下面我们就以.xml来进行讲解:
默认情况下,系统会在classpath下查找配置文件:(按照以下顺序)
1.classpath下名为 log4j-test.json 或者log4j-test.jsn文件
2.classpath下名为 log4j2-test.xml
3.classpath下名为 log4j.json 或者log4j.jsn文件
4.classpath下名为 log4j2.xml
请注意,此处我们常用的是log4j2.xml,这块与log4j不同;
以下是log4j2常用的配置信息:(逐一进行讲解)
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info" monitorInterval="30">
<Appenders> <!--控制台-->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console> <!--普通文件:-->
<File name="File" fileName="e:/log.out" append="true" immediateFlush="false" bufferedIO="true" bufferSize="1024">
<PatternLayout>
<Pattern>%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %L- %msg%n</Pattern>
</PatternLayout>
</File> <!--异步appender:-->
<Async name="Async">
<AppenderRef ref="File"/>
</Async> <!--循环写入文件:-->
<RollingFile name="RollingFile" fileName="e:/log.out" filePattern="e:/app-%d{yyyy-MM-dd_HH-mm}-%i.out">
<PatternLayout>
<Pattern>%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Pattern>
</PatternLayout>
<!--滚动策略:-->
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="100 kb"/>
</Policies>
<DefaultRolloverStrategy max="5"/>
</RollingFile> </Appenders> <Loggers> <!--单独指定logger-->
<Logger name="com.jiaboyan.logDemo.log4j2Demo" level="info" additivity="false" includeLocation="true">
<AppenderRef ref="File"/>
</Logger> <!--根logger-->
<Root level="info" >
<AppenderRef ref="Async"/>
<AppenderRef ref="File"/>
<AppenderRef ref="Console"/>
</Root> <!--异步logger-->
<AsyncRoot level="info">
<AppenderRef ref="File"/>
</AsyncRoot>
</Loggers> </Configuration>
1.Configuration -- 根节点
<Configuration status="debug" monitorInterval="30"></Configuration>
Configuration:表示log4j2中的Configuration对象,实际为XmlConfiguration; status:表示log4j2本身的日志信息打印级别,当设置为TRACE 或者 DEBUG 级别时,便会打印出log4j2内部初始化的一些日志信息; monitorInterval:表示每隔一定时间重新加载log4j2配置文件,单位秒;
2.Appenders -- Console
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console> name:表示控制台Appender的名称,<logger>中会依赖此名称,起名没有具体要求,但最好简明直译; target:表示ConsoleAppender使用哪种方式将日志输出到控制台,一般调用System.out.println()方法; PatternLayout--pattern:表示日志信息输出的格式;
3.Appenders -- File
<File name="File" fileName="e:/log.out" append="true" immediateFlush="false" bufferedIO="true" bufferSize="8096">
<PatternLayout>
<Pattern>%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %L- %msg%n</Pattern>
</PatternLayout>
</File> name:表示文件Appender的名称,<logger>中会依赖此名称,起名没有具体要求,但最好简明直译; fileName:表示生成的日志文件名称; append:表示新生成的日志是否追加到日志文件中,如果为true则表示追加,false表示覆盖原有日志信息; immediateFlush:表示日志打印请求是否立即输出,true为立即,false表示使用缓存; bufferedIO:表示日志打印请求是否使用缓存,true为使用,false为不使用; bufferSize:表示日志打印请求的使用缓存的大小,默认为8096字节; PatternLayout--pattern:同上;
4.Appenders -- RollingFile
<RollingFile name="RollingFile" fileName="e:/log.out" filePattern="e:/app-%d{yyyy-MM-dd_HH-mm}-%i.out">
    <PatternLayout>
        <Pattern>%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Pattern>
    </PatternLayout>
    <Policies>
        <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
        <CronTriggeringPolicy schedule="0 0 * * * ?"/>
        <SizeBasedTriggeringPolicy size="100 kb"/>
    </Policies>
    <DefaultRolloverStrategy max="5"/>
</RollingFile>
name:表示滚动文件Appender的名称,<logger>中会依赖此名称,起名没有具体要求,但最好简明直译;
fileName:表示当前日志所在的日志文件名称; 
filePattern:表示滚动日志的文件名称模板,当日志文件进行滚动后,滚动后的文件按照此模板进行命名;
PatternLayout--pattern:同上;
Policies:表示日志文件滚动策略;
Policies -- TimeBasedTriggeringPolicy:表示日志文件按照时间间隔来进行滚动;
Policies -- CronTriggeringPolicy:表示日志文件按照设置的时间点来进行滚动;
Policies -- SizeBasedTriggeringPolicy:表示日志文件按照文件大小来进行滚动;
DefaultRolloverStrategy:表示log4j2进行滚动后保存的日志文件数量,默认为7个;
5.TimeBasedTriggeringPolicy
<TimeBasedTriggeringPolicy interval="1" modulate="true"/> TimeBasedTriggeringPolicy表示按照时间间隔来进行日志文件的滚动,间隔单位可以是分钟、小时,具体需要根据filePattern的格式来进行判别;
例如filePattern="e:/app-%d{yyyy-MM-dd_HH-mm}-%i.out",则表示mm(分钟)为单位; interval:表示分隔日志的时间间隔大小,如果时间间隔单位是分钟,则表示相隔1分钟、10分钟等进行一次日志分隔; modulate:表示是否对分隔时间进行调制;如果设置为true则表示分隔的时间从每天的0点、每小时的0分钟开始进行计算,每间隔多久进行一次切割;比如,modulate=true,interval=4hours,那么假设上次封存日志的时间为03:00,则下次封存日志的时间为04:00,之后的封存时间依次为08:00,12:00,16:00。。。
6.CronTriggeringPolicy
<CronTriggeringPolicy schedule="0 0 * * * ?"/> CronTriggeringPolicy表示按照Cron表达式设置的时间点进行切割日志; schedule:表示设置的cron表达式;
7.SizeBasedTriggeringPolicy
<SizeBasedTriggeringPolicy size="100 kb"/> SizeBasedTriggeringPolicy表示按照规定的日志文件大小进行切割日志; size:表示进行切割日志文件大小的极值,当日志文件大小满足size的值时,就会进行日志的切割;
DefaultRolloverStrategy
<DefaultRolloverStrategy max="5"/>
DefaultRolloverStrategy表示log4j2每单位时间内最多能保存多少个日志切割文件,一般与SizeBasedTriggeringPolicy结合使用;
max:表示保存的最大值,默认为7;
例如:你的log4j2.xml设置如下:fileName="e:/log.out" filePattern="e:/app-%d{yyyy-MM-dd_HH-mm}-%i.out"
那么在每分钟内,你可以保留2个日志切割文件,多余的日志进行覆盖;
8.Appenders -- Async
<Async name="Async">
<AppenderRef ref="File"/>
</Async> name:表示异步Appender的名称,<logger>中会依赖此名称,起名没有具体要求,但最好简明直译;
异步Appender使用消费者生产者模式进行日志信息的打印,适用于并发量较大的情况;
9.PatternLayout
<PatternLayout>
<Pattern>%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Pattern>
</PatternLayout> Pattern:设置输出的日志信息格式;具体格式如下: %d{yyyy-MM-dd HH:mm:ss, SSS} : 日志生产时间
%t : 线程名称
%p : 日志级别
%level : 日志级别
%c : logger的名称
%logger : logger的名称
%C : Java类名
%m : 日志内容
%n : 换行符
%L : 日志输出所在行数
%M : 日志输出所在方法名
10.Loggers -- Logger
<Logger name="com.jiaboyan.logDemo.log4j2Demo" level="info" additivity="false">
<AppenderRef ref="File"/>
</Logger> 在<Loggers>节点下,对某个类单独进行日志配置,便可使用<logger>节点;
上例中,我们对名称为com.jiaboyan.logDemo.log4j2Demo的类进行日志配置。
level指定级别,additivity表示是否向上传递打印日志信息(若为true则向上传递,那么root根对象也会进行日志打印);
11.Loggers -- Root
<Root level="info" >
<AppenderRef ref="Async"/>
<AppenderRef ref="File"/>
<AppenderRef ref="Console"/>
</Root> Root根日志节点,指定具体的日志级别,以及使用何种Appender进行日志输出;
12.Loggers -- AsyncRoot
<AsyncRoot level="info" includeLocation="false">
<AppenderRef ref="File"/>
</AsyncRoot> 如果想使用异步logger,还需要在pom.xml中添加disruptor的依赖。
includeLocation结合异步logger使用,当其设置为true时,才会显示具体的行号,以及日志所在的类名;
如果设置为false,哪怕<Pattern>设置了输出行号也不会显示出来;
参考:https://www.jianshu.com/p/474eaecac699
Java日志体系(六)log4j2的更多相关文章
- java 日志体系(四)log4j 源码分析
		
java 日志体系(四)log4j 源码分析 logback.log4j2.jul 都是在 log4j 的基础上扩展的,其实现的逻辑都差不多,下面以 log4j 为例剖析一下日志框架的基本组件. 一. ...
 - java 日志体系目录
		
java 日志体系目录 1.1 java 日志体系(一)log4j1.log4j2.logback.jul.jcl.slf4j 1.2 java 日志体系(二)jcl 和 slf4j 2.1 java ...
 - Java 日志体系(二)jcl 和 slf4j
		
Java 日志体系(二)jcl 和 slf4j <java 日志体系(一)统一日志>:https://www.cnblogs.com/binarylei/p/9828166.html &l ...
 - Java 日志体系
		
Java 日志体系 <java 日志和 SLF4J 随想>:http://ifeve.com/java-slf4j-think/ 一.常用的日志组件 名称 jar 描述 log4j log ...
 - 混乱的 Java 日志体系
		
混乱的 Java 日志体系 2016/09/10 | 分类: 基础技术 | 0 条评论 | 标签: LOG 分享到: 原文出处: xirong 一.困扰的疑惑 目前的日志框架有 jdk 自带的 log ...
 - Java日志体系居然这么复杂?——架构篇
		
本文是一个系列,欢迎关注 日志到底是何方神圣?为什么要使用日志框架? 想必大家都有过使用System.out来进行输出调试,开发开发环境下这样做当然很方便,但是线上这样做就有麻烦了: 系统一直运行,输 ...
 - java 日志体系(三)log4j从入门到详解
		
java 日志体系(三)log4j从入门到详解 一.Log4j 简介 在应用程序中添加日志记录总的来说基于三个目的: 监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析工作: 跟踪代 ...
 - java日志体系的思考(转)
		
Java 日志缓存机制的实现 Java 日志管理最佳实践 混乱的 Java 日志体系 log日志远程统一记录 浅谈后端日志系统 Java异常处理和接口约定 用SLF4j/Logback打印日志-1 用 ...
 - 【原创】架构师必备,带你弄清混乱的JAVA日志体系!
		
引言 还在为弄不清commons-logging-xx.jar.log4j-xx.jar.sl4j-api-xx.jar等日志框架之间复杂的关系而感到烦恼吗? 还在为如何统一系统的日志输出而感到不知所 ...
 - 架构师必备,带你弄清混乱的JAVA日志体系!
		
作者:孤独烟 出处:http://rjzheng.cnblogs.com/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任 ...
 
随机推荐
- D. Connected Components  Croc Champ 2013 - Round 1 (并查集+技巧)
			
292D - Connected Components D. Connected Components time limit per test 2 seconds memory limit per t ...
 - ActiveMQ初步安装使用(一)
			
ActiveMQ 的官网 : http://activemq.apache.org ActiveMQ 扩展出: API 接受发送 MQ 的高可用 MQ 的集群容错配置 MQ 的持久化 延时发送 签收机 ...
 - 【Android-自定义控件】SwipeRefreshDemo 下拉刷新,上拉加载
			
参考:https://github.com/PingerOne/SwipeRefreshDemo 谷歌官方的SwipeRefreshLayout控件,只有下拉刷新功能. 自定义的SwipeRefres ...
 - 洛谷 P2832 行路难
			
题面 这个最短路有点special,会有疲劳度的加成效应,这个时候应该怎么办呢? 难就难在,如果走一条路比另一条路长,但是用的边少,那么这条路并不一定就更差. 我们要是能解决这个问题,就可以做出本题. ...
 - 【csp模拟赛2】黑莲花--数据结构+数论
			
没有什么能够阻挡,你对被阿的向往.天天 AK 的生涯,你的心了无牵挂. 虐过大佬的比赛,也曾装弱装逼.当你低头的瞬间,才发现旁边的人. 把你的四肢抬起来,使劲地往门上撞.盛开着永不凋零,黑莲花. —— ...
 - JS核心知识点:DOM\BOM\EVENT
			
1.DOM(Document Object Model) :文档对象模型2. DOM节点:页面中最基本的组成部分 3. childNodes:获取某个节点下所有的子节点 在标准及ie9以上 : 会获取 ...
 - MFC消息反射机制
			
消息反射机制要解决什么问题呢? 消息反射机制主要是为了控件而实现的.每当控件需要某些资讯(比如,绘制自身背景的画刷,显示字体的颜色等等)时,都会频繁地向其父窗口发送通告消息(notification ...
 - ew做代理 进一步内网渗透
			
0x00 前言 最近搞站的时候有内网穿透的需求,大佬向我推荐了EW,本文模拟一个攻击场景对Earthworm的使用方法做一个简单的介绍.其实相应的内容EW的官网已经说得很详细了,我这里纯粹是作为个人笔 ...
 - java中判断空字符串和null的判断方法
			
简单总结几个方法: 1.直观的: if(s == null ||"".equals(s)); //先判断是否对象,再判断是否是空字符串 2.比较字符串长度, 效率高, 比较绕: i ...
 - assign修饰对象类型会怎样?
			
首先我们需要明确,对象的内存一般被分配到堆上,基本数据类型和oc数据类型一般被分配在栈上. 如果用assign修饰对象,当对象释放后(因为不存在强引用,离开作用域对象内存可能被回收),指针的地址还是存 ...