日志框架整合SpringBoot保姆级教程+日志文件拆分(附源码)

news2024/11/15 21:06:07

目录

介绍

日志概述

日志文件

调试日志

系统日志

日志框架

日志框架的作用

日志框架的价值

流行的日志框架

SLF4J日志门面

介绍

环境搭建简单测试

集成log4j

logback 

Logback简介

Logback中的组件

Logback配置文件

日志输出格式

控制台输出日志

输出日志到指定普通文件

输出日志到html文件

日志文件拆分

过滤日志等级

 异步日志

自定义logger

log4j2 

简介

特征

自动重新加载配置

高级过滤

插件架构

无垃圾机制

案例实现

日志文件拆分

SpringBoot整合

整合logBack实现日志拆分 

 整合log4j2实现日志拆分

​编辑 源码地址


介绍

日志概述

只要程序员投身在实际的学习和生产环境中,就会对日志的重要性有着充分的认知,尤其是对于 Web 以及更高级的应用。在很多情况下,日志可能是我们了解应用如何执行的唯一方式。

但是现实是很多程序员对于日志的记录的认知比较肤浅,认为日志的记录输出是一件很简单而且会自动发生的事情,所以会经常忽略和日志相关的问题。

所以本课程主要就是针对于对于日志概念以及日志的框架不太熟悉的这类开发人群,更加详细且真实的体会日志为我们在开发和生产环境当中所带来的好处。

Java 语言的强大之处就是因为它强大而且成熟的生态体系。其中包括日志框架,就有很多成熟的开源资源可以直接使用。

日志文件

日志文件是用于记录系统操作事件的文件集合。它具有处理历史数据、诊断问题的追踪以及理解系统的活动等重要的作用。

调试日志

在软件开发中,我们要去经常的调试程序,或者做一些状态的输出,便于我们查询程序的运行状况。为了让我们能够更加灵活且方便的控制这些调试信息,我们肯定是需要更加专业的日志技术。我们平时在调试程序的过程中所使用的肯定就是专业开发工具自带的debug功能,可以实时查看程序运行情况,但不能有效保存运行情况的信息。调试日志是能够更加方便的去“重现”这些问题。

系统日志

系统日志是用来记录系统中硬件、软件和系统相关问题的信息。同时还可以监视系统中发生的事件。用户可以通过它来检查错误发生的原因,或者寻找收到攻击是留下的痕迹。

系统日志包括系统日志、应用日志和安全日志这几种分类。

日志框架

日志框架的作用
  • 控制日志输出的内容和格式。
  • 控制日志输出的位置。
  • 日志文件相关的优化,如异步操作、归档、压缩..
  • 日志系统的维护。
  • 面向接口开发 - 日志的门面。
日志框架的价值

因为软件系统发展到了今天非常的复杂,特别是服务器的软件,涉及到的知识和内容问题非常的多。对于日志记录来讲,在某些方面使用别人研发好的成熟的框架,这就相当于让别人帮你完成一些基础的工作。让我们可以有更多的时间去关注、处理我们的业务逻辑问题。

比如事务处理,日志记录等一些安全性的问题,我们使用框架丢做,不会影响业务的开发效率。

同时框架也是在不断升级的,我们可以不断的享受框架为我们带来的好处。

流行的日志框架
  • JUL

java.util.logging JAVA原生日志框架

  • Log4j

Apache的一个开源项目

  • Logback

由Log4j之父做的另一个开源项目,业界称之为log4j后浪,一个可靠、通用且灵活的java日志框架

  • Log4j2

Log4j官方的第二个版本,各个方面都与Logback及其相似,具有插件式结构、配置文件优化等特征。SpringBoot1.4版本以后就不再支持log4j,所以第二个版本——log4j2应运而生。

  • JCL

日志门面

  • SLF4J

日志门面

SLF4J日志门面

介绍

    简单日志门面(Simple Logging Facade For Java)SLF4J主要是为了给Java日志访问提供一套标准、规范的API框架,其主要意义在于提供接口,具体的实现可以交由其他日志框架,例如 log4j和 logback等。当然slf4j自己也提供了功能较为简单的实现,但是一般很少用到。对于一般的Java项目而言,日志框架会选择slf4j-api作为门面,配上具体的实现框架(log4j、logback等),中间使用桥接器完成桥接。所以我们可以得出 SLF4J最重要的两个功能就是对于日志框架的绑定以及日志框架的桥接。

环境搭建简单测试

  引入依赖

        <!--slf4j核心依赖-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!--slf4j自带简单日志实现-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

测试日志

 

 可以看到只打印了info和error信息,因为slf4j的默认日志打印级别就是info级

集成log4j

下面使用log4j实现来进行日志的打印
导入log4j所需依赖,注意要注释掉之前得slf4j自带的简单实现依赖

logback 

Logback简介

Logback 是由 log4j 创始人设计的又一个开源日志组件。

Logback 当前分成三个模块: logback-core,logback-classic和logback-access。

logback-core 是其它两个模块的基础模块。

logback-classic 是 log4j的一个改良版本。此外 logback-classic 完整实现SLF4J API。使你可以很方便地更换成其它日志系统如 log4j或JDK14 Logging。

logback-access 访问模块与 Servlet 容器集成提供通过 Http 来访问日志的功能。

Logback中的组件

  • Logger:日志的记录器,

主要用于存放日志对象,也可以定义日志类型、级别。

  • Appender:用于指定日志输出的目的地,目的地可以是控制台、文件、数据库等等。
  • Layout:负责把事件转换成字符串,格式化的日志信息的输出。在Logback 中Layout 对象被封装在 encoder 中.也就是说我们未来使用的 encoder 其实就是 Layout

Logback配置文件

Logback提供了3种配置文件。

  • logback.groovy
  • logback-test.xml
  • logback.xml

如果都不存在则采用默认的配置。

日志输出格式

标识符及占位符

描述

%-10level

级别,设置10个这符,左对齐

%d{yyyy-MM-dd HH:mm:ss.SSS}

日期时间

%c

当前类全限定名

%M

当前执行日志的方法

%L

行号

%thread

线程名称

%m或者%msg

输出的日志信息

%n

换行

控制台输出日志

引入所需依赖

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
        </dependency>

        <!--slf4j日志门面 核心依赖-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.32</version>
        </dependency>

        <!--
           logback-core是logback-classic的基础模块
           logback-classic已经涵盖了 logback-core,
           Maven有依赖传递性,会自动依赖logback-core
        -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.10</version>
        </dependency>

在资源目录下新建xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>

    <!--
        <property name="" value=""></property>
        配置文件通用属性,通过${name}的形式取值
    -->

    <property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] 日志级别:[%-5level] %c %M %L %m%n"></property>


    <!-- 控制台Appender -->
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <!--
            输出目标的配置,
            System.out:以黑色字体(默认)
            System.err:红色字体
        -->
        <target>
            System.err
        </target>
        <!-- 日志输出格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>

    <!--
        日志记录器配置,可以配置多个Appender,进行多方向的日志输出
        root => rootLogger
        level:  表示日志级别
    -->
    <root level="ALL">
        <appender-ref ref="consoleAppender"/>
    </root>

</configuration>

测试:

 

输出日志到指定普通文件

我们在部署项目到服务器里通常都是直接通过日志文件进行查看日志的,而这时就需要将日志信息输出到指定位置的指定文件中

添加输出日志文件配置

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>

    <!--
        <property name="" value=""></property>
        配置文件通用属性,通过${name}的形式取值
    -->

    <property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] 日志级别:[%-5level] %c %M %L %m%n"></property>
<!--    日志文件输出路径-->
    <property name="logDir" value="D:/javaPro/log/logback/log"></property>
<!--    保存的日志文件名-->
    <property name="fileName" value="logback.log"></property>
    <!--文件appender,默认是以追加日志的形式进行输出的-->
    <appender name="fileAppender" class="ch.qos.logback.core.FileAppender">
        <!--输出文件位置-->
        <file>${logDir}//${fileName}</file>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>



    <!-- 控制台Appender -->
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <!--
            输出目标的配置,
            System.out:以黑色字体(默认)
            System.err:红色字体
        -->
        <target>
            System.err
        </target>
        <!-- 日志输出格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>

    <!--
        日志记录器配置,可以配置多个Appender,进行多方向的日志输出
        root => rootLogger
        level:  表示日志级别
    -->
    <root level="ALL">
        <appender-ref ref="consoleAppender"/>
        <appender-ref ref="fileAppender"/>
    </root>

</configuration>

启动测试:

 

来到xml文件中配置的文件输出位置

 

 可以看到控制台的日志信息已经输出到logback.log文件中了,此时再重启测试,观察日志文件信息的变化:

可以看到日志信息是默认进行追加,不是覆盖

输出日志到html文件

在输出日志时,还可以将日志文件输出为html文件,来进行可读性比较好的阅读

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>

    <!--
        <property name="" value=""></property>
        配置文件通用属性,通过${name}的形式取值
    -->

    <property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] 日志级别:[%-5level] %c %M %L %m%n"></property>
<!--    日志文件输出路径-->
    <property name="logDir" value="D:/javaPro/log/logback/log"></property>
<!--    保存的日志文件名-->
    <property name="fileName" value="logback.log"></property>
    <!--文件appender,默认是以追加日志的形式进行输出的-->
    <appender name="fileAppender" class="ch.qos.logback.core.FileAppender">
        <!--输出文件位置-->
        <file>${logDir}//${fileName}</file>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>


    <property name="htmlFileName" value="logback.html"></property>
    <property name="htmlPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS}%thread%-5level%c%M%L%m"></property>
    <!--HTML文件appender-->
    <appender name="htmlFileAppender" class="ch.qos.logback.core.FileAppender">
        <!--输出文件位置-->
        <file>${logDir}//${htmlFileName}</file>
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="ch.qos.logback.classic.html.HTMLLayout">
                <pattern>${htmlPattern}</pattern>
            </layout>
        </encoder>
    </appender>
    



    <!-- 控制台Appender -->
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <!--
            输出目标的配置,
            System.out:以黑色字体(默认)
            System.err:红色字体
        -->
        <target>
            System.err
        </target>
        <!-- 日志输出格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>

    <!--
        日志记录器配置,可以配置多个Appender,进行多方向的日志输出
        root => rootLogger
        level:  表示日志级别
    -->
    <root level="ALL">
        <appender-ref ref="consoleAppender"/>
        <appender-ref ref="fileAppender"/>
        <appender-ref ref="htmlFileAppender"/>
    </root>

</configuration>

启动测试:

 可以看到html版本的日志文件可读性和ui要比普通文件要美观一些,但是html文件比较占用内存,所以在实际开发中,如果项目的日志文件比较多的情况下并不推荐使用html版

日志文件拆分

在实际开发中,项目的日志有时候会非常的多,此时日志文件如果不进行拆分将会导致日志文件过大,有时甚至上G,所以可以对日志进行配置拆分策略来进行解决

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>

    <!--
        <property name="" value=""></property>
        配置文件通用属性,通过${name}的形式取值
    -->

    <property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] 日志级别:[%-5level] %c %M %L %m%n"></property>
<!--    日志文件输出路径-->
    <property name="logDir" value="D:/javaPro/log/logback/log"></property>
<!--    保存的日志文件名-->
    <property name="fileName" value="logback.log"></property>
    <!--文件appender,默认是以追加日志的形式进行输出的-->
    <appender name="fileAppender" class="ch.qos.logback.core.FileAppender">
        <!--输出文件位置-->
        <file>${logDir}//${fileName}</file>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>


    <property name="htmlFileName" value="logback.html"></property>
    <property name="htmlPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS}%thread%-5level%c%M%L%m"></property>
    <!--HTML文件appender-->
    <appender name="htmlFileAppender" class="ch.qos.logback.core.FileAppender">
        <!--输出文件位置-->
        <file>${logDir}//${htmlFileName}</file>
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="ch.qos.logback.classic.html.HTMLLayout">
                <pattern>${htmlPattern}</pattern>
            </layout>
        </encoder>
    </appender>




    <!-- 控制台Appender -->
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <!--
            输出目标的配置,
            System.out:以黑色字体(默认)
            System.err:红色字体
        -->
        <target>
            System.err
        </target>
        <!-- 日志输出格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>



    <!--可拆分归档的appender-->
    <appender name="rollFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
        <file>${logDir}/roll_logback.log</file>
        <!--指定拆分规则-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--按照时间和压缩格式声明文件名,压缩格式gz-->
            <fileNamePattern>${logDir}/roll_logback.%d{yyyy-MM-dd}.log%i.gz</fileNamePattern>
            <!--按照文件大小进行拆分-->
            <maxFileSize>2KB</maxFileSize>
        </rollingPolicy>
    </appender>
    
    
    
    <!--
        日志记录器配置,可以配置多个Appender,进行多方向的日志输出
        root => rootLogger
        level:  表示日志级别
    -->
    <root level="ALL">
        <appender-ref ref="consoleAppender"/>
        <appender-ref ref="fileAppender"/>
        <appender-ref ref="htmlFileAppender"/>
        <appender-ref ref="rollFileAppender"/>
    </root>

</configuration>

此时在测试中书写一个for循环来进行模拟业务非常多的数据

启动测试:

 

 

查看gz压缩文件

 可以看到日志文件已经进行自动拆分了,当日志文件达到2kb大小时就可以进行正常的拆分

过滤日志等级

还可以通过设置过滤器对日志信息进行等级过滤

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>

    <!--
        <property name="" value=""></property>
        配置文件通用属性,通过${name}的形式取值
    -->

    <property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] 日志级别:[%-5level] %c %M %L %m%n"></property>
<!--    日志文件输出路径-->
    <property name="logDir" value="D:/javaPro/log/logback/log"></property>
<!--    保存的日志文件名-->
    <property name="fileName" value="logback.log"></property>
    <!--文件appender,默认是以追加日志的形式进行输出的-->
    <appender name="fileAppender" class="ch.qos.logback.core.FileAppender">
        <!--输出文件位置-->
        <file>${logDir}//${fileName}</file>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>


    <property name="htmlFileName" value="logback.html"></property>
    <property name="htmlPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS}%thread%-5level%c%M%L%m"></property>
    <!--HTML文件appender-->
    <appender name="htmlFileAppender" class="ch.qos.logback.core.FileAppender">
        <!--输出文件位置-->
        <file>${logDir}//${htmlFileName}</file>
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="ch.qos.logback.classic.html.HTMLLayout">
                <pattern>${htmlPattern}</pattern>
            </layout>
        </encoder>
    </appender>




    <!-- 控制台Appender -->
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <!--
            输出目标的配置,
            System.out:以黑色字体(默认)
            System.err:红色字体
        -->
        <target>
            System.err
        </target>
        <!-- 日志输出格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>



    <!--可拆分归档的appender-->
    <appender name="rollFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
        <file>${logDir}/roll_logback.log</file>
        <!--指定拆分规则-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--按照时间和压缩格式声明文件名,压缩格式gz-->
            <fileNamePattern>${logDir}/roll_logback.%d{yyyy-MM-dd}.log%i.gz</fileNamePattern>
            <!--按照文件大小进行拆分-->
            <maxFileSize>2KB</maxFileSize>
        </rollingPolicy>
    </appender>


    <!--使用过滤器,进行细粒度控制-->
    <appender name="consoleFilterAppender" class="ch.qos.logback.core.ConsoleAppender">
        <target>
            System.err
        </target>
        <!-- 日志输出格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>

        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <!--高于level中设置的级别,则打印日志-->
            <onMatch>ACCEPT</onMatch>
            <!--低于level中设置的级别,则屏蔽-->
            <onMismatch>DENY</onMismatch>
        </filter>

    </appender>



    <!--
        日志记录器配置,可以配置多个Appender,进行多方向的日志输出
        root => rootLogger
        level:  表示日志级别
    -->
    <root level="ALL">
<!--        <appender-ref ref="consoleAppender"/>-->
<!--        <appender-ref ref="fileAppender"/>-->
<!--        <appender-ref ref="htmlFileAppender"/>-->
<!--        <appender-ref ref="rollFileAppender"/>-->
        <appender-ref ref="consoleFilterAppender"/>
    </root>

</configuration>

启动测试:

可以看到由于过滤器中设置的是过滤出error等级及以上的信息,这里没有比error更高等级的日志信息了,所以只有error等级信息输出

 异步日志

我们将日志appender进行调整回原先的打印appender,然后加入一些测试数据,观察其执行的顺序

 启动测试:

可以看到无论启动多少次,下面的模拟的业务代码1=======这种代码都是在日志信息打印结束后才进行打印,这说明此时的日志是同步执行的

由此得出会出现的问题:
只要是在记录日志,那么系统本身的功能就处于一种停滞的状态当日志记录完毕后,才会执行其他的代码如果日志记录量非常庞大的话,那么我们对于系统本身业务代码的执行效率会非常低
此时可以使用logback提供的异步日志的功能

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>

    <!--
        <property name="" value=""></property>
        配置文件通用属性,通过${name}的形式取值
    -->

    <property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] 日志级别:[%-5level] %c %M %L %m%n"></property>
<!--    日志文件输出路径-->
    <property name="logDir" value="D:/javaPro/log/logback/log"></property>
<!--    保存的日志文件名-->
    <property name="fileName" value="logback.log"></property>
    <!--文件appender,默认是以追加日志的形式进行输出的-->
    <appender name="fileAppender" class="ch.qos.logback.core.FileAppender">
        <!--输出文件位置-->
        <file>${logDir}//${fileName}</file>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>


    <property name="htmlFileName" value="logback.html"></property>
    <property name="htmlPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS}%thread%-5level%c%M%L%m"></property>
    <!--HTML文件appender-->
    <appender name="htmlFileAppender" class="ch.qos.logback.core.FileAppender">
        <!--输出文件位置-->
        <file>${logDir}//${htmlFileName}</file>
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="ch.qos.logback.classic.html.HTMLLayout">
                <pattern>${htmlPattern}</pattern>
            </layout>
        </encoder>
    </appender>




    <!-- 控制台Appender -->
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <!--
            输出目标的配置,
            System.out:以黑色字体(默认)
            System.err:红色字体
        -->
        <target>
            System.err
        </target>
        <!-- 日志输出格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>



    <!--可拆分归档的appender-->
    <appender name="rollFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
        <file>${logDir}/roll_logback.log</file>
        <!--指定拆分规则-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--按照时间和压缩格式声明文件名,压缩格式gz-->
            <fileNamePattern>${logDir}/roll_logback.%d{yyyy-MM-dd}.log%i.gz</fileNamePattern>
            <!--按照文件大小进行拆分-->
            <maxFileSize>2KB</maxFileSize>
        </rollingPolicy>
    </appender>


    <!--使用过滤器,进行细粒度控制-->
    <appender name="consoleFilterAppender" class="ch.qos.logback.core.ConsoleAppender">
        <target>
            System.err
        </target>
        <!-- 日志输出格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>

        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <!--高于level中设置的级别,则打印日志-->
            <onMatch>ACCEPT</onMatch>
            <!--低于level中设置的级别,则屏蔽-->
            <onMismatch>DENY</onMismatch>
        </filter>

    </appender>
    
<!--    添加异步任务-->
    <appender name="asyncAppender" class="ch.qos.logback.classic.AsyncAppender">
<!--        指定异步任务执行的appender-->
        <appender-ref ref="consoleAppender"/>
    </appender>


    <!--
        日志记录器配置,可以配置多个Appender,进行多方向的日志输出
        root => rootLogger
        level:  表示日志级别
    -->
    <root level="ALL">
        <appender-ref ref="asyncAppender"/>
<!--        <appender-ref ref="consoleAppender"/>-->
<!--        <appender-ref ref="fileAppender"/>-->
<!--        <appender-ref ref="htmlFileAppender"/>-->
<!--        <appender-ref ref="rollFileAppender"/>-->
<!--        <appender-ref ref="consoleFilterAppender"/>-->
    </root>

</configuration>

 启动测试

 此时可以看到业务代码在日志信息中间就执行了,实现了异步任务的功能

自定义logger

在使用中我们还可以使用自定义的logger进行配置

启动测试

 

可以看到只打印了info及以上等级的日志

log4j2 

简介

Apache Log4j 2 是对 Log4j 的升级,它比其前身 Log4j 1.x 提供了重大改进,并提供了Logback 中可用的许多改进,同时修复了 Logback 架构中的一些问题。被誉为是目前最优秀的Java日志框架。

特征

Log4j2包含基于LMAX Disruptor 库的下一代异步记录器。在多线程场景中,异步记录器的吞吐量比 Log4j 1.x 和 Logback 高 18 倍,延迟低。

自动重新加载配置

与Logback一样,Log4j2可以在修改时自动重新加载其配置。与 Logback 不同,它会在重新配置发生时不会丢失日志事件。。

高级过滤

与 Logback 一样,Log4j2 支持基于 Log 事件中的上下文数据,标记,正则表达式和其他组件进行过滤。

此外,过滤器还可以与记录器关联。与 Logback 不同,Log4j2 可以在任何这些情况下使用通用的 Filter类。

插件架构

Log4j使用插件模式配置组件。因此,您无需编写代码来创建和配置Appender,Layout,Pattern Converter等。在配置了的情况下,Log4j自动识别插件并使用它们。

无垃圾机制

在稳定日志记录期间,Log4j2 在独立应用程序中是无垃圾的,在 Web 应用程序中是低垃圾。这减少了垃圾收集器的压力,并且可以提供更好的响应性能。目前市面上最主流的日志门面就是 SLF4J,虽然 Log4j2 也是日志门面,因为它的日志实现功能非常强大,性能优越。所以我们一般情况下还是将 Log4j2 看作是日志的实现。SLF4j+ Log4j2 的组合,是市场上最强大的日志功能实现方式,绝对是未来的主流趋势。

案例实现

由于log4j2和前面的logback在很多方面都很相似,这里只简单演示log4j2的主要功能

引入所需依赖

<!--log4j2日志门面-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.17.0</version>
        </dependency>

        <!--log4j2日志实现-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.17.0</version>
        </dependency>


        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
        </dependency>

启动测试

日志文件拆分

 		<!--slf4j日志门面-->
        <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.32</version>
        </dependency>


        <!--log4j适配器,因为log4j在slf4j之前就出现了,所以需要引入一个适配器-->
        <!-- 注意这是log4j的适配器,不是log4j2 的适配器,注意版本-->
        <!--https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
  <!--        <dependency>																-->
  <!--            <groupId>org.slf4j</groupId>						-->
  <!--            <artifactId>slf4j-log4j12</artifactId>	-->
  <!--            <version>1.7.32</version>								-->
  <!--        </dependency>																-->


        <!--log4j2适配器,虽然log4j2自己也有门面实现,但是主流都是使用slf4j的日志门面-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.17.0</version>
            <scope>test</scope>
        </dependency>

        <!--log4j2日志门面-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.17.0</version>
        </dependency>

        <!--log4j2日志实现-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.17.0</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
        </dependency>

添加log4j2.xml文件,书写拆分日志规则

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration xmlns="http://logging.apache.org/log4j/2.0/config"   status="off">

    <Properties>
        <Property name="logDir">D:/javaPro/log/logback/log4j2/log</Property>
        <Property name="fileName">log4j2.log</Property>
        <Property name="pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %m%n</Property>

        <Property name="rollLogName">roll_log.log</Property>
        <!--
            文件拆分时 存放的位置
            $${date:yyyy-MM-dd} : 根据日期当天,创建一个文件夹,例如:2021-12-26,记录当前的所有日志信息(拆分出来的日志放在这个文件夹中)
            %i:序号 从0开始
         -->
        <Property name="rollFilePattern">$${date:yyyy-MM-dd}//roll_log_%d{yyyy-MM-dd-mm}_%i.log</Property>
    </Properties>

    <Appenders>
        <!-- 控制台appender-->
        <Console name="consoleAppender" target="SYSTEM_OUT">
            <PatternLayout pattern="${pattern}"/>
        </Console>
        <!-- 文件appender-->
        <File name="fileAppender" fileName="${logDir}//${fileName}">
            <PatternLayout pattern="${pattern}"/>
        </File>

        <!--
            滚动文件appender
按照指定规则来扮日志文件
fileName: 日志文件的名字
filePattern: 日志文件拆分后文件的命名规则
        -->
        <RollingFile name="rollingFileAppender"
                     fileName="${logDir}//${rollLogName}"
                     filePattern="${logDir}//${rollFilePattern}">
            <PatternLayout pattern="${pattern}"/>

            <Policies>
                <!--在系统启动时,触发拆分规则,产生一个日志文件-->
                <OnStartupTriggeringPolicy/>
                <!--按照文件大小拆分,当fileName属性指定的文件超过该大小时,触发拆分事件-->
                <SizeBasedTriggeringPolicy size="10KB"/>
                <!--按照时间节点拆分,拆分规则就是filePattern-->
                <!--<TimeBasedTriggeringPolicy interval="1" modulate="true"/>-->
            </Policies>
            <!--在同一目录下,文件的个数限制30个,如果超出了设置的规则,则根据时间进行覆盖,新的覆盖旧的-->
            <DefaultRolloverStrategy max="30" />
        </RollingFile>

    </Appenders>

    <!-- 可以配置N多个Logger,包括Root和自定义Logger-->
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="consoleAppender"/>
            <!-- <AppenderRef ref="fileAppender"/> -->
            <AppenderRef ref="rollingFileAppender"/>
        </Root>
    </Loggers>
</Configuration>

模拟日志测试

SpringBoot整合

SpringBoot 是现今市场上最火爆用来简化 spring 开发的框架,springboot 日志也是开发中常用的日志系统。

SpringBoot 默认就是使用SLF4J作为日志门面,Logback作为日志实现来记录日志。

引入所需依赖

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


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

整合logBack实现日志拆分 

新建logback.xml文件

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <property name="pattern" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L %thread %m%n"></property>
    <property name="logDir" value="D:\\javaPro\\log\\logback\\log4j2\\log\\springbootLog\\logback"></property>

    <!--控制台日志-->
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <!--红色字体打印-->
        <target>
            System.err
        </target>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>

    <!--可拆分归档的文件日志-->
    <appender name="rollFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志输出格式-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
        <!--文件位置-->
        <file>${logDir}//roll_logback.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--按照时间和压缩格式声明文件名,压缩格式gz-->
            <fileNamePattern>${logDir}//roll_logback.%d{yyyy-MM-dd}.log%i.gz</fileNamePattern>
            <!-- 按照文件大小拆分,当日志文件达到这个大小时,将该文件以压缩格式归档 -->
            <maxFileSize>1KB</maxFileSize>
        </rollingPolicy>
    </appender>

    <!--自定义logger-->
    <logger name="com.example" level="info" additivity="false">
        <appender-ref ref="consoleAppender"/>
        <appender-ref ref="rollFileAppender"/>
    </logger>

</configuration>

 

启动测试

 

查看指定文件夹下的日志文件是否拆分

 

 整合log4j2实现日志拆分

由于log4j2性能的强大,以及当今市场上越来越多的项目选择使用slf4j+log4j2的组合,springboot默认使用的是slf4j+logback的组合,但我们可以将默认的logback置换为log4j2.

启动器的依赖,间接的依赖logback,所以需要将之前的环境中,logback的依赖去除
 

			
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <!--排除掉原始日志依赖,达到去除logback依赖的目的-->
                <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>		

添加log4j2.xml文件

<?xml version="1.0" encoding="UTF-8" ?>

<Configuration xmlns="http://logging.apache.org/log4j/2.0/config"   status="off">

    <Properties>
        <Property name="logDir">D:\\javaPro\\log\\logback\\log4j2\\log\\springbootLog\\log4j2</Property>
        <Property name="rollLogName">roll_log.log</Property>
        <Property name="rollFilePattern">$${date:yyyy-MM-dd}//roll_log_%d{yyyy-MM-dd-mm}_%i.log</Property>
        <Property name="pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %m%n</Property>
    </Properties>

    <Appenders>
        <!-- 控制台appender-->
        <Console name="consoleAppender" target="SYSTEM_ERR">
            <PatternLayout pattern="${pattern}"/>
        </Console>

        <RollingFile name="rollingFileAppender"
                     fileName="${logDir}//${rollLogName}"
                     filePattern="${logDir}//${rollFilePattern}">
            <PatternLayout pattern="${pattern}"/>
            <Policies>
                <OnStartupTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="10KB"/>
                <!--<TimeBasedTriggeringPolicy interval="1" modulate="true"/>-->
            </Policies>
            <DefaultRolloverStrategy max="30" />
        </RollingFile>
    </Appenders>

    <Loggers>
        <Root level="info">
            <AppenderRef ref="consoleAppender"/>
            <AppenderRef ref="rollingFileAppender"/>
        </Root>
    </Loggers>
</Configuration>

 启动测试

 源码地址

日志源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1620434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WebServer项目介绍文章【四叶专属】

Linux项目实战C轻量级Web服务器源码分析TinyWebServer 书接上文&#xff0c;学习开源项目的笔记没想到居然有不少阅读量&#xff0c;后面结合另一个前端开源项目简单做了点修改&#xff0c;没想到居然有需要的同学&#xff0c;那么我就专门为四叶开一篇文章吧&#xff0c;【源码…

【网络编程】网络编程中的基本概念及Java实现UDP、TCP客户端服务器程序(万字博文)

系列文章目录 【网络通信基础】网络中的常见基本概念 【网络编程】网络编程中的基本概念及Java实现UDP、TCP客户端服务器程序&#xff08;万字博文&#xff09; 【网络原理】UDP协议的报文结构 及 校验和字段的错误检测机制&#xff08;CRC算法、MD5算法&#xff09; 文章目…

RANSAC 配准算法

RANSAC 配准算法 1. 简介2. RANSAC步骤3. RANSAC原理4. RANSAC的优缺点5. 代码实现6. 参考 1. 简介 先讲一下背景吧。 点云配准&#xff08;Point Cloud Registration&#xff09;指的是输入两幅点云 (source 和 target) &#xff0c;输出一个变换使得变换后的source和target…

【Unity】苹果(IOS)开发证书保姆级申请教程

前言 我们在使用xcode出包的时候&#xff0c;需要用到iOS证书(.p12)和描述文件(.mobileprovision) 开发证书及对应的描述文件用于开发阶段使用&#xff0c;可以直接将 App 安装到手机上&#xff0c;一个描述文件最多绑定100台测试设备 1.证书管理 进入网站Apple Developer &…

在ubuntu20.04下迁移anaconda的目录,试验不行后,换成软连接

一、原因 随着不断的搭建不同的算法环境&#xff0c;原本在固态硬盘上安装的anaconda上占用空间越来越多。导致可用的固态硬盘空间越来越少&#xff0c;又因安装的环境太多&#xff0c;重新搭建比较费时费力。有没有直接将当前已经搭建好环境的anaconda 迁移到另外的目录呢&…

程序员过了35岁没人要?“这行越老越香”

程序员35岁失业&#xff1f;参加完OceanBase开发者大会&#xff0c;我又悟了&#xff01; 周六参加了OceanBase2024 开发者大会的现场&#xff0c;来之前我其实挺忐忑的&#xff0c;我觉得一个数据库产品的发布会&#xff0c;能有什么新鲜的东西&#xff1f; 踏入酒店的那一刻&…

monorepo搭建记录

最终文件效果 1、准备环境 npm pnpm 2、创建文件夹npm init vite // 名字可以为main&#xff08;自定义&#xff09; 创建主应用main npm init vite // 名字可以为main monorepo下创建文件夹web 创建辅助应用 例&#xff1a;react-demo&#xff0c;具体步骤&#xff1a;1、 cd…

深入理解JavaScript:对象什么时候创建

&#x1f31f; 我们在chrome浏览器中debug程序。为了好debug我们会写一些在日常开发中基本不会采用的代码书写方式。 JavaScript中创建对象有3中方式&#xff1a; 1、对象字面量&#xff1b; 2、new&#xff1b; 3、Object.create(对象)&#xff1b; 1、使用new创建对象 fun…

10分钟揭秘摘要抽取:探索信息提炼的奥秘

Introduction 本文分别介绍摘要数据集&#xff0c;摘要分类&#xff0c;摘要架构&#xff0c;相关baseline。并介绍若干篇EMNLP2023论文&#xff0c;介绍其最新工作。 1.数据集 1.1 文本摘要 DUC/TAC 英文|数据集较小|适用于传统摘要方法的评估 Gigaword 英文|启发式规则构…

【数据结构与算法】8.二叉树的基本概念|前序遍历|中序遍历|后序遍历

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更…

【Linux】iptables的应用

iptables 防火墙 防火墙是一种网络安全系统&#xff0c;它位于内部网络与外部网络&#xff08;如互联网&#xff09;之间&#xff0c;通过实施预定义的安全策略来控制网络间的通信。防火墙的主要目标是保护内部网络资源免受未经授权的访问、攻击或潜在威胁&#xff0c;同时允…

经风靡全球的 PHP 为何逐渐失去优势?

TIOBE 编程语言人气指数发布更新&#xff0c;并提出“PHP 的魔力是否正在消散&#xff1f;”的灵魂拷问。今年 4 月&#xff0c;PHP 在 TIOBE 编程语言指数榜上仅位列第 17&#xff0c;“成为其有史以来的最低排位”。 暴露 PHP 人气急剧下滑的还不只是 TIOBE 榜单。在年度 Sta…

到底什么是爬虫

1. 引言 在数据驱动的世界里&#xff0c;网络爬虫&#xff08;Web Crawling&#xff09;技术扮演着获取和处理网上数据的关键角色。无论是为了数据分析、机器学习项目的数据集构建还是简单地监测网页变化&#xff0c;学习如何创建一个基本的网页爬虫可以大大提升你的工作效率和…

JAVASE基础语法(异常、常用类)

一、异常 1.1 什么是异常 异常就是指不正常。是指代码在运行过程中可能发生错误&#xff0c;导致程序无法正常运行。 package com.atguigu.exception;public class TestException {public static void main(String[] args) {int[] arr {1,2,3,4,5};System.out.println(&quo…

【c++】探究C++中的list:精彩的接口与仿真实现解密

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好&#xff0c;本篇文章来到list有关部分&#xff0c;这一部分函数与前面的类似&#xff0c;我们简单讲解&#xff0c;重难点在模拟实现时的迭代器有关实现 目录 1.List介绍2.接…

CSS3新增特性(二)

四、2D 转换 • 属性名&#xff1a;transform &#xff08;可用于制作2D转换&#xff0c;也可用于制作3D转转换&#xff1b;2D转换是平面上的转换&#xff0c;3D转换是在三维立体空间的转换&#xff09; • 作用&#xff1a;对元素进行水平或垂直方向的移动、缩放、旋转、拉长…

你们项目日志是如何处理的???

ELK日志采集系统 1.什么是ELK ELK 是一套流行的数据搜索、分析和可视化解决方案&#xff0c;由三个开源项目组成&#xff0c;每个项目的首字母合起来形成了“ELK”这一术语&#xff1a; Elasticsearch (ES): Elasticsearch 是一个基于 Apache Lucene 构建的分布式、实时搜索与…

【Python性能优化】list、array与set

list、array与set 详述测试代码 详述 本文对比 list 与 set 在插入和取值时的性能差异&#xff0c;以提供一条什么时候该选择什么数据类型的建议。先上结果&#xff1a; array 与 list 的不同&#xff1a; 内存方面 array 是 C array 的包装&#xff0c;它直接存储数据&#xf…

Vu3+QuaggaJs实现web页面识别条形码

一、什么是QuaggaJs QuaggaJS是一个基于JavaScript的开源图像识别库&#xff0c;可用于识别条形码。 QuaggaJs的作用主要体现在以下几个方面&#xff1a; 实时图像处理与识别&#xff1a;QuaggaJs是一款基于JavaScript的开源库&#xff0c;它允许在Web浏览器中实现实时的图像…

授权协议OAuth 2.0之通过OIDC实现SSO

写在前面 本文来一起看下OIDC&#xff08;openid connect&#xff09;相关内容。 1&#xff1a;什么是OIDC OIDC的全称是openid connect&#xff0c;和OAuth2.0一样&#xff0c;也是属于协议和规范的范畴。OAuth2.0是一种授权协议&#xff0c;即规定了what you can do的内容…