首页 > 其他分享 >SpringBoot3 整合 Logback

SpringBoot3 整合 Logback

时间:2024-07-07 19:30:26浏览次数:12  
标签:UTF 整合 logback SpringBoot3 file spring 日志 Logback log

SpringBoot3 整合 Logback 日志框架


1. 默认框架实现

SpringBoot3 默认是使用 SLF4J + Logback 作为默认的日志门面和实现,但也支持其他日志系统,如 Log4j2、JUL (Java Util Logging),
这是通过所谓的日志门面实现的,开发者可以根据自己的需求选择合适的日志实现框架进行配置。

日志门面是指通过引入日志框架的抽象层来统一管理应用程序中的日志输出。
SpringBoot 内置了 Commons Logging、SLF4J 或 jboss-logging 作为日志抽象层(门面),具体的实现可以是 Log4j、JUL、Log4j2 或 Logback。

pom 文件中导入 spring-boot-starter-web 依赖后,会自动导入 spring-boot-starter 依赖,而其又依赖 spring-boot-starter-logging
spring-boot-starter-logging 即为 SpringBoot 的日志相关配置。因为 SpringBoot 启动的时候就要用到日志。

SpringBoot 启动后,默认日志如下图所示:
默认日志实现

如果发现控制台日志没有显示颜色,需要在 application 配置文件中设置 spring.output.ansi.enabled=ALWAYS

spring:
    # 配置 ANSI 输出
    output:
        ansi:
            # 有三个可选值:DETECT / ALWAYS / NEVER
            # DETECT - 检查终端是否支持 ANSI,是的话就启用彩色输出,默认值
            # ALWAYS - 不检查,总是彩色输出
            # NEVER - 禁用彩色输出
            enabled: ALWAYS

2. 自定义 Logback 日志框架

在 resources 目录下新建 logback.xmllogback-spring.xml 作为 Logback 的配置文件。


2.1 常用标签解释

<!--
    configuration 根节点
        scan
            当该属性设置为 true 时,配置文件如果发生改变,将会被重新加载,默认值: true
        scanPeriod
            监测 配置文件是否有修改 的时间间隔,如果没有给出时间单位,默认单位是毫秒
            当 scan 为 true 时,此属性生效。默认的时间间隔为 "1 minute",或者设为 "60 seconds"
        debug
            当此属性设置为 true 时,将打印出 logback 内部日志信息,实时查看 logback 运行状态。默认值为 false
-->
<configuration scan="" scanPeriod="" debug="">

    <!-- property 节点用来定义变量值,可以通过 ${} 来使用变量 -->
    <property name="xxx" value="" />

    <!--
        appender 子节点:负责写日志的组件
            name
                指定 appender 的名称
            class
                指定 appender 全限定名,有以下几种:
                ConsoleAppender:日志输出到控制台,类名 ch.qos.logback.core.ConsoleAppender
                FileAppender:日志输入到文件,类名 ch.qos.logback.core.FileAppender
                RollingFileAppender:滚动记录文件,FileAppender 的子类,当符合条件(大小、时间),日志进行切分处理
                    类名:ch.qos.logback.core.rolling.RollingFileAppender
    -->
    <appender name="" class="">
        <!-- encoder 节点:对日志进行格式化 -->
        <encoder>
            <!-- 输出格式,${xxx} 括号中引用的是 property 标签的 name 值 -->
            <pattern>${xxx}</pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>

        <!-- 有两个过滤器可供选择:临界值过滤器,级别过滤器。 -->
        <!-- 临界值过滤器 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <!-- 输出 DEBUG 级别及以上的日志 -->
            <level>DEBUG</level>
        </filter>
        <!--
            级别过滤器
            DENY:日志将立即被抛弃不再经过其他过滤器
            NEUTRAL:有序列表里的下个过滤器过接着处理日志,该级别既不处理,也不抛弃,日志会被保存下来并在本 appender 被执行
            ACCEPT:日志会被立即处理,不再经过剩余过滤器
        -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 只保留 ERROR 级别的日志 -->
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 配置日志输出,根据当前 ROOT 级别,日志输出时,级别高于 ROOT 默认的级别时会输出  -->
    <root level="INFO">
        <!-- 添加 appender 节点到 root 标签下 -->
        <appender-ref ref="" />
    </root>

</configuration>

2.2 日志输出到控制台


2.2.1 自定义输出
<?xml version="1.0" encoding="UTF-8"?>

<configuration  scan="true" scanPeriod="60 seconds" debug="false">

    <!--
        定义变量:输出到控制台的日志格式(彩色输出)

        输出值:
            %d:表示日期
            %thread:表示线程名
            %-5level:"-"左对齐,"5" 不满 5 位右补空格
            %logger{40}:Java 类名(含包名,这里设定了 40 位,若超过 40 位,包名会精简为类似 a.b.c.JavaBean 形式)
            %msg:日志消息
            %n:换行符

        输出颜色:
            %black, %green, %yellow, %blue,
            %magenta, %cyan, %white, %gray,
            %boldRed, %boldGreen, %boldYellow, %boldBlue,
            %boldMagenta, %boldCyan, %boldWhite
            %highlight(建议使用在 level 上,亮高显示区分 level 级别)
    -->
    <property name="log.console.pattern" value="%magenta(%d{yyyy-MM-dd HH:mm:ss:SSS}) [%thread] %highlight([%-5level]) %cyan(%logger{90}) - %msg%n" />

    <!-- 配置控制台的 appender -->
    <appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoder 节点:对日志进行格式化 -->
        <encoder>
            <!-- 输出格式 -->
            <pattern>${log.console.pattern}</pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 配置日志输出,所有的 appender 都要挂载到 root 节点下,level 标签指定了所有 appender 的默认日志级别  -->
    <root level="INFO">
        <appender-ref ref="CONSOLE_APPENDER" />
    </root>

</configuration>

2.2.2 使用 SpringBoot 默认格式输出
<?xml version="1.0" encoding="UTF-8"?>

<configuration  scan="true" scanPeriod="60 seconds" debug="false">

    <!-- 引入 SpringBoot 框架中的默认配置 -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <!-- 配置控制台的 appender -->
    <appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoder 节点:对日志进行格式化 -->
        <encoder>
            <!-- 输出格式,${CONSOLE_LOG_PATTERN} 是在 defaults.xml 中引入的变量 -->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 配置日志输出  -->
    <root level="INFO">
        <appender-ref ref="CONSOLE_APPENDER" />
    </root>

</configuration>

IDEA 启动后,可能日志不是彩色的,需要在 application 配置文件中 添加 spring.output.ansi.enabled = ALWAYS

spring:
    # 配置 ANSI 输出
    output:
        ansi:
            # 有三个可选值:DETECT / ALWAYS / NEVER
            # DETECT - 检查终端是否支持 ANSI,是的话就启用彩色输出,默认值
            # ALWAYS - 不检查,总是彩色输出
            # NEVER - 禁用彩色输出
            enabled: ALWAYS

2.3 日志输出到文件


2.3.1 自定义输出
<?xml version="1.0" encoding="UTF-8"?>

<configuration scan="true" scanPeriod="60 seconds" debug="false">

    <!--
        定义变量:输出到文件的日志格式

        输出值:
            %d:表示日期
            %thread:表示线程名
            %-5level:"-"左对齐,"5" 不满 5 位右补空格
            %logger{40}:Java 类名(含包名,这里设定了 40 位,若超过 40 位,包名会精简为类似 a.b.c.JavaBean 形式)
            %msg:日志消息
            %n:换行符
    -->
    <property name="log.file.pattern" value="%d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] [%-5level] %logger{90} - %msg%n" />
    <!-- 日志文件存储目录 -->
    <property name="log.file.path" value="D:/xxx/UniApp-Shop/xxx/system_logback" />

    <!-- 滚动输出日志到文件 -->
    <appender name="ROLLING_FILE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径 -->
        <file>${log.file.path}/system.log</file>
        <!-- encoder 节点:对日志进行格式化 -->
        <encoder>
            <pattern>${log.file.pattern}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!--
            设置滚动策略,用于配置文件大小限制、保留天数、文件名格式
            TimeBasedRollingPolicy: 基于时间滚动策略
            SizeAndTimeBasedRollingPolicy: 基于大小和时间的滚动策略(对时间滚动策略的补充)
            FixedWindowRollingPolicy: 基于固定窗口的滚动策略
        -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 文件命名格式,%d{yyyy-MM-dd} 表示日期格式,%i 表示文件索引,文件的名字会根据 fileNamePattern 的值,每隔一段时间改变一次 -->
            <fileNamePattern>${log.file.path}/system-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 每个日志文件的大小限制,建议 10MB 起才能有效果 -->
            <maxFileSize>2MB</maxFileSize>
            <!-- 设置保留的日志文件的最大数量,超出数量就删除旧文件。如果设置每天滚动,则下面的 3 代表最多保留 3 天  -->
            <maxHistory>3</maxHistory>
            <!-- 文件总大小 -->
            <totalSizeCap>10MB</totalSizeCap>
        </rollingPolicy>
    </appender>

    <!-- 将各 appender 挂载到 root 节点下,根据当前 ROOT 级别,日志输出时,级别高于 ROOT 默认的级别时会输出  -->
    <root level="DEBUG">
        <appender-ref ref="ROLLING_FILE_APPENDER" />
    </root>

</configuration>

2.3.2 使用 SpringBoot 默认格式输出

参照:2.2.2 使用 SpringBoot 默认格式输出


2.4 过滤器的使用


2.4.1 临界值过滤器 ThresholdFilter
<?xml version="1.0" encoding="UTF-8"?>

<configuration scan="true" scanPeriod="60 seconds" debug="false">

    <!-- 定义日志输出到控制台的格式(含颜色) -->
    <property name="log.console.pattern" value="%magenta(%d{yyyy-MM-dd HH:mm:ss:SSS}) [%thread] %highlight([%-5level]) %cyan(%logger{90}) - %msg%n" />

    <!-- 输出日志到控制台 -->
    <appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.console.pattern}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 临界值过滤器 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <!-- 输出 DEBUG 级别及以上的日志,即,输出:DEBUG / INFO / WARN / ERROR -->
            <level>DEBUG</level>
        </filter>
    </appender>

    <!-- 将各 appender 挂载到 root 节点下,根据当前 ROOT 级别,日志输出时,级别高于 ROOT 默认的级别时会输出  -->
    <root level="DEBUG">
        <appender-ref ref="CONSOLE_APPENDER" />
    </root>

</configuration>

2.4.2 级别过滤器 LevelFilter
<?xml version="1.0" encoding="UTF-8"?>

<configuration scan="true" scanPeriod="60 seconds" debug="false">

    <!-- 定义日志输出到控制台的格式(含颜色) -->
    <property name="log.console.pattern" value="%magenta(%d{yyyy-MM-dd HH:mm:ss:SSS}) [%thread] %highlight([%-5level]) %cyan(%logger{90}) - %msg%n" />

    <!-- 输出日志到控制台 -->
    <appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.console.pattern}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!--
            级别过滤器
            DENY:日志将立即被抛弃不再经过其他过滤器
            NEUTRAL:有序列表里的下个过滤器过接着处理日志,该级别既不处理,也不抛弃,日志会被保存下来并在本 appender 被执行
            ACCEPT:日志会被立即处理,不再经过剩余过滤器
        -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 只保留 ERROR 级别的日志 -->
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 将各 appender 挂载到 root 节点下,根据当前 ROOT 级别,日志输出时,级别高于 ROOT 默认的级别时会输出  -->
    <root level="DEBUG">
        <appender-ref ref="CONSOLE_APPENDER" />
    </root>

</configuration>

2.5 logger 标签指定具体包或类的日志级别

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

<configuration scan="true" scanPeriod="60 seconds" debug="false">

    <!-- 定义日志输出到控制台的格式(含颜色) -->
    <property name="log.console.pattern" value="%magenta(%d{yyyy-MM-dd HH:mm:ss:SSS}) [%thread] %highlight([%-5level]) %cyan(%logger{90}) - %msg%n" />

    <!-- 输出日志到控制台 -->
    <appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.console.pattern}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!--
        logger 标签:用来设置某一个包或者具体的某一个类的日志打印级别
            name 属性:用来指定受此 logger 约束的某一个包或某一个类
            level 属性:用来设置打印级别,若为设置此属性,当前 logger 将会继承上级(root)的级别
            additivity 属性:是否向上级传递打印信息,默认 true
    -->
    <!--
        控制 org.springframework 包下的所有类的 INFO 级别及以上的日志打印
        没有设置 appender,此 logger 本身不打印任何信息
        没有设置 additivity,默认 true,此 logger 的日志信息向上级(ROOT)传递
        ROOT 接到下级传递的信息,交给挂载的 appender-ref(有三个)进行打印输出
    -->
    <logger name="org.springframework" level="INFO" />

    <!-- 将各 appender 挂载到 root 节点下,根据当前 ROOT 级别,日志输出时,级别高于 ROOT 默认的级别时会输出  -->
    <root level="DEBUG">
        <appender-ref ref="CONSOLE_APPENDER" />
    </root>

</configuration>

2.6 从配置文件获取全局属性值

使用 <springProperty scope="context" name="" source="" defaultValue="" /> 标签从 application 文件中获取全局配置。

  • name 属性是在 logback.xml 中引用的名称,对应的值就为 source 或 defaultValue 属性的值
  • source 属性是 application 配置文件中的 变量名(key),通过这个变量名找到 value
  • defaultValue 属性:如果没有找到 source 属性的话就用 defaultValue 的值

注意:
(1) 如果是 从配置文件获取全局属性值 的话,那么 logback 的配置文件名称应为“logback-spring.xml”
(2) logback 的配置文件 关于 springProperty 标签会报红色,是因为 configuration 标签引用了 xsd 文件,不影响可忽略

logback-spring.xml

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

<configuration scan="true" scanPeriod="60 seconds" debug="false">

    <property name="log.file.pattern" value="%d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] [%-5level] %logger{90} - %msg%n" />
    <!-- 日志文件存储目录 -->
    <!-- <property name="log.file.path" value="D:/xxx/UniApp-Shop/xxx/system_logback" /> -->
    <!--
        从 application 配置文件取得 logback.path 的值作为变量,如果没有找到该属性的话就用 defaultValue 的值
        在 Windows 上,可以通过打开 Windows 资源管理器,然后在地址栏中键入 %userprofile% 来找到 user.home
        在 Mac 上,可以通过打开终端应用程序,然后输入 echo $HOME 命令来找到 user.home
        在 Linux 上,可以通过打开终端应用程序,然后输入 echo $HOME 命令来找到 user.home
        使用方式和 property 标签一样,使用 ${} 来引用
    -->
    <springProperty scope="context" name="log.file.path" source="logback.path" defaultValue="${user.home}/ShopSystem/log" />

    <!-- 滚动输出日志到文件 -->
    <appender name="ROLLING_FILE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径 -->
        <file>${log.file.path}/system.log</file>
        <!-- encoder 节点:对日志进行格式化 -->
        <encoder>
            <pattern>${log.file.pattern}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!--
            设置滚动策略,用于配置文件大小限制、保留天数、文件名格式
            TimeBasedRollingPolicy: 基于时间滚动策略
            SizeAndTimeBasedRollingPolicy: 基于大小和时间的滚动策略(对时间滚动策略的补充)
            FixedWindowRollingPolicy: 基于固定窗口的滚动策略
        -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 文件命名格式,%d{yyyy-MM-dd} 表示日期格式,%i 表示文件索引,文件的名字会根据 fileNamePattern 的值,每隔一段时间改变一次 -->
            <fileNamePattern>${log.file.path}/system-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 每个日志文件的大小限制,建议 10MB 起才能有效果 -->
            <maxFileSize>2MB</maxFileSize>
            <!-- 设置保留的日志文件的最大数量,超出数量就删除旧文件。如果设置每天滚动,则下面的 3 代表最多保留 3 天  -->
            <maxHistory>3</maxHistory>
            <!-- 文件总大小 -->
            <totalSizeCap>10MB</totalSizeCap>
        </rollingPolicy>
    </appender>

    <!-- 将各 appender 挂载到 root 节点下,根据当前 ROOT 级别,日志输出时,级别高于 ROOT 默认的级别时会输出  -->
    <root level="DEBUG">
        <appender-ref ref="ROLLING_FILE_APPENDER" />
    </root>

</configuration>

application.yaml

# logback.xml 中日志文件的配置项
logback:
    # 日志文件存储目录
    path: D:/xxx/UniApp-Shop/xxx/system_logback

3. logback 配置文件示例

根据需要自行修改(后续可能进行补充)

logback-spring.xml

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

<configuration scan="true" scanPeriod="60 seconds" debug="false">

    <!-- 定义日志输出到控制台的格式 -->
    <property name="log.console.pattern" value="%magenta(%d{yyyy-MM-dd HH:mm:ss:SSS}) [%thread] %highlight([%-5level]) %cyan(%logger{90}) - %msg%n" />
    <!-- 定义日志输出到文件中的格式 -->
    <property name="log.file.pattern" value="%d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] [%-5level] %logger{90} - %msg%n" />
    <!-- 日志文件存储目录(从 application 配置文件取得) -->
    <springProperty scope="context" name="file.path" source="logback.path" defaultValue="${user.home}/ShopSystem/log" />
    <!-- 输出 info 级别及以上的日志文件名-前缀(从 application 配置文件取得) -->
    <springProperty scope="context" name="file.name.info.prefix" source="logback.file-name.info.prefix" defaultValue="system" />
    <!-- 输出 info 级别及以上的日志文件名-后缀(从 application 配置文件取得) -->
    <springProperty scope="context" name="file.name.info.suffix" source="logback.file-name.info.suffix" defaultValue="log" />
    <!-- 输出 error 级别的日志文件名-前缀(从 application 配置文件取得) -->
    <springProperty scope="context" name="file.name.error.prefix" source="logback.file-name.error.prefix" defaultValue="system.error" />
    <!-- 输出 error 级别的日志文件名-后缀(从 application 配置文件取得) -->
    <springProperty scope="context" name="file.name.error.suffix" source="logback.file-name.error.suffix" defaultValue="log" />

    <!-- 输出日志到控制台 -->
    <appender name="CONSOLE_APPENDER" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.console.pattern}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 输出 DEBUG 级别及以上的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
    </appender>

    <!-- 滚动输出 INFO 级别及以上的日志到文件 -->
    <appender name="ROLLING_FILE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${file.path}/${file.name.info.prefix}.${file.name.info.suffix}</file>
        <encoder>
            <pattern>${log.file.pattern}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 设置滚动策略,基于大小和时间的滚动策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${file.path}/${file.name.info.prefix}.%d{yyyy-MM-dd}.%i.${file.name.info.suffix}</fileNamePattern>
            <maxFileSize>2MB</maxFileSize>
            <maxHistory>3</maxHistory>
            <totalSizeCap>10MB</totalSizeCap>
        </rollingPolicy>
        <!-- 输出 INFO 级别及以上的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
    </appender>

    <!-- 滚动输出 ERROR 级别的日志到文件 -->
    <appender name="ROLLING_FILE_ERROR_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${file.path}/${file.name.error.prefix}.${file.name.error.suffix}</file>
        <encoder>
            <pattern>${log.file.pattern}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 设置滚动策略,基于大小和时间的滚动策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${file.path}/${file.name.error.prefix}.%d{yyyy-MM-dd}.%i.${file.name.error.suffix}</fileNamePattern>
            <maxFileSize>2MB</maxFileSize>
            <maxHistory>3</maxHistory>
            <totalSizeCap>10MB</totalSizeCap>
        </rollingPolicy>
        <!-- 只保留 ERROR 级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 控制 org.springframework 包下的所有类的 INFO 级别及以上的日志打印 -->
    <logger name="org.springframework" level="INFO" />
    <!-- 控制 _org.springframework 包下的所有类的 INFO 级别及以上的日志打印 -->
    <logger name="_org.springframework" level="INFO" />

    <!-- 将各 appender 挂载到 root 节点下  -->
    <root level="DEBUG">
        <appender-ref ref="CONSOLE_APPENDER" />
        <appender-ref ref="ROLLING_FILE_APPENDER" />
        <appender-ref ref="ROLLING_FILE_ERROR_APPENDER" />
    </root>

</configuration>

application.yaml

# logback.xml 中日志文件的配置项
logback:
    # 日志文件存储目录
    path: D:/xxx/UniApp-Shop/xxx/system_logback
    # 文件名
    file-name:
        # 输出 info 级别及以上的日志文件名
        info:
            # 文件名前缀
            prefix: system
            # 文件名后缀
            suffix: log
        # 输出 error 级别的日志文件名
        error:
            # 文件名前缀
            prefix: system.error
            # 文件名后缀
            suffix: log

4. 在 IDEA 中设置 logback.xml 的自动提示功能

参考:https://blog.csdn.net/adley_app/article/details/131365159

  • 方式1
    在 configuration 标签中添加 xmlns、xmlns:xsi 和 xsi:schemaLocation 属性
<configuration xmlns="http://ch.qos.logback/xml/ns/logback"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://ch.qos.logback/xml/ns/logback
               https://raw.githubusercontent.com/enricopulatzo/logback-XSD/master/src/main/xsd/logback.xsd">

  选择 https://raw.githubxxx/xxx/logback.xsd,点击 fetch external resource(提取外部资源),自动下载 xsd 文件

  • 方式2
    若无法下载,则在 resource 目录下创建 logback.xsd 文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!--
    logback.xml schema,
        https://github.com/enricopulatzo/logback-XSD
        https://github.com/nkatsar/logback-XSD
-->
<xsd:schema targetNamespace="http://ch.qos.logback/xml/ns/logback"
            xmlns="http://ch.qos.logback/xml/ns/logback"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified"
            attributeFormDefault="unqualified"
            version="1.1">

    <xsd:element name="configuration" type="Configuration"/>
    <xsd:element name="included" type="Configuration"/>

    <xsd:complexType name="Configuration">
        <xsd:choice maxOccurs="unbounded">
            <xsd:element name="shutdownHook" minOccurs="0" maxOccurs="1" type="ShutdownHook"/>
            <xsd:element name="statusListener" minOccurs="0" maxOccurs="unbounded" type="StatusListener"/>
            <xsd:element name="contextListener" minOccurs="0" maxOccurs="unbounded" type="ContextListener"/>
            <xsd:element name="jmxConfigurator" minOccurs="0" maxOccurs="1" type="JmxConfigurator"/>
            <xsd:element name="conversionRule" minOccurs="0" maxOccurs="unbounded" type="ConversionRule"/>
            <xsd:element name="include" minOccurs="0" maxOccurs="unbounded" type="Include"/>
            <xsd:element name="contextName" minOccurs="0" maxOccurs="1" type="xsd:string"/>
            <xsd:element name="define" minOccurs="0" maxOccurs="unbounded" type="Define"/>
            <xsd:element name="timestamp" minOccurs="0" maxOccurs="1" type="Timestamp"/>
            <xsd:element name="if" minOccurs="0" maxOccurs="unbounded" type="If"/>
            <xsd:element name="property" minOccurs="0" maxOccurs="unbounded" type="Property"/>
            <xsd:element name="appender" minOccurs="0" maxOccurs="unbounded" type="Appender"/>
            <xsd:element name="logger" minOccurs="0" maxOccurs="unbounded" type="Logger"/>
            <xsd:element name="root" minOccurs="0" maxOccurs="1" type="Root"/>
            <xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:choice>
        <xsd:attribute name="debug" type="xsd:boolean" use="optional"/>
        <xsd:attribute name="scan" type="xsd:boolean" use="optional" default="false"/>
        <xsd:attribute name="scanPeriod" type="xsd:string" use="optional" default="1 minute"/>
        <xsd:attribute name="packagingData" type="xsd:boolean" use="optional" default="false"/>
        <xsd:anyAttribute/>
    </xsd:complexType>

    <xsd:complexType name="ShutdownHook">
        <xsd:attribute name="class" type="xsd:string" use="optional"
                       default="ch.qos.logback.core.hook.DelayingShutdownHook"/>
        <xsd:anyAttribute/>
    </xsd:complexType>

    <xsd:complexType name="ConversionRule">
        <xsd:attribute name="conversionWord" type="xsd:string"/>
        <xsd:attribute name="converterClass" type="xsd:string"/>
    </xsd:complexType>

    <xsd:complexType name="StatusListener">
        <xsd:attribute name="class" type="xsd:string" use="optional"/>
        <xsd:anyAttribute/>
    </xsd:complexType>

    <xsd:complexType name="ContextListener">
        <xsd:choice maxOccurs="unbounded">
            <xsd:element name="resetJUL" type="xsd:boolean"/>
            <xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:choice>
        <xsd:attribute name="class" type="xsd:string"/>
        <xsd:anyAttribute/>
    </xsd:complexType>

    <xsd:complexType name="Include">
        <xsd:attribute name="file" use="optional" type="xsd:string"/>
        <xsd:attribute name="resource" use="optional" type="xsd:string"/>
        <xsd:attribute name="url" use="optional" type="xsd:string"/>
        <xsd:attribute name="optional" use="optional" type="xsd:boolean"/>
    </xsd:complexType>

    <xsd:complexType name="Define">
        <xsd:sequence>
            <xsd:any minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
        <xsd:anyAttribute/>
    </xsd:complexType>

    <xsd:complexType name="Timestamp">
        <xsd:sequence>
            <xsd:any minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
        <xsd:attribute name="key" type="xsd:string" use="optional"/>
        <xsd:attribute name="datePattern" type="xsd:string" use="optional"/>
        <xsd:attribute name="timeReference" type="xsd:string" use="optional"/>
        <xsd:anyAttribute/>
    </xsd:complexType>

    <xsd:complexType name="RollingPolicy">
        <xsd:choice maxOccurs="unbounded">
            <xsd:element name="fileNamePattern" minOccurs="1" maxOccurs="1" type="xsd:string"/>
            <xsd:element name="maxHistory" minOccurs="0" maxOccurs="1" type="xsd:int"/>
            <xsd:element name="minIndex" minOccurs="0" maxOccurs="1" type="xsd:int"/>
            <xsd:element name="maxIndex" minOccurs="0" maxOccurs="1" type="xsd:int"/>
            <xsd:element name="timeBasedFileNamingAndTriggeringPolicy" minOccurs="0" maxOccurs="1" type="TriggeringPolicy"/>
            <xsd:element name="cleanHistoryOnStart" minOccurs="0" maxOccurs="1" type="xsd:boolean"/>
            <xsd:element name="maxFileSize" minOccurs="0" maxOccurs="1" type="FileSize"/>
            <xsd:element name="totalSizeCap" minOccurs="0" maxOccurs="1" type="FileSize"/>
        </xsd:choice>
        <xsd:attribute name="class" type="xsd:string" use="required"/>
    </xsd:complexType>

    <xsd:simpleType name="FileSize">
        <xsd:restriction base="xsd:string">
            <xsd:pattern value="[1-9][0-9]*(KB|MB|GB)?"/>
        </xsd:restriction>
    </xsd:simpleType>

    <xsd:complexType name="TriggeringPolicy">
        <xsd:sequence>
            <xsd:element name="maxFileSize" minOccurs="0" maxOccurs="1" type="FileSize"/>
        </xsd:sequence>
        <xsd:attribute name="class" type="xsd:string" use="required"/>
    </xsd:complexType>

    <xsd:complexType name="If">
        <xsd:choice maxOccurs="unbounded">
            <xsd:element type="Configuration" name="then"/>
            <xsd:element type="Configuration" name="else"/>
            <xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:choice>
        <xsd:attribute name="condition" type="xsd:string"/>
        <xsd:anyAttribute/>
    </xsd:complexType>

    <xsd:complexType name="Property">
        <xsd:sequence>
            <xsd:any minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
        <xsd:attribute name="scope" type="xsd:string" use="optional"/>
        <xsd:attribute name="name" type="xsd:string" use="optional"/>
        <xsd:attribute name="value" type="xsd:string" use="optional"/>
        <xsd:attribute name="file" type="xsd:string" use="optional"/>
        <xsd:attribute name="resource" type="xsd:string" use="optional"/>
        <xsd:anyAttribute/>
    </xsd:complexType>

    <xsd:complexType name="Appender">
        <xsd:choice maxOccurs="unbounded">
            <xsd:element name="target" minOccurs="0" maxOccurs="1" type="Target"/>
            <xsd:element name="file" minOccurs="0" maxOccurs="1" type="xsd:string"/>
            <xsd:element name="withJansi" minOccurs="0" maxOccurs="1" type="xsd:boolean"/>
            <xsd:element name="encoder" minOccurs="0" maxOccurs="1" type="Encoder"/>
            <xsd:element name="filter" minOccurs="0" maxOccurs="1" type="Filter"/>
            <xsd:element name="append" minOccurs="0" maxOccurs="1" type="xsd:boolean"/>
            <xsd:element name="prudent" minOccurs="0" maxOccurs="1" type="xsd:boolean"/>
            <xsd:element name="layout" minOccurs="0" maxOccurs="1" type="Layout"/>
            <xsd:element name="rollingPolicy" minOccurs="0" maxOccurs="1" type="RollingPolicy"/>
            <xsd:element name="connectionSource" minOccurs="0" maxOccurs="1" type="ConnectionSource"/>
            <xsd:element name="triggeringPolicy" minOccurs="0" maxOccurs="1" type="TriggeringPolicy"/>
            <xsd:element name="appender-ref" minOccurs="0" maxOccurs="1" type="AppenderRef"/>
            <xsd:any namespace="##other" processContents="skip" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:choice>
        <xsd:attribute name="name" type="xsd:string" use="required"/>
        <xsd:attribute name="class" type="xsd:string" use="required"/>
        <xsd:anyAttribute/>
    </xsd:complexType>

    <xsd:simpleType name="Target">
        <xsd:restriction base="xsd:string">
            <xsd:enumeration value="System.out"/>
            <xsd:enumeration value="System.err"/>
        </xsd:restriction>
    </xsd:simpleType>

    <xsd:complexType name="Filter">
        <xsd:choice maxOccurs="unbounded">
            <xsd:element name="level" minOccurs="0" maxOccurs="unbounded" type="LoggerLevel"/>
            <xsd:element name="onMatch" minOccurs="0" maxOccurs="unbounded" type="MatchValue"/>
            <xsd:element name="onMismatch" minOccurs="0" maxOccurs="unbounded" type="MatchValue"/>
            <xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:choice>
        <xsd:attribute name="class" type="xsd:string" use="optional"/>
        <xsd:anyAttribute/>
    </xsd:complexType>

    <xsd:simpleType name="MatchValue">
        <xsd:restriction base="xsd:string">
            <xsd:enumeration value="ACCEPT"/>
            <xsd:enumeration value="DENY"/>
            <xsd:enumeration value="NEUTRAL"/>
        </xsd:restriction>
    </xsd:simpleType>

    <xsd:complexType name="Layout">
        <xsd:choice maxOccurs="unbounded">
            <xsd:element name="pattern" minOccurs="0" maxOccurs="1" type="xsd:string"/>
            <xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:choice>
        <xsd:attribute name="class" type="xsd:string" use="optional"/>
        <xsd:anyAttribute/>
    </xsd:complexType>

    <xsd:complexType name="Logger">
        <xsd:choice maxOccurs="unbounded">
            <xsd:element name="appender-ref" minOccurs="0" maxOccurs="unbounded" type="AppenderRef"/>
            <xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:choice>
        <xsd:attribute name="name" type="xsd:string" use="required"/>
        <xsd:attribute name="level" type="LoggerLevel" use="optional"/>
        <xsd:attribute name="additivity" type="xsd:boolean" use="optional" default="true"/>
        <xsd:anyAttribute/>
    </xsd:complexType>

    <xsd:complexType name="Encoder">
        <xsd:choice maxOccurs="unbounded">
            <xsd:element name="charset" type="xsd:string" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="immediateFlush" type="xsd:boolean" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="layout" minOccurs="0" maxOccurs="1" type="Layout"/>
            <xsd:element name="outputPatternAsHeader" type="xsd:boolean" minOccurs="0" maxOccurs="1"/>
            <xsd:element name="pattern" type="xsd:string" minOccurs="0" maxOccurs="1"/>
        </xsd:choice>
        <xsd:attribute name="class" type="xsd:string" use="optional"
                       default="ch.qos.logback.classic.encoder.PatternLayoutEncoder"
        />
    </xsd:complexType>

    <xsd:complexType name="Root">
        <xsd:sequence>
            <xsd:element name="appender-ref" minOccurs="0" maxOccurs="unbounded" type="AppenderRef"/>
        </xsd:sequence>
        <xsd:attribute name="level" use="required" type="LoggerLevel"/>
        <xsd:anyAttribute/>
    </xsd:complexType>

    <xsd:complexType name="AppenderRef">
        <xsd:attribute name="ref" type="xsd:string"/>
    </xsd:complexType>

    <xsd:simpleType name="LoggerLevel">
        <xsd:union>
            <xsd:simpleType>
                <xsd:restriction base="xsd:string">
                    <xsd:enumeration value="OFF"/>
                    <xsd:enumeration value="off"/>
                    <xsd:enumeration value="ALL"/>
                    <xsd:enumeration value="all"/>
                    <xsd:enumeration value="INHERITED"/>
                    <xsd:enumeration value="inherited"/>
                    <xsd:enumeration value="NULL"/>
                    <xsd:enumeration value="null"/>
                    <xsd:enumeration value="ERROR"/>
                    <xsd:enumeration value="error"/>
                    <xsd:enumeration value="WARN"/>
                    <xsd:enumeration value="warn"/>
                    <xsd:enumeration value="INFO"/>
                    <xsd:enumeration value="info"/>
                    <xsd:enumeration value="DEBUG"/>
                    <xsd:enumeration value="debug"/>
                    <xsd:enumeration value="TRACE"/>
                    <xsd:enumeration value="trace"/>
                </xsd:restriction>
            </xsd:simpleType>
            <xsd:simpleType>
                <xsd:restriction base="xsd:string">
                    <xsd:pattern value="($\{.+:-)?[Oo][Ff]{2}\}?"/>
                    <xsd:pattern value="($\{.+:-)?[Aa][Ll]{2}\}?"/>
                    <xsd:pattern value="($\{.+:-)?[Ii][Nn][Hh][Ee][Rr][Ii][Tt][Ee][Dd]\}?"/>
                    <xsd:pattern value="($\{.+:-)?[Nn][Uu][Ll]{2}\}?"/>
                    <xsd:pattern value="($\{.+:-)?[Ee][Rr]{2}[Oo][Rr]\}?"/>
                    <xsd:pattern value="($\{.+:-)?[Ww][Aa][Rr][Nn]\}?"/>
                    <xsd:pattern value="($\{.+:-)?[Ii][Nn][Ff][Oo]\}?"/>
                    <xsd:pattern value="($\{.+:-)?[Dd][Ee][Bb][Uu][Gg]\}?"/>
                    <xsd:pattern value="($\{.+:-)?[Tt][Rr][Aa][Cc][Ee]\}?"/>
                    <xsd:pattern value="\$\{.+\}"/>
                </xsd:restriction>
            </xsd:simpleType>
        </xsd:union>
    </xsd:simpleType>

    <xsd:complexType name="JmxConfigurator"/>

    <xsd:complexType name="ConnectionSource">
        <xsd:sequence>
            <xsd:element name="driverClass" type="xsd:string"/>
            <xsd:element name="url" type="xsd:string"/>
            <xsd:element name="user" type="xsd:string"/>
            <xsd:element name="password" type="xsd:string"/>
        </xsd:sequence>
        <xsd:attribute name="class" type="xsd:string" use="required"/>
    </xsd:complexType>

</xsd:schema>
  • 方式3
    若不想在 resource 目录下创建 xsd 文件,可将 xsd 文件放到本地。
    在 方式1 中自动下载的 xsd 一般放在 C:\Users\xxx\AppData\Local\JetBrains\IdeaIC2024.1\extResources 目录下,
    File > Settings... > Languages & Frameworks > Schemas and DTDs > 在右侧 "External schemas and DTDs" 区域添加关联
      URI: xml 文件中引用的 xsd 地址,即,https://raw.githxxx/logback.xsd
      File: 本地存放 xsd 的路径

参考:

https://www.cnblogs.com/gavincoder/p/10091757.html
https://www.dandelioncloud.cn/article/details/1530032828347858945
https://cloud.tencent.com/developer/article/1733197
https://www.cnblogs.com/wlovet/p/17517263.html
https://www.cnblogs.com/hefeng2014/p/17973169
https://blog.csdn.net/qq_21259459/article/details/106517209


以上!

2024年7月7日 19:28

标签:UTF,整合,logback,SpringBoot3,file,spring,日志,Logback,log
From: https://www.cnblogs.com/wuze-blog/p/18287445

相关文章

  • vite+vue3整合less教程
    1、安装依赖pnpminstall-Dlessless-loader2、定义全局css变量文件src/assets/css/global.less:root{--public_background_font_Color:red;--publicHouver_background_Color:#fff;--header_background_Color:#fff;--menu_background:#fff;}3、......
  • springboot整合ElasticSearch
    RestClient依赖,此为java的客户端,从来交互elasticsearch<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId></dependency>因为SpringBoot默认的ES版本是7.17.10,所以我们需要......
  • SpringBoot整合Dubbo的快速使用教程
        目录一、什么是Dubbo?二、SpringBoot整合Dubbo 1、父工程引入依赖2、各个Dubbo服务子模块引入依赖3、服务提供者 (1)启动类添加注解@EnableDubbo(2)服务类添加注解@DubboService(3)配置文件配置dubbo的信息4、服务的消费者 (1)启动类添加注解@EnableDubbo(2)接......
  • activiti流程配置——vue整合bpmn.js
    acitivti提供了流程图绘制的应用,可以整合到流程项目钟。但是现在很多项目都是前后端分离,vue前端开发比较多。所以,我用vue整合了一下bpmn。具体的整合过程,网上有大把的资料可以参考;我这边就不罗列了。我主要记录一下,vue整合bpmn过程中,对于activiti流程而言有几个地方要注意:......
  • Spring Cloud Gateway整合Knife4j 4.4.0实现微服务聚合文档(报错解决详细版)
    以前做过的都是单服务应用的文档,就算换到了微服务里做的实际上也是单服务(每个服务模块一个单独的文档,然后手动访问不同的端口去查找不同的模块文档,例如用户是3000端口,订单是3100端口,商品是3200端口)。这样的实现实际上挺蠢的,对前端伙伴很不友好,对自己测试也不友好,因此今天要说的......
  • Springboot整合Apollo
    一、Apollo作用随着程序功能的日益复杂,程序的配置日益增多:各种功能的开关、参数的配置、服务器的地址……对程序配置的期望值也越来越高:配置修改后实时生效,灰度发布,分环境、分集群管理配置,完善的权限、审核机制……在这样的大环境下,传统的通过配置文件、数据库等方式已经越来越......
  • 全网最简单由浅入深的二极管知识,重新归纳整合,是初学者的宝藏文章
        二极管具有电流单向导通的特性,二极管可大致分为半导体二极管和真空二极管。半导体二极管是制作在半导体材料上的,并不具有实际的管状结构,而早期的二极管却真真切切地是被制作在玻璃管中的,它的工作原理也和半导体二极管不同。    1873年,弗雷德里克·格思里(Fr......
  • SpringBoot3连接Mysql数据库
    pom引入包,启动器<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.o......
  • 飞书集成机器人搭建实战/多平台整合机器人源码部署流程
    一、引言在当今数字化办公时代,多平台整合成为提高工作效率的关键。飞书集成机器人能够打通不同平台之间的壁垒,实现信息的快速流通和协同办公。本文将带您实战搭建飞书集成机器人,并详细介绍多平台整合机器人的源码部署流程。二、集成需求分析在开始搭建之前,我们需要明确集成......
  • springboot3(cloud 2022.0.0)整合seata1.7.1
    一、第一步下载对应版本的seata服务  二、修改conf下的application.yml配置注意:主要是连接nacos的一些配置:注册中心和服务发现的配置1#Copyright1999-2019Seata.ioGroup.2#3#LicensedundertheApacheLicense,Version2.0(the"License");4#you......