springboot logback 设置日志级别

  1. 在application.yml 通过配置配置,按住Ctrl + 左键可以看源码
javascript 复制代码
logging:
  level:
    root: info
    com.dj.test.controller: debug
    com.dj.test.service: debug
  1. 自己写接口直接动态修改日志级别,读取application.yml配置文件算是间接修改

所以不能这样写 ctx.getLogger("").setLevel(overallLevel);

java 复制代码
package com.ldj.mybatisflex.controller;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

@RestController
public class LogLevelController {

    @PostMapping("/log/level")
    public String setLogLevel(String rootLevel, String level, String packagePath) {
        LoggerContext ctx = (LoggerContext) LoggerFactory.getILoggerFactory();

        // 设置根日志器的日志级别
        if (rootLevel != null && !rootLevel.trim().isEmpty()) {
            Level overallLevel = Level.toLevel(rootLevel.trim(), null);
            if (overallLevel == null) {
                return "Error: Invalid overall log level: " + rootLevel;
            }

            // 虽然Logback的标准根记录器名称空串""  但是springboot是"ROOT"
            // ctx.getLogger("").setLevel(overallLevel); 
            ctx.getLogger(Logger.ROOT_LOGGER_NAME).setLevel(overallLevel);
        }

        // 设置指定包路径的日志级别
        if (level != null && !level.trim().isEmpty() && packagePath != null && !packagePath.trim().isEmpty()) {
            Level pkgLevel = Level.toLevel(level.trim(), null);
            if (pkgLevel == null) {
                return "Error: Invalid package log level: " + level;
            }
            for (String path : packagePath.split(",")) {
                String p = path.trim();
                if (!p.isEmpty()) {
                    ctx.getLogger(p).setLevel(pkgLevel);
                }
            }
        }

        return "Succeeded in changing the log level";
    }

}

Logback 的"继承规则"(Inheritance Rules)是指:当一个 Logger 没有显式配置自己的 Appender 时,它会自动"继承"其父 Logger 的 Appender。意思说交给根日志器来打印日志

  1. logback-spring.xml 配置
javascript 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">

    <!-- ========== 全局参数 ========== -->
    <property name="APP_NAME" value="mybatis-flex"/>            <!-- 项目名称 -->
    <property name="LOG_HOME" value="/data/logs/mybatis-flex"/> <!-- 日志基本目录-->
    <property name="log.maxHistory" value="7"/>                 <!-- 日志保留7天 -->
    <property name="log.maxSize" value="100MB"/>                <!-- 单个日志文件最大100MB -->
    <property name="log.level" value="INFO"/>                   <!-- 默认日志级别 -->

    <!-- 文件日志格式(含 traceId,便于链路追踪) -->
    <property name="log.pattern"
              value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [traceId:%X{traceId}] %logger{36} - %msg%n"/>

    <!-- 控制台:彩色输出,方便开发/运维查看 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%green(%d{HH:mm:ss.SSS}) [%thread] %highlight(%-5level) %cyan(%logger{20}) - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 业务 INFO 日志(仅你自己的代码) -->
    <appender name="APP_INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/info/${APP_NAME}-info.log</file>
        <createParentDirectories>true</createParentDirectories> <!-- 自动创建目录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/info/${APP_NAME}-info-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern>
            <maxFileSize>${log.maxSize}</maxFileSize>
            <maxHistory>${log.maxHistory}</maxHistory>
            <totalSizeCap>10GB</totalSizeCap>
        </rollingPolicy>
        <encoder><pattern>${log.pattern}</pattern><charset>UTF-8</charset></encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 业务 ERROR 日志(仅你自己的代码) -->
    <appender name="APP_ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/error/${APP_NAME}-error.log</file>
        <createParentDirectories>true</createParentDirectories> <!-- 自动创建目录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/error/${APP_NAME}-error-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern>
            <maxFileSize>${log.maxSize}</maxFileSize>
            <maxHistory>${log.maxHistory}</maxHistory>
            <totalSizeCap>10GB</totalSizeCap>
        </rollingPolicy>
        <encoder><pattern>${log.pattern}</pattern><charset>UTF-8</charset></encoder>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
    </appender>

    <!-- ======================核心:按包路径隔离日志======================= -->
    <!-- 替换为你项目的根包名!例如:com.example.order; additivity="false" 表示不要在传递给根logger(root)再次打印,小弟自己处理就好,不麻烦老板root -->
    <logger name="com.example.order" level="${log.level}" additivity="false">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="APP_INFO_FILE"/>
        <appender-ref ref="APP_ERROR_FILE"/>
    </logger>

    <!-- ======================降噪处理======================= -->
    <!-- 以下框架的低于WARN级别的日志会直接过滤掉, WARN+的日志由于自己没有配置的appender 会传递给rootLogger打印-->
    <logger name="org.springframework" level="WARN"/>
    <logger name="com.zaxxer.hikari" level="WARN"/>
    <logger name="org.apache.catalina" level="WARN"/>
    <logger name="com.fasterxml.jackson" level="WARN"/>

    <!-- ======================兜底处理======================= -->
    <!-- 如果被上面小弟logger已经配置到日志产生包路径,但是小弟自己又没有appender进行处理,对应日志的会传递给老板root兜底打印-->
    <root level="${log.level}">
        <appender-ref ref="CONSOLE"/>
    </root>

</configuration>
相关推荐
C雨后彩虹2 小时前
字符串拼接
java·数据结构·算法·华为·面试
遥远_2 小时前
一次高并发压垮系统的排查与重生(上)
java·微服务·性能优化·高并发·限流·qps
C雨后彩虹2 小时前
ConcurrentHashMap入门:高并发场景的 HashMap替代方案
java·数据结构·哈希算法·集合·hashmap
weixin_425023002 小时前
Spring boot 2.7.18使用knife4j
java·spring boot·后端
产幻少年3 小时前
面试题八股
java
wanghowie3 小时前
01.08 Java基础篇|设计模式深度解析
java·开发语言·设计模式
Data_agent3 小时前
京东商品价格历史信息API使用指南
java·大数据·前端·数据库·python
Knight_AL3 小时前
Java 17 新特性深度解析:记录类、密封类、模式匹配与增强的 switch 表达式对比 Java 8
java·开发语言
最贪吃的虎3 小时前
Spring Boot 自动装配(Auto-Configuration)深度实现原理全解析
java·运维·spring boot·后端·mysql