SpringBoot中日志的使用log4j

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-loggingartifactId>
  <groupId>org.springframework.bootgroupId>
dependency>

SpringBoot中日志的使用log4j_第1张图片

org.springframework.boot的依赖:

<dependencies>
  <dependency>
    <groupId>ch.qos.logbackgroupId>
    <artifactId>logback-classicartifactId>
    <version>1.2.6version>
    <scope>compilescope>
  dependency>
  <dependency>
    <groupId>org.apache.logging.log4jgroupId>
    <artifactId>log4j-to-slf4jartifactId>
    <version>2.14.1version>
    <scope>compilescope>
  dependency>
  <dependency>
    <groupId>org.slf4jgroupId>
    <artifactId>jul-to-slf4jartifactId>
    <version>1.7.32version>
    <scope>compilescope>
  dependency>
dependencies>

1.2 spring-boot-starter

SpringBoot中日志的使用log4j_第2张图片

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.bootgroupId>
    <artifactId>spring-boot-starter-loggingartifactId>
dependency>

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

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

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

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-webartifactId>
dependency>

完整 pom.xml 文件:


<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.0modelVersion>
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.5.6version>
        <relativePath/>
    parent>

    <groupId>com.loggroupId>
    <artifactId>spring-boot-logartifactId>
    <version>0.0.1-SNAPSHOTversion>
    <name>spring-boot-logname>
    <description>spring-boot-logdescription>

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

    <dependencies>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>

    dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            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:

会生成:

SpringBoot中日志的使用log4j_第3张图片

我们设置:

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

SpringBoot中日志的使用log4j_第4张图片

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中日志的使用log4j_第5张图片

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

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

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

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

日志框架 配置文件
Logback logback-spring.xml、logback.xml
Log4j2 log4j2-spring.xml、log4j2.xml
JUL logging.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">
    
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%npattern>
    encoder>
  appender>
 
  <logger name="chapters.configuration" level="INFO"/>
 
  
  
  <root level="DEBUG">          
    <appender-ref ref="STDOUT" />
  root>  
  
configuration>

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

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

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


<configuration>
 
    
    
    <property name="pattern" value="[%-5level]  %d{yyyy-MM-dd HH:mm:ss}  %c  %M  %L  %thread  %m  %n"/>
  
    
    <appender name="myConsole" class="ch.qos.logback.core.ConsoleAppender">
        
        <target>System.errtarget>
        
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}pattern>
        encoder>
    appender>
 
 
    
    <logger name="com.ahead" level="info" additivity="false">
        <appender-ref ref="myConsole" />
    logger>
configuration>

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

4.3 元素

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

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

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

SpringBoot中日志的使用log4j_第6张图片

4.4 元素

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

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

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

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

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

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

Logger name Assigned level Effective level
root DEBUG DEBUG
X none DEBUG
X.Y none DEBUG
X.Y.Z none DEBUG

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

Logger name Assigned level Effective level
root ERROR ERROR
X INFO INFO
X.Y DEBUG DEBUG
X.Y.Z WARN WARN

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

Logger name Assigned level Effective level
root DEBUG DEBUG
X INFO INFO
X.Y none INFO
X.Y.Z ERROR ERROR

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

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

Logger name Assigned level Effective level
root DEBUG DEBUG
X INFO INFO
X.Y none INFO
X.Y.Z none INFO

4.5 元素

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

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

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

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

4.6 元素

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

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

元素可以包含零个或一个元素,零个或多个元素以及零个或多个

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

SpringBoot中日志的使用log4j_第7张图片

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

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

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

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

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

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

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

SpringBoot中日志的使用log4j_第8张图片

其中最重要的两个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中最重要就是pattern属性,它负责控制输出日志的格式,这里给出一个我自己写的示例:

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

其中:

# 日期
%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中最重要的两个过滤器为:LevelFilterThresholdFilter

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

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

出:

<configuration>
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>INFOlevel>
      <onMatch>ACCEPTonMatch>
      <onMismatch>DENYonMismatch>
    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">
    
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
      <level>INFOlevel>
    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






<configuration scan="true" scanPeriod="10 seconds">

    <contextName>spring-boot-logcontextName>

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

    
    
    <springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
    
    <property name="FILE_DIR" value="D:\\logs\\${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}}"/>
    
    
    <property name="LOG_FORMAT" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
    

    
    
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        
        
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUGlevel>
        filter>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            
            <springProfile name="dev">
                <pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level]  %m%npattern>
            springProfile>
            
            <springProfile name="pro">
                
                <pattern>${CONSOLE_LOG_FORMAT}pattern>
                
                <charset>UTF-8charset>
            springProfile>
        encoder>
    appender>

    
    
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>${FILE_DIR}\\spring-log.logfile>
        <append>trueappend>
        <encoder>
            
            <pattern>${LOG_FORMAT}pattern>
        encoder>
    appender>

    
    
    <appender name="FILE_ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
        
        <file>${ROLL_FILE_DIR}\\spring-log-rolling.logfile>
        
        <encoder>
            
            <pattern>${LOG_FORMAT}pattern>
            
            <charset>UTF-8charset>
        encoder>
        
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${ROLL_FILE_DIR}\\spring-log-rolling.%d{yyyy-MM-dd}.%i.logfileNamePattern>
            
            <maxHistory>30maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                
                <maxFileSize>100MBmaxFileSize>
            timeBasedFileNamingAndTriggeringPolicy>
            
            
            <totalSizeCap>500MBtotalSizeCap>
            <cleanHistoryOnStart>truecleanHistoryOnStart>
        rollingPolicy>
        
    appender>
    

    

    

    
    
    
    
    

    
    <root level="info">
        
        
        
        <appender-ref ref="CONSOLE" />
        
        <appender-ref ref="FILE" />
        
        <appender-ref ref="FILE_ROLLING" />
    root>
    

    
    

    
    
    
configuration>

使用是需要设置:

spring.profiles.active = dev/pro

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

  
  
  
  
  
  
  
  
<configuration scan="true" scanPeriod="60 seconds" debug="false">  
      
    <property name="log_dir" value="/customize/logs" />  
      
    <property name="maxHistory" value="30"/>  
      
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">  
          
        <encoder>  
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger -%msg%npattern>  
        encoder>  
    appender>  
      
      
      
      
    <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">  
          
        <filter class="ch.qos.logback.classic.filter.LevelFilter">  
            <level>ERRORlevel>  
            <onMatch>ACCEPTonMatch>  
            <onMismatch>DENYonMismatch>  
        filter>  
          
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
              
            <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/error-log.logfileNamePattern>  
              
            <maxHistory>${maxHistory}maxHistory>  
        rollingPolicy>  
          
          
          
          
        <encoder>  
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%npattern>  
        encoder>  
    appender>  
      
      
      
      
    <appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">  
          
        <filter class="ch.qos.logback.classic.filter.LevelFilter">  
            <level>WARNlevel>  
            <onMatch>ACCEPTonMatch>  
            <onMismatch>DENYonMismatch>  
        filter>  
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
              
            <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/warn-log.log  
            fileNamePattern>  
              
            <maxHistory>${maxHistory}maxHistory>  
        rollingPolicy>  
        <encoder>  
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%npattern>  
        encoder>  
    appender>  
      
      
      
      
      
    <appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">  
          
        <filter class="ch.qos.logback.classic.filter.LevelFilter">  
            <level>INFOlevel>  
            <onMatch>ACCEPTonMatch>  
            <onMismatch>DENYonMismatch>  
        filter>  
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
              
            <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/info-log.log  
            fileNamePattern>  
              
            <maxHistory>${maxHistory}maxHistory>  
        rollingPolicy>  
        <encoder>  
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%npattern>  
        encoder>  
    appender>  
      
      
      
      
      
    <appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">  
          
        <filter class="ch.qos.logback.classic.filter.LevelFilter">  
            <level>DEBUGlevel>  
            <onMatch>ACCEPTonMatch>  
            <onMismatch>DENYonMismatch>  
        filter>  
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
              
            <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/debug-log.log  
            fileNamePattern>  
              
            <maxHistory>${maxHistory}maxHistory>  
        rollingPolicy>  
        <encoder>  
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%npattern>  
        encoder>  
    appender>  
      
      
      
      
      
    <appender name="TRACE" class="ch.qos.logback.core.rolling.RollingFileAppender">  
          
        <filter class="ch.qos.logback.classic.filter.LevelFilter">  
            <level>TRACElevel>  
            <onMatch>ACCEPTonMatch>  
            <onMismatch>DENYonMismatch>  
        filter>  
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
              
            <fileNamePattern>${log_dir}/%d{yyyy-MM-dd}/trace-log.log  
            fileNamePattern>  
              
            <maxHistory>${maxHistory}maxHistory>  
        rollingPolicy>  
        <encoder>  
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%npattern>  
        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 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


<configuration debug="true">
 
    
    
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        
        
        <encoder>
            
            
            
            
            
            
            
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) --- [%15.15(%thread)] %cyan(%-40.40(%logger{40})) : %msg%npattern>
            
            <charset>UTF-8charset>
        encoder>
    appender>
 
    
    
    
    
    <appender name="info_log" class="ch.qos.logback.core.rolling.RollingFileAppender">
        
        <File>logs/project_info.logFile>
        
        <append>trueappend>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERRORlevel>
            <onMatch>DENYonMatch>
            <onMismatch>ACCEPTonMismatch>
        filter>
        
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            
            
            
            <fileNamePattern>logs/project_info.%d.%i.logfileNamePattern>
            
            <maxHistory>30maxHistory>
            
            <totalSizeCap>20GBtotalSizeCap>
            
            <maxFileSize>10MBmaxFileSize>
        rollingPolicy>
        
        <encoder>
            
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{40}) : %msg%npattern>
            
            <charset>UTF-8charset>
        encoder>
    appender>
 
    
    
    
    
    <appender name="error_log" class="ch.qos.logback.core.rolling.RollingFileAppender">
        
        <File>logs/project_error.logFile>
        
        <append>trueappend>
        
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERRORlevel>
        filter>
        
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            
            
            
            <fileNamePattern>logs/project_error.%d.%i.logfileNamePattern>
            
            <maxHistory>30maxHistory>
            
            <totalSizeCap>20GBtotalSizeCap>
            
            <maxFileSize>10MBmaxFileSize>
        rollingPolicy>
        
        <encoder>
            
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{40}) : %msg%npattern>
            
            <charset>UTF-8charset>
        encoder>
    appender>
 
    
    
    <root level="INFO">
        <appender-ref ref="STDOUT" />
    root>
 
    
    
    <logger name="com.sailing.springbootmybatis" level="INFO">
        <appender-ref ref="info_log" />
        <appender-ref ref="error_log" />
    logger>
 
    
    <logger name="com.sailing.springbootmybatis.mapper" level="DEBUG" additivity="false">
        <appender-ref ref="info_log" />
        <appender-ref ref="error_log" />
    logger>
 
    
    <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 的多个重载函数:

SpringBoot中日志的使用log4j_第9张图片

你可能感兴趣的:(spring,boot,spring,boot)