五SpringBoot整合log4j2
Posted Java栈点
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了五SpringBoot整合log4j2相关的知识,希望对你有一定的参考价值。
概述
代码易写,bug难改。相信很多从事Java开发的码友们都遇到过各种各样的线上bug,而解决bug依靠的就是珍贵的log信息。本文将着重讲解SpringBoot中整合Log4j2,同时也会做一些日志框架之间的横向对比,再也不用担心“log用时方恨少”的情况了。
日志框架
1. 常用日志框架
java.util.logging:Java原生日志系统,在受到Log4j启发后,于Java1.4中引入的一个全新API。
Log4j:是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIXSyslog守护进程等;我们也可以控制每一条日志的输出格式。
Logback:是由log4j创始人设计的又一个开源日志组件,可以理解为升级款。
Log4j2:是log4j1.x和logback的改进版,可以配置全局异步或者混合异步模式,使得日志的吞吐量、性能比log4j1.x提高10倍,同时利用JDK1.5的并发特性降低了死锁发生的概率,而且配置更加简单灵活。
2. 性能对比
这里引用网上对相关日志框架性能测评结果:
对比结果显而易见,原文在这里
3. 日志门面
什么是简单日志门面?
对应的英文为Simple Logging Facade,是存取日志的标准接口,真正记录日志的功能由具体的日志框架去实现,比如java.util.logging, logback, log4j,slf4j-simple等。
日志门面有哪些?具体实现日志功能的框架有哪些?
常见简单日志门面:jcl,slf4j
常见日志实现类框架:log4j,logback,jul(java.util.logging)
为什么使用日志门面?
从软件设计上来说,是遵循解耦合的原则和适应灵活多变的市场需求,达到以不变应万变的效果。日志门面模式的原型在23种设计模式中对应的是外观模式:该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
可以抽象的将日志门面理解为应用程序与日志框架之间的中间件,起到解耦合的作用,无论日志框架怎么变更,都不会影响到应用程序的正常运行。
日志门面-slf4j
slf4j的本质就是门面服务,定义了一套通用的标准接口,并非真正实现了日志的输出功能,具体的实现框架可以使用Log4j、logback、Log4j2等。
而我们作为Java攻城狮,个人比较推荐的方案就是slf4j + log4j,前者是个优秀的通用的API集合,屏蔽各个日志框架之间的差异性。后者(log4j/log4j2)的性能表现上文可见那是相当的厉害啊,傲视群雄啊…因此,我们在项目当中,可不要再引用什么log4j、JUL等相关API了,直接换用日志门面的通用API,以后哪怕换日志框架,也不会对系统造成很大的影响。
整合log4j2基本流程
1. 修改POM文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 排除掉SpringBoot的默认log配置 -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--log4j2启动类-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
2. 添加Log4j2的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!--
log4j2使用说明:1. 使用方式:private static final Logger logger = LoggerFactory.getLogger(实际类名.class);
2、特别说明:(1)需要注意日志文件备份数和日志文件大小,注意预留目录空间。(2)实际部署的时候需要将Properties中的路径修改为Linux路径。(3)切记不要使用LogManager.getLogger(xxx.class);等API接口,不够规范且不利于日志框架的变更。-->
<configuration status="info">
<!-- log4j2配置中的公共变量 -->
<Properties>
<!--
格式化输出:%date:表示日期
%thread:表示线程名
%-5level:级别从左显示5个字符宽度
%msg:日志消息
%n:表示换行符
%logger{36}:表示Logger名字最长36个字符
-->
<!-- 定义日志记录的固定格式 -->
<property name="LOG_INFO_STYLE" value="[timi:] %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n" />
<!-- 配置日志文件的存储位置 -->
<property name="FILE_PATH" value="/Users/zhengwei/Documents/SpringBoot/log-file/logs" />
<!-- 配置日志文件的名称 -->
<property name="FILE_NAME" value="demo-log" />
</Properties>
<appenders>
<!--控制台输出日志的配置-->
<Console name="Console" target="SYSTEM_OUT">
<!--控制台只输出debug及以上级别的信息-->
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
<!--日志输出的格式-->
<PatternLayout pattern="${LOG_INFO_STYLE}"/>
</Console>
<!--这个会打印出所有的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/${FILE_NAME}-info.log"
filePattern="${FILE_PATH}/${FILE_NAME}-info-%d{yyyy-MM-dd}_%i.log.gz">
<!-- 当前文件记录info及以上级别的信息,其他信息则忽略-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_INFO_STYLE}"/>
<Policies>
<TimeBasedTriggeringPolicy modulate="true" interval="12"/>
<SizeBasedTriggeringPolicy size="500MB" />
</Policies>
<!--文件夹下最多的文件个数,超过该数量则覆盖旧的日志文件-->
<DefaultRolloverStrategy max="20" />
</RollingFile>
<!--定义出现错误的日志记录规则-->
<RollingFile name="RollingFileError" fileName="${FILE_PATH}/${FILE_NAME}-error.log"
filePattern="${FILE_PATH}/${FILE_NAME}-error-%d{yyyy-MM-dd}_%i.log.gz">
<!-- 当前文件记录error及以上级别的信息,其他信息则忽略-->
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_INFO_STYLE}"/>
<Policies>
<!--日志滚动时间-->
<TimeBasedTriggeringPolicy modulate="true" interval="12"/>
<!--日志滚动大小-->
<SizeBasedTriggeringPolicy size="200MB" />
</Policies>
<!--文件夹下最多的文件个数,超过该数量则覆盖旧的日志文件-->
<DefaultRolloverStrategy max="10" />
</RollingFile>
<!-- 记录执行过的sql相关日志信息 -->
<RollingFile name="RollingFileSql" fileName="${FILE_PATH}/${FILE_NAME}-sql.log"
filePattern="${FILE_PATH}/${FILE_NAME}-sql-%d{yyyy-MM-dd}_%i.log.gz">
<PatternLayout pattern="${LOG_INFO_STYLE}"/>
<Policies>
<SizeBasedTriggeringPolicy size="500MB"/>
<TimeBasedTriggeringPolicy modulate="true" interval="12"/>
</Policies>
</RollingFile>
</appenders>
<!--定义loggers,只有定义了logger并引入appender,appender才会生效-->
<loggers>
<!--建立一个默认的root的logger-->
<root level="info">
<appender-ref ref="Console"/>
<appender-ref ref="RollingFileInfo"/>
<appender-ref ref="RollingFileError"/>
</root>
<!-- 打印sql日志信息 -->
<logger name="com.example.demo.helloworld.dao" level="debug" additivity="false">
<appender-ref ref="Console"/>
<appender-ref ref="RollingFileSql"/>
</logger>
</loggers>
</configuration>
注:该配置文件生成的log分为三类(可以自行添加分类):info级别、error级别、SQL日志。可以根据需求自行调整。
log4j2配置详解
log4j2的配置文件结构:
<Configuratio 自定义属性....>
<Properties>
<property ..../>
</Properties>
<Appenders>
<Console ....>
....
</Console>
<RollingFile ....>
....
</RollingFile>
</Appenders>
<loggers>
<root ....>
....
</root>
<logger ....>
....
</logger>
</loggers>
</Configuration>
Configuration:整个log4j2配置文件的根节点。
参数 | 含义 |
---|---|
status | 指定log4j2内部日志的输出级别 |
monitorInterval | 指定log4j2自动重新检查配置文件的间隔时间,单位:s |
package | 定义log4j2插件的类所在的包名 |
Properties:定义配置文件中的公共变量:日志文件路径、日志文件名前缀、单条日志记录的格式定义等。
参数 | 含义 |
---|---|
property | 定义固定格式参数信息 |
Appenders:在其子节点中定义日志文件的输出目的地,比如:控制台、不同级别日志输出到不同文件等。
Console节点:控制日志输出到控制台。
参数 | 含义 |
---|---|
name | 定义Appender的名称 |
target | 默认SYSTEM_OUT,也可修改为SYSTEM_ERR |
File节点:定义输出到指定位置的文件的Appender
参数 | 含义 |
---|---|
name | 定义Appender的名称 |
fileName | 输出日志全路径的文件名 |
RollingFile节点:定义超过指定大小或者什么时候自动创建新的文件的Appender
参数 | 含义 |
---|---|
name | 定义Appender的名称 |
fileName | 输出日志全路径的文件名 |
filePattern | 指定发生滚动后的旧日志归档名称,可以定义为压缩文件格式 |
注:这三个节点都有一个共同子节点
Loggers:有两个子节点:logger、root
root:子节点,用来定义项目的根日志器。
参数 | 含义 |
---|---|
level | 定义日志的8个输出级别 |
AppenderRef | root的一个子节点,指定日志器输出到哪个Appender |
logger:
参数 | 含义 |
---|---|
level | 定义日志的8个输出级别 |
AppenderRef | root的一个子节点,指定日志器输出到哪个Appender |
name | 指定Logger的名称,通常为类全名或类所在的包名,使用Logger时会根据这个名称来查找 |
总结
总的来说,整合log4j2日志系统的流程还是相当简单的,在后续的文章中会介绍整合ELK的教程,欢迎大家继续关注,也希望大家多多指点,一起进步…
参考文章:https://www.cnblogs.com/qq771490826/articles/7991706.html
官方文档:https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/reference/htmlsingle/#boot-features-custom-log-configuration
感谢,请多多指教!
以上是关于五SpringBoot整合log4j2的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot整合log4j2导入新的依赖出现jar冲突解决
全栈编程系列SpringBoot整合Shiro(含KickoutSessionControlFilter并发在线人数控制以及不生效问题配置启动异常No SecurityManager...)(代码片段