五、SpringBoot整合log4j2

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_38323872/article/details/99681544

概述

代码易写,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>
  1. Configuration:整个log4j2配置文件的根节点。
参数 含义
status 指定log4j2内部日志的输出级别
monitorInterval 指定log4j2自动重新检查配置文件的间隔时间,单位:s
package 定义log4j2插件的类所在的包名
  1. Properties:定义配置文件中的公共变量:日志文件路径、日志文件名前缀、单条日志记录的格式定义等。
参数 含义
property 定义固定格式参数信息
  1. Appenders:在其子节点中定义日志文件的输出目的地,比如:控制台、不同级别日志输出到不同文件等。
  • Console节点:控制日志输出到控制台。
参数 含义
name 定义Appender的名称
target 默认SYSTEM_OUT,也可修改为SYSTEM_ERR
  • File节点:定义输出到指定位置的文件的Appender
参数 含义
name 定义Appender的名称
fileName 输出日志全路径的文件名
  • RollingFile节点:定义超过指定大小或者什么时候自动创建新的文件的Appender
参数 含义
name 定义Appender的名称
fileName 输出日志全路径的文件名
filePattern 指定发生滚动后的旧日志归档名称,可以定义为压缩文件格式

:这三个节点都有一个共同子节点<PatternLayout…/>,用于自定义输出的单条日志的格式。
4. 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

源码地址:https://github.com/zheng-weiwei/public/tree/master/springboot-log4j2

如有兴趣,可以扫描下方微信群或者qq群二维码进群,进群即送海量学习视频以及各大厂面试题,稳赚不赔!

感谢,请多多指教!

猜你喜欢

转载自blog.csdn.net/weixin_38323872/article/details/99681544