log4j2比logback好用。

现在之所有以spring采用logback,根据我个人的理解应该是某种非常特殊的理由。否则log4j2的性能比logback更好,且异步性能极好!

异步日志是log4j的最大有点,个人对此深有体会。异步对于系统的性能影响是很大的,事务的并发越多,log4j2对于性能的影响就越加明显。

本文主要讨论:

1.如何开启异步

2.如何让同一个类的日志根据级别输出到不同文件中,而且还不会重复

一、springboot集成log4j2

具体设定,到处都是,虽然如此,本文还是重复一遍从网友那里参考的内容。

1.引用log4j2,并排除默认的日志log-back

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 去掉springboot默认配置 -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- 引入log4j2依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.lmax/disruptor 异步要求这个支持 -->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.4</version>
</dependency>

注意:除了spring-boot-starter-web,还有一些artifactId(包标识)指定的包会包含spring-boot-starter-logging(内含Log-back).

所以,如果不好确认,那么可以使用sts或者idea的pom.xml查看器,查看是否包含spring-boot-starter-logging,如果有,那么就排除掉,否则log4j2无效。

2.application.yml/properties指定log4j2的配置

可以使用一些列的属性具体指定配置,但那样不方便,所以一般我们只指定一个属性

logging:
config: classpath:log4j2.xml

然后在log4j2.xml中指定各种配置。

3.设置log4j2的内容

这个可以参考官方的资料 : https://logging.apache.org/log4j/2.x/manual/configuration.html

二、开启异步

关键在于设定logger(记录器)。

记录器可以通常设定三类记录器:同步、异步、控制台

此处略去同步和控制台。

下面是异步的部分参考:

<AsyncLogger name="com.hongcan.srv.basetest" additivity="false" includeLocation="true">
<appender-ref ref="RollingFileInfo" />
<appender-ref ref="RollingFileDebug" />
<appender-ref ref="RollingFileWarn" />
<appender-ref ref="RollingFileError" />
</AsyncLogger>

注意:如果要为一个包或者具体类指定多个appender(写入器),那么必须如上指定,而不是一个包/类指定多个记录器(如果这样,只有一个会生效)。

属性 additivity并非一直都是生效,要看appender的情况,includeLocation则建议设置为false。为了便于阅读,项目组在制定日志输出内容方面应该多花费一些心思。

三、不同级别日志输出到不同文件,且不重复

按照一般的设定(基本上是默认),级别高的日志会输出到所有文件,此类方式便于在一个文件查看所有的日志,这种方式便于调试和解决问题,但有时候也不太方便,因为内容实在太多了。

如果想达成这样的目的,那么可以如下设定:

<RollingFile name="RollingFileDebug" fileName="${file_path}/rolling-debug.log"
filePattern="${file_path}/${backup_folder}/debug${backup_file_suffix}">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<Filters>
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters> <!-- 写入日志文件的模板 -->
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${file_max_size}"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,超过该数量,会滚动删除前面的记录 -->
<DefaultRolloverStrategy max="10"/>
</RollingFile> <AsyncLogger name="com.hongcan.srv.basetest" additivity="false" includeLocation="true">
<appender-ref ref="RollingFileInfo" />
<appender-ref ref="RollingFileDebug" />
<appender-ref ref="RollingFileWarn" />
<appender-ref ref="RollingFileError" />
</AsyncLogger>

如果我们在指定类内部执行log.error("haha!"),那么这个内容会输出到debug,info,warn,error文件中。

如果不想这样,那么可以如下:

<RollingFile name="RollingFileDebug" fileName="${file_path}/rolling-debug.log"
filePattern="${file_path}/${backup_folder}/debug${backup_file_suffix}">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<Filters>
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters> <!-- 写入日志文件的模板 -->
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${file_max_size}"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,超过该数量,会滚动删除前面的记录 -->
<DefaultRolloverStrategy max="10"/>
</RollingFile> <AsyncLogger name="com.hongcan.srv.basetest" additivity="false" includeLocation="true">
<appender-ref ref="RollingFileInfo" />
<appender-ref ref="RollingFileDebug" />
<appender-ref ref="RollingFileWarn" />
<appender-ref ref="RollingFileError" />
</AsyncLogger><configuration status="warn" monitorInterval="30">
<Properties>
<!-- 日志显示模板,显示内容的格式如下 -->
<Property name="LOG_HOME">${sys:log.home}</Property>
<!-- [21:55:33:047] [INFO] - org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:173) - Initializing Spring embedded WebApplicationContext -->
<Property name="log_pattern" value="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<!-- 保存日志文件目录 -->
<Property name="file_path" value="${sys:user.home}/logs/configservice-test"/>
<!-- 日志文件的最大容量,超过该值就进行备份 -->
<Property name="file_max_size" value="10MB"/>
<!-- 备份的文件夹名称 如下为:2020-02 -->
<Property name="backup_folder" value="$${date:yyyy-MM}"/>
<!-- 备份文件的后缀,日志文件超过file_max_size会备份到filePattern指定的目录下 -->
<!-- 并开启日志压缩,避免太大 -->
<Property name="backup_file_suffix" value="-%d{yyyy-MM-dd}-%i.log.zip"/>
</Properties> <!--定义appender-->
<appenders> <!--控制台的输出配置-->
<console name="Console" target="SYSTEM_OUT">
<!-- 设置控制台只输出INFO及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<!--输出日志的格式-->
<PatternLayout pattern="${log_pattern}"/>
</console> <!-- 所有的日志信息会打印到此文件中,append=false每次启动程序会自动清空 -->
<!-- <File name="all" fileName="${file_path}/all.log" append="true">
<PatternLayout pattern="${log_pattern}"/>
</File>--> <!--
该RollingFile存储INFO级别的日志,
默认存储到 fileName 文件中
超过SizeBasedTriggeringPolicy的设定值,则存储到 filePattern 文件中
-->
<RollingFile name="RollingFileDebug" fileName="${file_path}/rolling-debug.log"
filePattern="${file_path}/${backup_folder}/debug${backup_file_suffix}">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<Filters>
<ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="INFO" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters> <!-- 写入日志文件的模板 -->
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${file_max_size}"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,超过该数量,会滚动删除前面的记录 -->
<DefaultRolloverStrategy max="10"/>
</RollingFile>
<RollingFile name="RollingFileInfo" fileName="${file_path}/rolling-info.log"
filePattern="${file_path}/${backup_folder}/info${backup_file_suffix}">
<Filters>
<ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<!-- 写入日志文件的模板 -->
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${file_max_size}"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,超过该数量,会滚动删除前面的记录 -->
<DefaultRolloverStrategy max="10"/>
</RollingFile> <RollingFile name="RollingFileWarn" fileName="${file_path}/rolling-warn.log"
filePattern="${file_path}/${backup_folder}/warn${backup_file_suffix}">
<Filters>
<ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${file_max_size}"/>
</Policies>
</RollingFile> <RollingFile name="RollingFileError" fileName="${file_path}/rolling-error.log"
filePattern="${file_path}/${backup_folder}/error${backup_file_suffix}">
<Filters>
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="${log_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="${file_max_size}"/>
</Policies>
</RollingFile> </appenders> <!-- 只有定义了logger并使用appender-ref,appender才会生效 -->
<loggers>
<AsyncLogger name="com.hongcan.srv.basetest" additivity="false" includeLocation="true">
<appender-ref ref="RollingFileInfo" />
<appender-ref ref="RollingFileDebug" />
<appender-ref ref="RollingFileWarn" />
<appender-ref ref="RollingFileError" />
</AsyncLogger> <AsyncLogger name="io.netty" level="debug" additivity="false" includeLocation="true">
<appender-ref ref="RollingFileDebug"/>
</AsyncLogger> <!-- 正式环境下,要求关闭console -->
<root level="all">
<appender-ref ref="Console"/>
</root> <!--注: 防止 Log4j2 退出时报OOME
1 混合异步和同步Logger;root logger 为同步,其它为异步(如果additivity为false同步也行)
2 AsyncLogger 的additivity属性设置为false
-->
</loggers> </configuration>

关键的配置是这样的:

<Filters>
    <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
    <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
    <ThresholdFilter level="INFO" onMatch="DENY" onMismatch="NEUTRAL"/>
    <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>

ThreholdFilter的属性 onMismatch的值 NEUTRAL决定了如何输出。

以上的配置就是这么一个意思,如果日志级别是ERROR,WARN,INFO的时候,那么就拒绝。如果不是,那么就让debug过滤器处理。

而debug过滤器的意思就是:如果匹配就接收,如果不匹配那么就拒绝!

四、控制台输出与调试

一般开发的时候,会要求控制台输出,要做到这一点非常简单,按照如下配置即可。

<!--定义appender-->
<appenders>
<!--控制台的输出配置-->
<console name="Console" target="SYSTEM_OUT">
<!-- 设置控制台只输出INFO及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
<!--输出日志的格式-->
<PatternLayout pattern="${log_pattern}"/>
</console>
</appenders> <!-- 只有定义了logger并使用appender-ref,appender才会生效 -->
<loggers>
<!-- 正式环境下,要求关闭console -->
<root level="all">
<appender-ref ref="Console"/>
</root>
</loggers>

分别定义好appender和logger即可。 通过控制level来控制控制台的输出。

如果使用springboot,那么可以通过多定义一个log4j的配置文件,例如定义为logj2-dev.xml,并在application-dev.properties中指定。

五、发送邮件

有时候,还需要发送邮件。

具体可以参考 https://blog.csdn.net/david_pfw/article/details/85846351

这里模仿了下:

<!--定义appender-->
<appenders>
<SMTP name="Mail" subject="警告日志测试" to="lzfhope@163.com" from="lzfdev@163.com"
smtpHost="smtp.163.com"
smtpPort="25"
smtpPassword="xxxxxxx"
smtpProtocol="smtp"
smtpUsername="lzfdev@163.com"
smtpDebug="true"
bufferSize="50"
>
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
</SMTP> <Async name="AsyncMail">
<appender-ref ref="Mail"/>
</Async> </appenders> <!-- 只有定义了logger并使用appender-ref,appender才会生效 -->
<loggers>
<!-- 正式环境下,要求关闭console -->
<root level="all">
<appender-ref ref="Console"/>
<appender-ref ref="AsyncMail" />
</root>
</loggers>

此外,要导入

<!-- https://mvnrepository.com/artifact/com.sun.mail/javax.mail -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>

如果配置都没有问题,还出现如下异常:

javax.mail.AuthenticationFailedException: 550 User has no permission

那么需要到163开启smtp权限,具体参考:https://blog.csdn.net/AngleFlyyy/article/details/107765541

然后,把这个提示的密码替换到配置文件中,假定这个密码是:UWPPVUQOPGDGWC00

那么log4j2.xml中对应如下:

<!--定义appender-->
<appenders>
<! -- smtpPassword不能是原始的密码,例如原始密码是123,那么不能输入123,而应该是163 smtp配置提示的密码 -->
<SMTP name="Mail" subject="警告日志测试" to="lzfhope@163.com" from="lzfdev@163.com"
smtpHost="smtp.163.com"
smtpPort="25"
smtpPassword="UWPPVUQOPGDGWC00"
smtpProtocol="smtp"
smtpUsername="lzfdev@163.com"
smtpDebug="true"
bufferSize="50"
>
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
</SMTP> <Async name="AsyncMail">
<appender-ref ref="Mail"/>
</Async> </appenders>

这样就可以发送邮件了,如下图:

如果还有问题,那么开启下调试: smtpDebug="true"

六、小结

logj4j2比较常会用就这些。但它的功能又远远不止这些!

日志之log4j2和springboot的更多相关文章

  1. 【SpringBoot】Logback日志框架介绍和SpringBoot整合实战

    ========================11.Logback日志框架介绍和SpringBoot整合实战 2节课================================ 1.新日志框架L ...

  2. log4j 和 log4j2 在springboot中的性能对比

    文章链接: https://pengcheng.site/2019/11/17/log4j-he-log4j2-zai-springboot-zhong-de-xing-neng-dui-bi/ 前言 ...

  3. 笔记:MyBatis 日志显示-log4j2

    在ClassPath路径创建log4j2.xml配置文件,增加如下日志配置: <?xml version="1.0" encoding="UTF-8"?& ...

  4. 11、Logback日志框架介绍和SpringBoot整合实战 2节课

    1.新日志框架LogBack介绍     简介:日志介绍和新日志框架Logback讲解 1.常用处理java的日志组件 slf4j,log4j,logback,common-logging 等     ...

  5. IDEA整合日志框架Log4j2+Slf4j详细配置过程

    日志框架这么多,他们之间到底是什么关系呢?笼统的讲就是slf4j是一系列的日志接口,而log4j2.logback是具体实现了接口功能的日志框架.现在的主流日志接口都使用slf4j,而日志的实现就见仁 ...

  6. 小D课堂 - 零基础入门SpringBoot2.X到实战_第11节 Logback日志框架介绍和SpringBoot整合实战_45、SpringBoot2.x日志讲解和Logback配置实战

    笔记 2.SpringBoot2.x日志讲解和自定义Logback配置实战     简介:讲解SpringBoot2.x整合Logback配置实战 1.官网介绍:https://docs.spring ...

  7. 日志框架 log4j2 全解析

    概述 logging翻译为日志记录 那问题是什么是日志? 日志实际上是日记的一种,用于记录某个时间点发生了什么事情,比如大学老师的教学日志,工作日志等 为什么要记录日志? 在实际生活中记录日志主要为了 ...

  8. 讲武德,你们要的高性能日志工具 Log4j2,来了

    Log4j 介绍过了,SLF4J 介绍过了,Logback 也介绍过了,你以为日志系列的文章就到此终结了? 不不不,我告诉你,还有一个 Log4j 2,顾名思义,它就是 Log4j 的升级版,就好像手 ...

  9. 怎样在idea添加log日志 以及log4j2配置文件解读

    网上找了很多篇文章,就数这篇比较全,从下载到配置都有讲到,解决从0开始接触java日志文件添加的各位同学.参考文章:https://www.cnblogs.com/hong-fithing/p/769 ...

  10. spring boot更换日志为log4j2

    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- ...

随机推荐

  1. dotnet C# 如何使用 MemoryFailPoint 检查是否有足够的内存资源来执行操作

    在 dotnet 里面的 MemoryFailPoint 可用来测试当前进程是否还能分配申请给定大小的内存空间,这个是一个高级编程的类型,大部分情况下都不需要用到.本文内容由 New Bing 编写, ...

  2. WPF 对接 Vortice 调用 D2D 使用 IWICBitmap 离屏渲染

    通过 Vortice 库可以使用非常底层的方式调用到 Direct2D1 进行渲染,本文将使用 D2D 离屏渲染到 IWICBitmap 上,再使用一点点反射黑科技,直接将此 IWICBitmap 对 ...

  3. WPF 框架开发 调试和开发 XAML 构建过程的 PresentationBuildTasks 方法

    阅读本文,你可以了解如何编写开发和调试 XAML 构建为 Baml 和 g.cs 文件的过程和工具.本文也适合想要了解 WPF 的 XAML 构建过程的开发者阅读,本文提供了可以断点调试 WPF 的 ...

  4. Git的操作使用

    Git结构: # 工作区:当前编辑的区域 # 缓存区:add之后的区域 # 本地仓库:commit之后的区域 # 远程仓库:GitHub,gitlab,码云... 一.Git的初步认识 一.Git是什 ...

  5. WebKit Inside: CSS 样式表的解析

    CSS 全称为层叠样式表(Cascading Style Sheet),用来定义 HTML 文件最终显示的外观. 为了理解 CSS 的加载与解析,需要对 CSS 样式表的组成,尤其是 CSS Sele ...

  6. Java工具类库大总结

    1. Java自带工具方法 1.1 List集合拼接成以逗号分隔的字符串 // 如何把list集合拼接成以逗号分隔的字符串 a,b,c List<String> list = Arrays ...

  7. nim 3. 各种集合

    其实我挺想先去学习一下nim的模块系统,毕竟我决定暂时放弃学习golang,就是因为感觉他的模块和包方面的设计,不像c#+nuget的组合那么舒服. 但是这里还是先学习一下集合吧,感觉这方面nim很有 ...

  8. Akima算法

    测量数据的内插已有各种方法,如线性内插.多项式内插.样条函数插值等,但这里的Akima插值法具有独特的优点. 线性内插只顾及其附近两点的影响. 多项式内插时,低阶多项式由于参数较少,内插精度很低,而使 ...

  9. 记一次asp.net 8 服务器爆满的解决过程

    1.描述一下服务器配置: 一台2c4g的centos,做api接口反代 一台8c16g的windows 2019 作为实际服务器,跑了iis,sql server,mongodb,redis 2.业务 ...

  10. FFmpeg开发笔记(二十一)Windows环境给FFmpeg集成AVS3解码器

    ​AVS3是中国AVS工作组制定的第三代音视频编解码技术标准,也是全球首个已推出的面向8K及5G产业应用的视频编码标准.AVS工作组于2019年3月9日完成第三代AVS视频标准(AVS3)基准档次的制 ...