SpringBoot中日志的使用log4j

news2024/12/23 16:40:22

SpringBoot中日志的使用log4j

项目中日志系统是必不可少的,目前比较流行的日志框架有 log4jlogback 等,这两个框架的作者是同一个

人,Logback 旨在作为流行的 log4j 项目的后续版本,从而恢复 log4j 离开的位置。

另外 slf4j(Simple Logging Facade for Java) 则是一个日志门面框架,提供了日志系统中常用的接口,

logbacklog4j 则对 slf4j 进行了实现。

官网:https://logging.apache.org/log4j/1.x/

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

Spring Boot在所有内部日志中使用Commons Logging,但也保留默认配置对常用日志的支持,如:

Java Util Logging, Log4J, Log4J2, SLF4J, Logback

每种 Logger 都可以通过配置使用控制台或者文件输出日志内容。

默认情况下,如果您使用 Starters,会使用 Logback 来实现日志管理。

我们没必要纠结使用默认的 Logback 还是 Log4j,直接用 Slf4j 即可。至于这个日志具体是如何写到控制台或

者文件的,则由Spring Boot项目中引入了什么具体的日志框架决定,默认情况下就是 Logback

我们本文将讲述如何在spring boot 中应用 logback+slf4j 实现日志的记录。

1、各个日志之间的关系

1.1 spring-boot-starter-logging

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

在这里插入图片描述

org.springframework.boot的依赖:

<dependencies>
  <dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.6</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-to-slf4j</artifactId>
    <version>2.14.1</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jul-to-slf4j</artifactId>
    <version>1.7.32</version>
    <scope>compile</scope>
  </dependency>
</dependencies>

1.2 spring-boot-starter

在这里插入图片描述

boot-starter-web 启动器当中,会依赖中我们所使用环境的一些 jar包的信息,里面就包含了slf4j 日志门面和

logback的日志实现。

1.3 总结

1、SpringBoot底层默认使用 logback 作为日志实现

2、使用了 SLF4J 作为日志门面

3、将JUL也转换成 slf4j

4、在使用Springboot框架之后,其内部所有的日志实现都通过桥接器转换成slf4j日志门面进行统一的管理,最终

交给logback日志实现框架进行日志输出。

2、为什么使用logback

  • Logback 是log4j 框架的作者开发的新一代日志框架,它效率更高、能够适应诸多的运行环境,同时天然支持

    SLF4J。

  • Logback的定制性更加灵活,同时也是spring boot的内置日志框架。

3、项目编写

3.1 添加依赖

maven依赖中添加了spring-boot-starter-logging

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

但是呢,实际开发中我们不需要直接添加该依赖,你会发现spring-boot-starter其中包含了spring-boot-

starter-logging,该依赖内容就是 Spring Boot 默认的日志框架Logback+SLF4J。而spring-boot-starter-

web包含了spring-boot-starte,所以我们只需要引入web组件即可:

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

完整 pom.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.6</version>
        <relativePath/>
    </parent>

    <groupId>com.log</groupId>
    <artifactId>spring-boot-log</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-log</name>
    <description>spring-boot-log</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <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>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3.2 Controller编写

package com.log.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author zhangshixing
 * @date 2021年11月04日 17:42
 */
// 也可以使用@Slf4j注解输出日志(建议)
@RestController
public class DemoController {

    /**
     * 声明日志记录器对象(slf4j包)
     */
    public static final Logger logger = LoggerFactory.getLogger(DemoController.class);

    @GetMapping("get")
    public void test() {
        logger.error("error");
        logger.warn("warn");
        logger.info("info");
        logger.debug("debug");
        logger.trace("trace");
    }
}

3.3 测试类

package com.log;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringBootLogApplicationTests {

    // 声明日志记录器对象(slf4j包)
    public static final Logger logger = LoggerFactory.getLogger(SpringBootLogApplicationTests.class);

    @Test
    void contextLoads() {
        logger.error("error");
        logger.warn("warn");
        logger.info("info");
        logger.debug("debug");
        logger.trace("trace");
    }
}

输出:

2023-11-18 10:17:19.458 ERROR 1596 --- [           main] com.log.SpringBootLogApplicationTests    : error
2023-11-18 10:17:19.458  WARN 1596 --- [           main] com.log.SpringBootLogApplicationTests    : warn
2023-11-18 10:17:19.458  INFO 1596 --- [           main] com.log.SpringBootLogApplicationTests    : info

因为我们没有提供任何配置文件,因此默认的日志级别就是info,所以 debug 和 trace 不会输出。

4、基本配置

Springboot 支持对日志进行具体的配置,可以直接在 application.properties 配置文件中简单定义,也可以

导入具体日志实现的配置文件。

4.1 默认配置

4.1.1 日志输出文件配置

默认情况下Spring Boot将日志输出到控制台,不会写到日志文件。

如果要编写除控制台输出之外的日志文件,则需在

application.properties中设置logging.file.namelogging.file.path属性。

注:二者不能同时使用,如若同时使用,则只有 logging.file.name 生效

  • logging.file.name=文件名

  • logging.file.path=日志文件路径

  • logging.level.包名=指定包下的日志级别

  • logging.pattern.console=日志打印规则

logging.file.name 设置文件,可以是绝对路径,也可以是相对路径。如:logging.file.name=my.log

logging.file.path设置目录,会在该目录下创建spring.log文件,并写入日志内容,如:

logging.file.path=/var/log

注:二者不能同时使用,如若同时使用,则只有logging.file.name生效,可以看到这种方式配置简单,但

是能实现的功能也非常有限,如果想要更复杂的需求,就需要下面的定制化配置了。

我们设置:

logging.file.path=D:

会生成:

在这里插入图片描述

我们设置:

logging.file.path=D:
logging.file.name=D:\\my_log.txt

在这里插入图片描述

4.1.2 指定日志输出的级别、格式
# 自定义logger对象的日志级别,com.log.controller是自定义logger对象的名称,也就是包名
logging.level.com.log.controller = trace
# 指定控制台输出消息格式
# 格式配置请参考:https://logging.apache.org/log4j/2.x/manual/layouts.html
logging.pattern.console = [%-5level] %d{yyyy-MM-dd HH:mm:ss} %c [%thread] %m%n

发送请求:http://127.0.0.1:8080/get

输出:

[ERROR] 2023-11-18 21:24:04 com.log.controller.DemoController [http-nio-8080-exec-1] error
[WARN ] 2023-11-18 21:24:04 com.log.controller.DemoController [http-nio-8080-exec-1] warn
[INFO ] 2023-11-18 21:24:04 com.log.controller.DemoController [http-nio-8080-exec-1] info
[DEBUG] 2023-11-18 21:24:04 com.log.controller.DemoController [http-nio-8080-exec-1] debug
[TRACE] 2023-11-18 21:24:04 com.log.controller.DemoController [http-nio-8080-exec-1] trace
4.1.3 指定日志文件消息格式
# 指定日志文件消息格式
logging.pattern.file=[%-5level] %d{yyyy-MM-dd HH:mm:ss} %c [%thread] %m%n

输出:

在这里插入图片描述

SpringBoot提供的默认配置文件无法进行复杂的配置,比如所有日志都放到一个文件当中,不易于后期维护和管

理,希望是按照一定的规则进行滚动拆分,比如文件大小,时间等。通过简单的SpringBoot提供的配置文件还不

够,通常在企业开发中会导入具体某个日志实现相应的配置文件。

给类路径下放上每个日志框架自己的配置文件,SpringBoot就不使用默认配置的了:

日志框架配置文件
Logbacklogback-spring.xml、logback.xml
Log4j2log4j2-spring.xml、log4j2.xml
JULlogging.properties

4.2 logback-spring.xml说明

Spring Boot 官方推荐优先使用带有 -spring 的文件名作为你的日志配置(如使用logback-spring.xml,而不

logback.xml),命名为logback-spring.xml的日志配置文件,将xml放至src/main/resource下面。

也可以使用自定义的名称,比如logback-config.xml,只需要在application.properties文件中使用

logging.config=classpath:logback-config.xml指定即可。

对于 logback 配置文件,logback-spring.xmllogback.xml 都能够被加载识别,增加了 -spring 的配置

文件会被 SpringBoot 框架解析,而不是由 logback 解析。

被 SpringBoot 框架解析的文件,只需修改 SpringBoot 的全局参数,就能对配置文件进行灵活调整,而不需要再

修改 logback 提供的核心配置文件了。

4.3 Logback架构

在讲解logback-spring.xml之前我们先来了解三个单词:Logger(记录器),Appenders(附加器) 和

Layouts(布局)。

Logback 的架构主要由三个核心组件组成:Logger、Appender 和 Layout。其中,Logger 用于记录 Log,

Appender 用于将 Log 输出到控制台或文件,Layout 用于定义 Log 输出格式。

这三种类型的组件协同工作,使开发人员能够根据消息类型和级别记录消息,并在运行时控制这些消息的格式以及

报告的位置。下面简要介绍一下这三个概念。

4.3.1 Logger

Logger 相当于一个记录器,用于产生 Log。Logger 有一个与之关联的 Log Level,表示记录 Log 要记录的最小等

级。Logger 可以选择是否记录它接收到的 Log,如果记录的 Log Level 低于 Logger 的 Log Level 则不记录。多个

Logger 可以形成一颗 Logger 的层次结构。

4.3.2 Appender

Appender 用于配置 Log 输出的目的地。Log 可以输出到控制台,文件,远程服务器等等。每个 Appender 都有

一个 Layout,用于格式化 Log 输出。一个 Logger 可以由多个 Appender 处理 Log 事件,例如,一个 Logger 可

以将所有 Error Level 的 Log 信息输出到一个文件中,同时将其他 Level 的 Log 输出到控制台。

4.3.3 Layout

Layout 用于格式化 Log 的输出方式。Layout 的作用是对 Log 进行格式化,然后由 Appender 输出。在 Layout

中可以定义 Log 的输出格式,比如时间,线程名称,Log Level 和 Log 的正文内容等。

4.3.4 Logback 配置文件

Logback 的配置文件使用 XML 格式编写,一般命名为 logback.xml 。配置文件中包括了 Logger、Appender 和

Encoder 等标签。下面是一个基本的 xml 配置文件的示例:

<configuration>
 
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>
 
  <logger name="chapters.configuration" level="INFO"/>
 
  <!-- Strictly speaking, the level attribute is not necessary since -->
  <!-- the level of the root level is set to DEBUG by default.       -->
  <root level="DEBUG">          
    <appender-ref ref="STDOUT" />
  </root>  
  
</configuration>

上面示例中,定义了一个名为 STDOUT 的 Appender,它是 ConsoleAppender 类型,用于将日志信息输出到控制

台上。同时定义了一个根 Logger,日志级别为 DEBUG,并将日志信息输出到 STDOUT Appender 中。Encoder

标签用于定义日志信息的输出格式。

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
 
    <!-- 配置集中管理属性
         作用:如果其他标签要使用,可以直接通过表达式来引用:${property的name值}-->
    <!-- 1.配置日志的输出格式,name:自定义名称  value:具体格式值 -->
    <property name="pattern" value="[%-5level]  %d{yyyy-MM-dd HH:mm:ss}  %c  %M  %L  %thread  %m  %n"/>
  
    <!-- 2.配置控制台输出的appender, name:自定义appender名称  class:appender类型-->
    <appender name="myConsole" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 2.1控制输出流对象,默认System.out控制台黑色字体,修改为System.err红色字体 -->
        <target>System.err</target>
        <!-- 2.2日志消息的格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>
 
 
    <!-- 3.自定义logger 对象,additivity:是否继承父元素RootLogger的属性配置-->
    <logger name="com.ahead" level="info" additivity="false">
        <appender-ref ref="myConsole" />
    </logger>
</configuration>

上传了具体日志实现的配置文件后,默认的SpringBoot配置信息就会作废。

4.3 <configuration>元素

logback.xml配置文件的基本结构可以描述为<configuration>元素,包含零个或多个<appender>元素,后跟

零个或多个<logger>元素,后跟最多一个<root>元素(也可以没有)。

下图说明了这种基本结构:

在这里插入图片描述

4.4 <logger>元素

<logger>元素只接受一个必需的name属性,一个可选的level属性和一个可选的additivity属性,允许值为

true或false。level属性的值允许一个不区分大小写的字符串值TRACE,DEBUG,INFO,WARN,ERROR,ALL或OFF

特殊于大小写不敏感的值INHERITED或其同义词NULL将强制记录器的级别从层次结构中的较高级别继承。

<logger>元素可以包含零个或多个<appender-ref>元素,这样引用的每个appender都被添加到指定的logger

中,logger元素级别具有继承性。

例1:示例中,仅为根记录器分配了级别。 此级别值DEBUG由其他记录器X,X.Y和X.Y.Z继承

Logger nameAssigned levelEffective level
rootDEBUGDEBUG
XnoneDEBUG
X.YnoneDEBUG
X.Y.ZnoneDEBUG

例2:所有记录器都有一个指定的级别值。 级别继承不起作用

Logger nameAssigned levelEffective level
rootERRORERROR
XINFOINFO
X.YDEBUGDEBUG
X.Y.ZWARNWARN

例3:记录器root,X和X.Y.Z分别被分配了DEBUG,INFO和ERROR级别。 Logger X.Y从其父X继承其级别值。

Logger nameAssigned levelEffective level
rootDEBUGDEBUG
XINFOINFO
X.YnoneINFO
X.Y.ZERRORERROR

例4:在示例4中,记录器root和X分别被分配了DEBUG和INFO级别。 记录器X.Y和X.Y.Z从其最近的父X继承其级别

值,该父级具有指定的级别。

Logger nameAssigned levelEffective level
rootDEBUGDEBUG
XINFOINFO
X.YnoneINFO
X.Y.ZnoneINFO

4.5 <root>元素

<root>元素配置根记录器,它支持单个属性,即 level 属性。它不允许任何其他属性,因为 additivity 标志不适

用于根记录器。此外,由于根记录器已被命名为 ROOT,因此它也不允许使用 name 属性。

level 属性的值可以是不区分大小写的字符串 TRACE, DEBUG, INFO, WARN, ERROR, ALL, OFF之一。

<root>元素可以包含零个或多个<appender-ref>元素,这样引用的每个 appender 都被添加到根记录器中。

4.6 <appender>元素

appender使用<appender>元素配置,该元素采用两个必需属性 name 和 class。name 属性指定 appender 的名

称,而 class 属性指定要实例化的 appender 类的完全限定名称。

<appender>元素可以包含零个或一个<layout>元素,零个或多个<encoder>元素以及零个或多个<filter>

素,下图说明了常见的结构:

在这里插入图片描述

重要:在logback中,输出目标称为appenderaddAppender方法将appender添加到给定的记录器logger。给

定记录器的每个启用的日志记录请求都将转发到该记录器中的所有appender以及层次结构中较高的appender

换句话说,appender是从记录器层次结构中附加地继承的。

例如,如果将控制台appender添加到根记录器,则所有启用的日志记录请求将至少在控制台上打印。如果另外将

文件追加器添加到记录器(例如L),则对L和L的子项启用的记录请求将打印在文件和控制台上。通过将记录器的

additivity标志设置为false,可以覆盖此默认行为,以便不再添加appender累积。

Appender是一个接口,它有许多子接口和实现类,具体如下图所示:

在这里插入图片描述

其中最重要的两个Appender为:ConsoleAppenderRollingFileAppender

4.6.1 ConsoleAppender

ConsoleAppender,如名称所示,将日志输出到控制台上。

4.6.2 RollingFileAppender

RollingFileAppenderFileAppender的一个子类,扩展了FileAppender,具有翻转日志文件的功能。例

RollingFileAppender可以记录到名为log.txt文件的文件,并且一旦满足某个条件,就将其日志记录目标

更改为另一个文件。

有两个与RollingFileAppender交互的重要子组件。第一个RollingFileAppender子组件,即RollingPolicy

负责执行翻转所需的操作。RollingFileAppender的第二个子组件,即TriggeringPolicy将确定是否以及何时

发生翻转。因此,RollingPolicy负责什么和TriggeringPolicy负责什么时候。

作为任何用途,RollingFileAppender必须同时设置RollingPolicyTriggeringPolicy。但是,如果其

RollingPolicy也实现了TriggeringPolicy接口,则只需要显式指定前者。

滚动策略:

  • TimeBasedRollingPolicy:可能是最受欢迎的滚动策略。它根据时间定义翻转策略,例如按天或按月。

    TimeBasedRollingPolicy承担滚动和触发所述翻转的责任。实际上,TimeBasedTriggeringPolicy

    现了RollingPolicyTriggeringPolicy接口。

  • SizeAndTimeBasedRollingPolicy:有时您可能希望按日期归档文件,但同时限制每个日志文件的大小,特

    别是如果后处理工具对日志文件施加大小限制。为了满足此要求,logback 提供了

    SizeAndTimeBasedRollingPolicy,它是TimeBasedRollingPolicy的一个子类,实现了基于时间和日志

    文件大小的翻滚策略。

4.6.3 <encoder>元素

encoder中最重要就是pattern属性,它负责控制输出日志的格式,这里给出一个我自己写的示例:

<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) --- [%15.15(%thread)] %cyan(%-40.40(%logger{40})) : %msg%n</pattern>

其中:

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

# 日志级别
%-5level

# 颜色,info为蓝色,warn为浅红,error为加粗红,debug为黑色
%highlight()

# 打印日志的线程
%thread

# 如果记录的线程字符长度小于15(第一个)则用空格在左侧补齐,如果字符长度大于15(第二个),则从开头开始截断多余的字符
%15.15()

# 颜色
%cyan

# 日志输出的类名
# 表示logger名字最长40个字符,否则按照句点分割。
%logger{40}

# 如果记录的logger字符长度小于40(第一个)则用空格在右侧补齐,如果字符长度大于40(第二个),则从开头开始截断多余的字符
%-40.40()

# 日志输出内容
%msg

# 换行符
%n

格式配置请参考:https://logging.apache.org/log4j/2.x/manual/layouts.html

4.6.4 <filter>元素

filter中最重要的两个过滤器为:LevelFilterThresholdFilter

LevelFilter根据精确的级别匹配过滤事件。如果事件的级别等于配置的级别,则筛选器接受或拒绝该事件,具

体取决于onMatchonMismatch属性的配置。例如下面配置将只打印INFO级别的日志,其余的全部禁止打印输

出:

<configuration>
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>INFO</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>
    <encoder>
      <pattern>
        %-4relative [%thread] %-5level %logger{30} - %msg%n
      </pattern>
    </encoder>
  </appender>
  <root level="DEBUG">
    <appender-ref ref="CONSOLE" />
  </root>
</configuration>

ThresholdFilter过滤低于指定阈值的事件。对于等于或高于阈值的事件,ThresholdFilter将在调用其

decision()方法时响应NEUTRAL

但是,将拒绝级别低于阈值的事件,例如下面的配置将拒绝所有低于INFO级别的日志,只输出INFO以及以上级别

的日志:

<configuration>
  <appender name="CONSOLE"
    class="ch.qos.logback.core.ConsoleAppender">
    <!-- deny all events with a level below INFO, that is TRACE and DEBUG -->
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
      <level>INFO</level>
    </filter>
    <encoder>
      <pattern>
        %-4relative [%thread] %-5level %logger{30} - %msg%n
      </pattern>
    </encoder>
  </appender>
  <root level="DEBUG">
    <appender-ref ref="CONSOLE" />
  </root>
</configuration>

5、详细的logback-spring.xml示例1

<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL, 如果设置为WARN, 则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时, 配置文档如果发生改变, 将会被重新加载, 默认值为true -->
<!-- scanPeriod:设置监测配置文档是否有修改的时间间隔, 如果没有给出时间单位, 默认单位是毫秒, 当scan为true时, 此属性生效, 默认的时间间隔为1分钟 -->
<!-- debug:当此属性设置为true时, 将打印出logback内部日志信息, 实时查看logback运行状态, 默认值为false -->
<configuration scan="true" scanPeriod="10 seconds">

    <contextName>spring-boot-log</contextName>

    <!-- 彩色日志 -->
    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />

    <!-- 变量定义begin-->
    <!-- 使用spring.application.name设置的名字 -->
    <springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
    <!-- 定义日志存储的路径,建议不要配置相对路径 -->
    <property name="FILE_DIR" value="D:\\logs\\${APP_NAME}" />
    <!-- 设置全局属性,通过获取变量的形式${APP_NAME} -->
    <property name="ROLL_FILE_DIR" value="D:\\logs\\${APP_NAME}" />
    <!-- 彩色日志格式 -->
    <property name="CONSOLE_LOG_FORMAT" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
    <!--默认日志格式: 时间日期 -> 日志级别 -> 线程ID -> 分隔符 -> 线程名 -> Logger名(通常对应的是类名) -> 日志内容 -->
    <!-- 格式化输出:%date表示日期, %thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息, %n是换行符-->
    <property name="LOG_FORMAT" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
    <!-- 变量定义end-->

    <!-- 日志输出方式定义 begin -->
    <!--1、输出到控制台-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--此日志appender是为开发使用, 只配置最低级别, 控制台输出的日志级别是大于或等于此级别的日志信息-->
        <!-- 日志级别过滤DEBUG以下 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!-- 如果是开发环境,使用默认的消息格式 -->
            <springProfile name="dev">
                <pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level]  %m%n</pattern>
            </springProfile>
            <!-- 如果是生产环境,使用简单的消息格式输出消息 -->
            <springProfile name="pro">
                <!-- 按照上面配置的LOG_FORMAT来打印日志 -->
                <pattern>${CONSOLE_LOG_FORMAT}</pattern>
                <!-- 设置字符集 -->
                <charset>UTF-8</charset>
            </springProfile>
        </encoder>
    </appender>

    <!-- 2、输出到文件  -->
    <!-- 输出到文件, 这种方式是单个日志文件保存, 文件会不停的增大, 除非手动删除 -->
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>${FILE_DIR}\\spring-log.log</file>
        <append>true</append>
        <encoder>
            <!-- 按照上面配置的LOG_FORMAT来打印日志 -->
            <pattern>${LOG_FORMAT}</pattern>
        </encoder>
    </appender>

    <!-- 3、滚动输出到文件  -->
    <!-- 滚动日志输出,每天生成一个日志文件,保存30天的日志文件,FILE用来切分文件的 -->
    <appender name="FILE_ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 当前记录的日志文档完整路径 -->
        <file>${ROLL_FILE_DIR}\\spring-log-rolling.log</file>
        <!--日志文档输出格式-->
        <encoder>
            <!-- 按照上面配置的LOG_FORMAT来打印日志 -->
            <pattern>${LOG_FORMAT}</pattern>
            <!-- 此处设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
        <!--日志滚动策略,按照时间、按大小滚动记录-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${ROLL_FILE_DIR}\\spring-log-rolling.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 只保留30天的日志(非持续运行情况下,30天外不会清理)-->
            <maxHistory>30</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- 日志文件的最大大小 -->
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!-- 应对服务非持续偶尔运行,日志清理机制无法触发而导致日志得不到清理的情况-->
            <!-- 超出删除老文件 -->
            <totalSizeCap>500MB</totalSizeCap>
            <cleanHistoryOnStart>true</cleanHistoryOnStart>
        </rollingPolicy>
        <!-- 以上的配置是当日志文件的大小达到100MB时,就新建一个日志文件,当滚动日志所占控件总和超过500MB时,就将最老的日志文件删除掉
        最多保存30天的日志文件,超过30天也会将最老的日志文件删除
        需要注意的是,如果日志文件比较大,如果1个小时就创建了5个日志文件,每个100MB,那下一个小时重新生成的日志文件会将上一个小时的日志文件覆
        盖掉,而且由于日志文件大小总和超过500MB,所以实际无法保存30天的日志文件,所以需要根据实际项目确定以上参数该怎么设置-->
    </appender>
    <!-- 日志输出方式定义 end -->

    <!-- <logger>用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>
    <logger>仅有一个name属性,一个可选的level和一个可选的addtivity属性
    name:用来指定受此logger约束的某一个包或者具体的某一个类
    level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
    还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别
    如果未设置此属性,那么当前logger将会继承上级的级别
    addtivity:是否向上级logger传递打印信息,默认是true
    -->

    <!--root节点是必选节点,用来指定通用的日志输出级别,只有一个level属性
    level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
    不能设置为INHERITED或者同义词NULL,默认是DEBUG
    可以包含零个或多个元素,标识这个appender将会添加到这个logger
    -->

    <!-- 日志输出级别 begin-->
    <!-- cloud环境下,去掉nacos的日志打印信息 -->
    <!--
    <logger name="com.alibaba.nacos" level="OFF" addtivity="false"> </logger>
    -->
    <!-- 打印info级别的信息 -->
    <!--
    <root level="INFO">
        <appender-ref ref="FILE"/>
    </root>
    -->

    <!-- 控制整个项目的日志级别 -->
    <root level="info">
        <!--使用info级别输出日志到控制台、文件及滚动文件-->
        <!--采用上面定义的日志输出方式确定本项目究竟将日志输出到什么地方-->
        <!--输出到终端-->
        <appender-ref ref="CONSOLE" />
        <!--输出到文件-->
        <appender-ref ref="FILE" />
        <!--输出到文件,滚动输出,避免单个文件过大,通常采用这种方式-->
        <appender-ref ref="FILE_ROLLING" />
    </root>
    <!-- 日志输出级别 end-->

    <!--
    如果采用root定义,则是所有包的日志都会打印,如果要控制只需要当前的包,则使用下面的logger的标签定义
    name表示是打印哪个包下面的
   level表示这个包下面什么级别的日志打印出来
    -->
    <!--
    <logger name="com.log.controller" level="debug">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
        <appender-ref ref="FILE_ROLLING" />
    </logger>
    -->

    <!-- 本地环境输出至控制台 -->
    <!-- 如果使用了 springProfile, 需要将logback.xml名称改为logback-spring.xml-->
    <!--
    <springProfile name="dev">
        <root level="DEBUG">
            <appender-ref ref="CONSOLE" />
            <appender-ref ref="FILE" />
        </root>
    </springProfile>
    -->
</configuration>

使用是需要设置:

spring.profiles.active = dev/pro

6、详细的logback-spring.xml示例2

<?xml version="1.0" encoding="UTF-8"?>  
  
<!-- 从高到地低 OFF 、 FATAL 、 ERROR 、 WARN 、 INFO 、 DEBUG 、 TRACE 、 ALL -->  
<!-- 日志输出规则  根据当前ROOT 级别,日志输出时,级别高于root默认的级别时  会输出 -->  
<!-- 以下  每个配置的 filter 是过滤掉输出文件里面,会出现高级别文件,依然出现低级别的日志信息,通过filter 过滤只记录本级别的日志-->  
  
  
<!-- 属性描述 scan:性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。   
    debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->  
<configuration scan="true" scanPeriod="60 seconds" debug="false">  
    <!-- 定义日志文件 输入位置 -->  
    <property name="log_dir" value="/customize/logs" />  
    <!-- 日志最大的历史 30天 -->  
    <property name="maxHistory" value="30"/>  
    <!-- ConsoleAppender 控制台输出日志 -->  
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">  
        <!-- 对日志进行格式化 -->  
        <encoder>  
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger -%msg%n</pattern>  
        </encoder>  
    </appender>  
      
      
    <!-- ERROR级别日志 -->  
    <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 RollingFileAppender-->  
    <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">  
        <!-- 过滤器,只记录WARN级别的日志 -->  
        <filter class="ch.qos.logback.classic.filter.LevelFilter">  
            <level>ERROR</level>  
            <onMatch>ACCEPT</onMatch>  
            <onMismatch>DENY</onMismatch>  
        </filter>  
        <!-- 最常用的滚动策略,它根据时间来制定滚动策略.既负责滚动也负责出发滚动 -->  
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
            <!--日志输出位置  可相对、和绝对路径 -->  
            <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/error-log.log</fileNamePattern>  
            <!-- 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件假设设置每个月滚动,且<maxHistory>是6,  
            则只保存最近6个月的文件,删除之前的旧文件。注意,删除旧文件是,那些为了归档而创建的目录也会被删除-->  
            <maxHistory>${maxHistory}</maxHistory>  
        </rollingPolicy>  
          
        <!-- 按照固定窗口模式生成日志文件,当文件大于20MB时,生成新的日志文件。窗口大小是1到3,当保存了3个归档文件后,将覆盖最早的日志。   
        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">     
          <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/.log.zip</fileNamePattern>     
          <minIndex>1</minIndex>     
          <maxIndex>3</maxIndex>     
        </rollingPolicy>   -->  
        <!-- 查看当前活动文件的大小,如果超过指定大小会告知RollingFileAppender 触发当前活动文件滚动   
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">     
            <maxFileSize>5MB</maxFileSize>     
        </triggeringPolicy>   -->  
          
        <encoder>  
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>  
        </encoder>  
    </appender>  
      
      
      
    <!-- WARN级别日志 appender -->  
    <appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">  
        <!-- 过滤器,只记录WARN级别的日志 -->  
        <filter class="ch.qos.logback.classic.filter.LevelFilter">  
            <level>WARN</level>  
            <onMatch>ACCEPT</onMatch>  
            <onMismatch>DENY</onMismatch>  
        </filter>  
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
            <!-- 按天回滚 daily -->  
            <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/warn-log.log  
            </fileNamePattern>  
            <!-- 日志最大的历史 60天 -->  
            <maxHistory>${maxHistory}</maxHistory>  
        </rollingPolicy>  
        <encoder>  
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>  
        </encoder>  
    </appender>  
      
      
      
      
    <!-- INFO级别日志 appender -->  
    <appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">  
        <!-- 过滤器,只记录INFO级别的日志 -->  
        <filter class="ch.qos.logback.classic.filter.LevelFilter">  
            <level>INFO</level>  
            <onMatch>ACCEPT</onMatch>  
            <onMismatch>DENY</onMismatch>  
        </filter>  
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
            <!-- 按天回滚 daily -->  
            <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/info-log.log  
            </fileNamePattern>  
            <!-- 日志最大的历史 60天 -->  
            <maxHistory>${maxHistory}</maxHistory>  
        </rollingPolicy>  
        <encoder>  
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>  
        </encoder>  
    </appender>  
      
      
      
      
    <!-- DEBUG级别日志 appender -->  
    <appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">  
        <!-- 过滤器,只记录DEBUG级别的日志 -->  
        <filter class="ch.qos.logback.classic.filter.LevelFilter">  
            <level>DEBUG</level>  
            <onMatch>ACCEPT</onMatch>  
            <onMismatch>DENY</onMismatch>  
        </filter>  
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
            <!-- 按天回滚 daily -->  
            <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/debug-log.log  
            </fileNamePattern>  
            <!-- 日志最大的历史 60天 -->  
            <maxHistory>${maxHistory}</maxHistory>  
        </rollingPolicy>  
        <encoder>  
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>  
        </encoder>  
    </appender>  
      
      
      
      
    <!-- TRACE级别日志 appender -->  
    <appender name="TRACE" class="ch.qos.logback.core.rolling.RollingFileAppender">  
        <!-- 过滤器,只记录ERROR级别的日志 -->  
        <filter class="ch.qos.logback.classic.filter.LevelFilter">  
            <level>TRACE</level>  
            <onMatch>ACCEPT</onMatch>  
            <onMismatch>DENY</onMismatch>  
        </filter>  
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
            <!-- 按天回滚 daily -->  
            <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/trace-log.log  
            </fileNamePattern>  
            <!-- 日志最大的历史 60天 -->  
            <maxHistory>${maxHistory}</maxHistory>  
        </rollingPolicy>  
        <encoder>  
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>  
        </encoder>  
    </appender>  
  
    <logger name="java.sql.PreparedStatement" value="DEBUG" />    
    <logger name="java.sql.Connection" value="DEBUG" />    
    <logger name="java.sql.Statement" value="DEBUG" />    
    <logger name="com.ibatis" value="DEBUG" />    
    <logger name="com.ibatis.common.jdbc.SimpleDataSource" value="DEBUG" />    
    <logger name="com.ibatis.common.jdbc.ScriptRunner" level="DEBUG"/>    
    <logger name="com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate" value="DEBUG" />    
      
      
      
    <!-- root级别   DEBUG -->  
    <root level="debug">  
        <!-- 控制台输出 -->  
        <appender-ref ref="STDOUT" />  
        <!-- 文件输出 -->  
        <appender-ref ref="ERROR" />  
        <appender-ref ref="INFO" />  
        <appender-ref ref="WARN" />  
        <appender-ref ref="DEBUG" />  
        <appender-ref ref="TRACE" />  
    </root>  
</configuration>  

7、详细的logback-spring.xml示例3

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
 
    <!-- appender是configuration的子节点,是负责写日志的组件。 -->
    <!-- ConsoleAppender:把日志输出到控制台 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 默认情况下,每个日志事件都会立即刷新到基础输出流。 这种默认方法更安全,因为如果应用程序在没有正确关闭appender的情况下退出,则日志事件不会丢失。
         但是,为了显着增加日志记录吞吐量,您可能希望将immediateFlush属性设置为false -->
        <!--<immediateFlush>true</immediateFlush>-->
        <encoder>
            <!-- %37():如果字符没有37个字符长度,则左侧用空格补齐 -->
            <!-- %-37():如果字符没有37个字符长度,则右侧用空格补齐 -->
            <!-- %15.15():如果记录的线程字符长度小于15(第一个)则用空格在左侧补齐,如果字符长度大于15(第二个),则从开头开始截断多余的字符 -->
            <!-- %-40.40():如果记录的logger字符长度小于40(第一个)则用空格在右侧补齐,如果字符长度大于40(第二个),则从开头开始截断多余的字符 -->
            <!-- %msg:日志打印详情 -->
            <!-- %n:换行符 -->
            <!-- %highlight():转换说明符以粗体红色显示其级别为ERROR的事件,红色为WARN,BLUE为INFO,以及其他级别的默认颜色。 -->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) --- [%15.15(%thread)] %cyan(%-40.40(%logger{40})) : %msg%n</pattern>
            <!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
 
    <!-- info 日志-->
    <!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
    <!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是project_info.log -->
    <!--             2.如果日期没有发生变化,但是当前日志的文件大小超过10MB时,对当前日志进行分割 重命名-->
    <appender name="info_log" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志文件路径和名称-->
        <File>logs/project_info.log</File>
        <!--是否追加到文件末尾,默认为true-->
        <append>true</append>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>DENY</onMatch><!-- 如果命中ERROR就禁止这条日志 -->
            <onMismatch>ACCEPT</onMismatch><!-- 如果没有命中就使用这条规则 -->
        </filter>
        <!--有两个与RollingFileAppender交互的重要子组件。 第一个RollingFileAppender子组件,即RollingPolicy:负责执行翻转所需的操作。
         RollingFileAppender的第二个子组件,即TriggeringPolicy:将确定是否以及何时发生翻转。 因此,RollingPolicy负责什么和TriggeringPolicy负责什么时候.
        作为任何用途,RollingFileAppender必须同时设置RollingPolicy和TriggeringPolicy,但是,如果其RollingPolicy也实现了TriggeringPolicy接口,则只需要显式指定前者。-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 日志文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
            <!-- 文件名:logs/project_info.2017-12-05.0.log -->
            <!-- 注意:SizeAndTimeBasedRollingPolicy中 %i和%d令牌都是强制性的,必须存在,要不会报错 -->
            <fileNamePattern>logs/project_info.%d.%i.log</fileNamePattern>
            <!-- 每产生一个日志文件,该日志文件的保存期限为30天, ps:maxHistory的单位是根据fileNamePattern中的翻转策略自动推算出来的,例如上面选用了yyyy-MM-dd,则单位为天
            如果上面选用了yyyy-MM,则单位为月,另外上面的单位默认为yyyy-MM-dd-->
            <maxHistory>30</maxHistory>
            <!-- 每个日志文件到10mb的时候开始切分,最多保留30天,但最大到20GB,哪怕没到30天也要删除多余的日志 -->
            <totalSizeCap>20GB</totalSizeCap>
            <!-- maxFileSize:这是活动文件的大小,默认值是10MB,测试时可改成5KB看效果 -->
            <maxFileSize>10MB</maxFileSize>
        </rollingPolicy>
        <!--编码器-->
        <encoder>
            <!-- pattern节点,用来设置日志的输入格式 ps:日志文件中没有设置颜色,否则颜色部分会有ESC[0:39em等乱码-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{40}) : %msg%n</pattern>
            <!-- 记录日志的编码:此处设置字符集 - -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
 
    <!-- error 日志-->
    <!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
    <!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是project_error.log -->
    <!--             2.如果日期没有发生变化,但是当前日志的文件大小超过10MB时,对当前日志进行分割 重命名-->
    <appender name="error_log" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志文件路径和名称-->
        <File>logs/project_error.log</File>
        <!--是否追加到文件末尾,默认为true-->
        <append>true</append>
        <!-- ThresholdFilter过滤低于指定阈值的事件。 对于等于或高于阈值的事件,ThresholdFilter将在调用其decision()方法时响应NEUTRAL。 但是,将拒绝级别低于阈值的事件 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level><!-- 低于ERROR级别的日志(debug,info)将被拒绝,等于或者高于ERROR的级别将相应NEUTRAL -->
        </filter>
        <!--有两个与RollingFileAppender交互的重要子组件。 第一个RollingFileAppender子组件,即RollingPolicy:负责执行翻转所需的操作。
        RollingFileAppender的第二个子组件,即TriggeringPolicy:将确定是否以及何时发生翻转。 因此,RollingPolicy负责什么和TriggeringPolicy负责什么时候.
       作为任何用途,RollingFileAppender必须同时设置RollingPolicy和TriggeringPolicy,但是,如果其RollingPolicy也实现了TriggeringPolicy接口,则只需要显式指定前者。-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 活动文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
            <!-- 文件名:logs/project_error.2017-12-05.0.log -->
            <!-- 注意:SizeAndTimeBasedRollingPolicy中 %i和%d令牌都是强制性的,必须存在,要不会报错 -->
            <fileNamePattern>logs/project_error.%d.%i.log</fileNamePattern>
            <!-- 每产生一个日志文件,该日志文件的保存期限为30天, ps:maxHistory的单位是根据fileNamePattern中的翻转策略自动推算出来的,例如上面选用了yyyy-MM-dd,则单位为天
            如果上面选用了yyyy-MM,则单位为月,另外上面的单位默认为yyyy-MM-dd-->
            <maxHistory>30</maxHistory>
            <!-- 每个日志文件到10mb的时候开始切分,最多保留30天,但最大到20GB,哪怕没到30天也要删除多余的日志 -->
            <totalSizeCap>20GB</totalSizeCap>
            <!-- maxFileSize:这是活动文件的大小,默认值是10MB,测试时可改成5KB看效果 -->
            <maxFileSize>10MB</maxFileSize>
        </rollingPolicy>
        <!--编码器-->
        <encoder>
            <!-- pattern节点,用来设置日志的输入格式 ps:日志文件中没有设置颜色,否则颜色部分会有ESC[0:39em等乱码-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{40}) : %msg%n</pattern>
            <!-- 记录日志的编码:此处设置字符集 - -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
 
    <!--给定记录器的每个启用的日志记录请求都将转发到该记录器中的所有appender以及层次结构中较高的appender(不用在意level值)。
    换句话说,appender是从记录器层次结构中附加地继承的。
    例如,如果将控制台appender添加到根记录器,则所有启用的日志记录请求将至少在控制台上打印。
    如果另外将文件追加器添加到记录器(例如L),则对L和L'子项启用的记录请求将打印在文件和控制台上。
    通过将记录器的additivity标志设置为false,可以覆盖此默认行为,以便不再添加appender累积-->
    <!-- configuration中最多允许一个root,别的logger如果没有设置级别则从父级别root继承 -->
    <root level="INFO">
        <appender-ref ref="STDOUT" />
    </root>
 
    <!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
    <!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE  -->
    <logger name="com.sailing.springbootmybatis" level="INFO">
        <appender-ref ref="info_log" />
        <appender-ref ref="error_log" />
    </logger>
 
    <!-- 利用logback输入mybatis的sql日志,
    注意:如果不加 additivity="false" 则此logger会将输出转发到自身以及祖先的logger中,就会出现日志文件中sql重复打印-->
    <logger name="com.sailing.springbootmybatis.mapper" level="DEBUG" additivity="false">
        <appender-ref ref="info_log" />
        <appender-ref ref="error_log" />
    </logger>
 
    <!-- additivity=false代表禁止默认累计的行为,即com.atomikos中的日志只会记录到日志文件中,不会输出层次级别更高的任何appender-->
    <logger name="com.atomikos" level="INFO" additivity="false">
        <appender-ref ref="info_log" />
        <appender-ref ref="error_log" />
    </logger>
</configuration>

8、使用注意事项

8.1 日志级别判断

这里再说下 log 日志输出代码,一般有人可能在代码中使用如下方式输出:

Object entry = new SomeObject(); 
logger.debug("The entry is " + entry);

上面看起来没什么问题,但是会存在构造消息参数的成本,即将entry转换成字符串相加。

并且无论是否记录消息,都是如此,即:哪怕日志级别为 INFO,也会执行括号里面的操作,但是日志不会输出,

下面是优化后的写法:

if(logger.isDebugEnabled()) { 
    Object entry = new SomeObject(); 
    logger.debug("The entry is " + entry);
}

上面的写法,首先对设置的日志级别进行了判断,如果为debug模式,才进行参数的构造,对第一种写法进行

了改善。

8.2 占位符

不过还有最好的写法,使用占位符:

Object entry = new SomeObject(); 
logger.debug("The entry is {}.", entry);

只有在评估是否记录之后,并且只有在决策是肯定的情况下,记录器实现才会格式化消息并将{} 对替换为条目

的字符串值。换句话说,当禁用日志语句时,此表单不会产生参数构造的成本。

logback 作者进行测试得出:第一种和第三种写法将产生完全相同的输出。但是,在禁用日志记录语句的情况下,

第三个变体将比第一个变体优于至少30倍。

如果有多个参数,写法如下:

logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);

如果需要传递三个或更多参数,则还可以使用Object []变体:

Object[] paramArray = {newVal, below, above};
logger.debug("Value {} was inserted between {} and {}.", paramArray);

记录日志的时候我们可能需要在文件中记录下异常的堆栈信息,经过测试,logger.error(e)不会打印出堆

栈信息,正确的写法是:

logger.error("程序异常, 详细信息:{}", e.getLocalizedMessage() , e);

我们可以看到 info 的多个重载函数:

在这里插入图片描述

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

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

相关文章

本地Git项目同时推送至GitHub和Gitee

分别在gitee和github新建一个仓库 github: gitee: 添加远程仓库 git remote add origin1 [你的GitHub仓库URL] git remote add origin2 [你的Gitee仓库URL] 在本地中初始化创建一个git本地分支 git init 进入.git目录下修改config文件 [remote "origin"] url g…

Google Earth Engine(GEE)操作

地理信息网站 Eatrth Explorer操作界面 在研究中&#xff0c;我们常需要遥感数据。在下面的网站中&#xff0c;可以得到遥感数据。 EarthExplorer (usgs.gov)https://earthexplorer.usgs.gov/登陆网站&#xff1a; 通常&#xff0c;在Additional Criteria中&#xff0c;可以…

【精选】项目管理工具——Maven详解

Maven简介 Maven是一个项目管理工具。它可以帮助程序员构建工程&#xff0c;管理jar包&#xff0c;编译代码&#xff0c;完成测试&#xff0c;项目打包等等。 Maven工具是基于POM&#xff08;Project Object Model&#xff0c;项目对象模型&#xff09;实现的。在Maven的管理下…

【数据结构】前言

数据结构是在计算机中维护数据的方式。 数据结构是OI重要的一部分。 同的数据结构各有优劣&#xff0c;能够处理的问题各不相同&#xff0c;而根据具体问题选取合适的数据结构&#xff0c;可以大大提升程序的效率。 所以&#xff0c;学习各种各样的数据结构是很有必要的。 数据…

车载通信架构 —— 新车载总线类型下(以太网)的通信架构

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消耗你的人和事&#xff0c;多看一眼都是你的不…

Azure Machine Learning - Azure AI 搜索中的集成数据分块和嵌入

在基于索引器的索引编制中&#xff0c;Azure AI _集成矢量化_将数据分块和文本到矢量嵌入添加到技能中&#xff0c;它还为查询添加文本到矢量的转换。 关注TechLead&#xff0c;分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验&#xff0c;同济本…

栈与队列:设计循环队列

目录 题目&#x1f525;&#xff1a; 数据模型&#xff1a; 本题大意&#xff1a; 思路分析&#xff1a; 代码分析&#xff1a; 一、定义队列 二、初始化、判断队列的空和满⭐ 初始化&#xff1a; 空满的判断&#xff1a; 三、入队和出队&#x1f387; 入队&…

LeetCode【32】最长的有效括号

题目&#xff1a; 思路&#xff1a; 括号字符串依次入栈&#xff0c;删除匹配的成对括号。最后栈中留下的都是无法匹配的断点。这些断点的差值减一就是断点间有效括号串的长度&#xff0c;取这些长度的最大值即可。 例如括号字符串 “)()((())(”&#xff0c;最后留在栈中的…

比Postman强在哪里

Postman的受众对象主要是广大开发人员&#xff0c;调测使用&#xff0c;它并不能完全满足专业测试人员需求&#xff0c;而自动化测试平台可以 1&#xff0c;Postman&#xff0c;Jmter是单机版软件&#xff0c;类似打游戏你和电脑PK&#xff0c;而很多时候是要联网和其他人团队作…

LeetCode【36】有效的数独

题目&#xff1a; 思路&#xff1a; https://blog.51cto.com/u_15072778/3788083 代码&#xff1a; public boolean isValidSudoku(char[][] board) {// 二维数组第一个标识 0-9行&#xff0c;第二个表示 0-9数字&#xff0c;存的内容boolean 表示第0-9行&#xff0c;0-9这些…

系列十二、强引用、软引用、弱引用、虚引用分别是什么?

一、整体架构 二、强引用&#xff08;默认支持模式&#xff09; 2.1、概述 当内存不足时&#xff0c;JVM开始垃圾回收&#xff0c;对于强引用的对象&#xff0c;就算是出现了OOM也不会对该对象进行回收&#xff0c;死都不收。 强引用是我们最常见的普通对象引用&#xff0c;只…

INFINI Labs 产品更新 | 发布 Easysearch Java 客户端,Console 支持 SQL 查询等功能

近年来&#xff0c;日志管理平台越来越流行。使用日志管理平台可以实时地、统一地、方便地管理和查看日志&#xff0c;挖掘日志数据价值&#xff0c;驱动运维、运营&#xff0c;提升服务管理效率。 方案架构 Beats 是轻量级采集器&#xff0c;包括 Filebeat、Metricbeat 等。E…

我叫:选择排序【JAVA】

1.我是个啥子&#xff1f;&#xff1f; 选择式排序&#xff1a;属于内部排序法,从欲排序的数据中,按指定的规则选出某一元素&#xff0c;再依规定交换位置后达到排序的目的。 2.我的思想 基本思想:第一次从arr[0]~arr[n-1]中选取最小值&#xff0c;与arr[0]交换&#xff0c;第…

【Promise12数据集】Promise12数据集介绍和预处理

【Segment Anything Model】做分割的专栏链接&#xff0c;欢迎来学习。 【博主微信】cvxiayixiao 本专栏为公开数据集的介绍和预处理&#xff0c;持续更新中。 要是只想把Promise12数据集的raw形式分割为png形式&#xff0c;快速导航&#xff0c;直接看2&#xff0c;4标题即可 …

个人博客添加访问人数以及访问时间-githubpage

layout: post # 使用的布局&#xff08;不需要改&#xff09; title: 个人博客添加访问人数以及访问时间 # 标题 subtitle: 个人博客优化 #副标题 date: 2023-11-18 # 时间 author: BY ThreeStones1029 # 作者 header-img: img/about_bg.jpg #这篇文章标题背景图片 catalog: tr…

centos7 探测某个tcp端口是否在监听

脚本 nc -vz 192.168.3.128 60001 if [ $? -eq 0 ]; thenecho "tcp succeed" elseecho "tcp failed" fi nc -vz 192.168.3.128 60001 探测192.168.3.128服务器上60001 tcp端口, -vz说明是探测TCP的 端口开启的情况 执行脚本 端口禁用情况 执行脚本

054-第三代软件开发-信号槽

第三代软件开发-信号槽 文章目录 第三代软件开发-信号槽项目介绍信号槽实现原理与MFC消息映射机制区别Qt信号槽机制的优缺点 关键字&#xff1a; Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#x…

Vue中实现div的任意移动

前言 在系统应用中&#xff0c;像图片&#xff0c;流程预览及打印预览等情况&#xff0c;当前视窗无法全部显示要预览的全部内容&#xff0c;设置左右和上下滚动条后&#xff0c;如果用鼠标拖动滚动条&#xff0c;又不太便利&#xff0c;如何用鼠标随意的移动呢&#xff1f; …

Apache ECharts简介

二十九、Apache ECharts 29.1 介绍 Apache ECharts 是一款基于 JavaScript 的数据可视化图表库&#xff0c;提供直观、生动、可交互、可个性化定制的数据可视化图表。 官网地址&#xff1a;https://echarts.apache.org/zh/index.html 常见效果展示&#xff1a; 1). 柱形图 …

定点整数、小数

文章目录 一、定点整数二、定点小数三、定点小数的加/减运算 一、定点整数 二、定点小数 三、定点小数的加/减运算 对两个定点小数A、B进行加法/减法时&#xff0c;需要先转换为补码 计算机硬件如何做定点小数补码的加法&#xff1a;从最低位开始&#xff0c;按位相加&#x…