关于SpringBoot 如何动态切换 logback 日志的输出级别

本文详细介绍了如何在SpringBoot应用中通过接口动态设置Logback的日志级别,以便根据不同场景调整日志输出,提升开发和运维效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

摘要:

1. 引言

2.Springboot项目默认的日志配置

2.1 Logback日志级别介绍

2.2 扩展:Logback和slf4j的区别

3.SpringBoot动态设置Logback日志级别的方法

3.1 描述

3.2 编写Controller接口

3.3 运行结果展示      

3.3.1日志输出级别为INFO时

3.3.1.1获取日志输出级别

3.3.1.2 测试日志输出级别

3.3.2 切换日志输出级别为DEBUG

3.3.2.1 切换日志输出级别

3.3.2.2 验证日志输出级别是否切换成功

4. 总结


摘要:

        本文将详细介绍在SpringBoot应用中如何动态设置Logback日志的输出级别。所谓动态,就是在不影响服务正常运行的情况下,通过接口的方式实现日志级别的动态调整,可以满足不同环境、不同业务场景下的日志需求,提高开发和运维的效率。

1. 引言

        在软件开发的过程中,日志系统作为追踪、调试、优化和监控应用运行状态的重要手段,一直发挥着至关重要的作用。对于Java Web应用来说,Logback凭借其优秀的性能和灵活的配置,成为了许多开发者的首选日志框架。而Spring Boot,作为简化Spring应用开发的框架,内置了对Logback的支持,进一步简化了日志的配置和管理。

        然而,在实际的应用场景中,我们常常需要根据不同的运行环境、业务需求或者系统性能等因素,动态地调整日志的级别。比如,在开发阶段,我们可能需要将日志级别设置为DEBUG,以便详细追踪代码的执行过程;而在生产环境中,为了避免产生过多的日志影响系统性能,我们可能会将日志级别调整为INFO或者WARN。传统的日志级别配置通常是在配置文件(如application.properties或logback.xml)中静态设置的,这种方式在应对动态需求时显得不够灵活。

        因此,如何在Spring Boot应用中实现Logback日志级别的动态设置,成为了一个值得关注的问题。通过动态设置日志级别,我们可以根据实际需求灵活地调整日志的输出,既满足了开发调试的需要,又保证了生产环境的稳定运行。

2.Springboot项目默认的日志配置

2.1 Logback日志级别介绍

        Spring Boot项目的默认日志配置主要依赖于其内置的日志框架——Logback。Logback是一个功能强大且灵活的日志框架,由Log4j的作者开发。Spring Boot默认使用Logback来记录日志,并提供了默认的日志配置文件logback-spring.xml,该文件通常位于项目的src/main/resources目录下。

         在Logback中,日志级别从低到高分为:TRACE < DEBUG < INFO < WARN < ERROR。默认情况下,如果设置为某个级别,那么比它高的级别都会被记录。例如,如果设置级别为INFO,那么INFO、WARN、ERROR级别的日志都会被记录,而DEBUG、TRACE级别的日志则不会被记录。

        在默认配置下,Spring Boot的日志级别被设置为INFO,这意味着只会输出INFO级别及以上的日志,如WARN和ERROR。更详细的日志级别,如DEBUG和TRACE,默认情况下是不会输出的。这种配置方式有助于在生产环境中减少不必要的日志输出,避免磁盘空间被填满。

        此外,Spring Boot还允许通过配置文件(如application.properties或application.yml)来动态调整日志级别。你可以在这些文件中设置具体的包或类的日志级别,以满足不同的需求。

        关于日志输出格式,Spring Boot也提供了默认的配置。日志输出通常包括日期、时间、日志级别、进程ID、线程名、源码类名以及详细的日志信息。这种格式化的输出有助于开发者快速定位问题。

        最后,Spring Boot还支持彩色输出,如果你的终端支持ANSI,可以通过在application.properties中设置spring.output.ansi.enabled参数来启用。这会使日志输出更具可读性。

        总的来说,Spring Boot的默认日志配置旨在提供一套简洁、高效且易于配置的日志解决方案,以满足大多数常见的日志需求。同时,它也提供了足够的灵活性,允许开发者根据实际需求进行自定义配置。

2.2 扩展:Logback和slf4j的区别

        Logback和SLF4J在日志记录领域各自扮演着不同的角色,它们的主要区别体现在概念、用途以及在实际应用中的协作方式上。

Logback

        Logback是一个具体的日志框架,由Log4j的创始人设计,旨在解决Log4j存在的问题。它是一个功能强大且灵活的日志系统,提供了丰富的配置选项和特性。Logback可以直接输出日志到控制台、文件或数据库等,并支持多种日志级别和格式化选项。通过配置文件(如logback.xml),开发者可以详细定义日志的行为,包括日志的输出格式、级别、滚动策略等。

SLF4J(Simple Logging Facade for Java)

        SLF4J则是一个日志抽象层或称为日志门面,它本身并不提供日志的实现功能。相反,它定义了一套统一的日志记录接口,如LoggerLoggerFactory,使得开发者可以通过这些接口来进行日志记录,而无需关心具体的日志实现框架。SLF4J的主要目标是使得各种日志框架(如Logback、Log4j等)的使用方式统一化,从而简化日志框架的切换过程。

区别与协作

  1. 角色与功能:Logback是具体的日志记录实现,负责实际的日志输出和管理;而SLF4J则是日志的抽象层,定义了日志记录的接口,使得开发者可以方便地使用这些接口进行日志记录,而不必关心底层实现。
  2. 使用方式:在实际应用中,开发者通常会使用SLF4J的接口进行日志记录,而Logback则作为SLF4J的实现框架在背后工作。这意味着,当开发者调用SLF4J的接口记录日志时,实际上是Logback在负责处理这些日志记录请求。
  3. 灵活性与可替换性:由于SLF4J是一个抽象层,它允许开发者根据需要选择具体的日志实现框架。这意味着,如果开发者发现Logback不能满足某些特定需求,他们可以很容易地切换到另一个实现了SLF4J接口的日志框架,如Log4j,而无需修改大量的日志记录代码。

        总结来说,Logback和SLF4J在日志记录中各自扮演着重要的角色。Logback提供了强大的日志实现功能,而SLF4J则通过统一的接口简化了日志框架的使用和切换过程。在实际应用中,它们通常一起使用,以提供高效、灵活且易于管理的日志记录方案。

3.SpringBoot动态设置Logback日志级别的方法

3.1 描述

        首先,我们需要通过Spring的依赖注入功能,获取到Logback的LoggerContext对象。LoggerContext是Logback的核心类,负责管理所有的日志对象和配置。

        主要依赖是:

import org.slf4j.LoggerFactory;  
import ch.qos.logback.classic.LoggerContext; 

        然后通过LoggerContext对象,我们可以获取到指定的Logger对象,通过其内部的setLevel()修改其日志级别、getLevel()获取当前日志级别

        通过接口的形式,在不影响项目运行情况的前提下,动态切换日志输出级别。

3.2 编写Controller接口

该接口主要包含三个方法:

  • testLoggerLevel():测试日志输出级别
  • getLocalLoggerLevel():获取当前日志输出级别
  • loggerLevelChange(@PathVariable("level") String level):更改日志输出级别
package com.fz.coldchainbase.server.controller;

import com.myd.common.core.domain.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.impl.StaticLoggerBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
/**
 * @Author ZhaoShuHao
 * @Date 2024/3/8 11:09
 */
@RestController
@RequestMapping("/logger")
@Api(tags = "日志输出级别动态切换接口")
public class LoggerController {
    private final static Logger logger = LoggerFactory.getLogger(LoggerController.class);


    @ApiOperation("测试日志输出级别")
    @PostMapping("/testLoggerLevel")
    public R testLoggerLevel(){
        /**
         * 日志输出级别的优先级通常按照其重要性和详细程度进行排序。一般而言,
         * 优先级从高到低依次为:FATAL>ERROR>WARN>INFO>DEBUG>TRACE。
         * 这个顺序反映了不同级别日志信息的紧急程度和详细程度。
         * 输出规则是:只有等于或高于该级别的日志信息才会被输出
         */
        logger.trace("------我是trace---------");
        logger.debug("------我是debug---------");
        logger.info("-------我是info----------");
        logger.warn("-------我是warn----------");
        logger.error("------我是error---------");
        return R.ok("测试成功,请去控制台查看日志输出");
    }

    @ApiOperation("获取当前日志输出级别")
    @PostMapping("/getLocalLoggerLevel")
    public R getLocalLoggerLevel(){
        // 获取 LoggerContext
        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
        // 获取 Logger 实例,这里假设我们要获取 root logger 的级别
        ch.qos.logback.classic.Logger rootLogger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
        // 获取当前日志级别
        Level currentLevel = rootLogger.getLevel();
        // 输出当前日志级别
       logger.debug("当前日志输出级别为:" + currentLevel.levelStr);
        return R.ok("当前日志输出级别为:" + currentLevel.levelStr);
    }


    @ApiOperation("更改日志输出级别")
    @ApiImplicitParam(dataType = "String",paramType = "path",name = "level",value = "debug、info、warn、error")
    @PostMapping("/loggerLevelChange/{level}")
    public R loggerLevelChange(@PathVariable("level") String level){
        String loggerFactoryClassStr = StaticLoggerBinder.getSingleton().getLoggerFactoryClassStr();
       logger.debug("loggerFactoryClassStr>>>>" + loggerFactoryClassStr);
        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
        ch.qos.logback.classic.Logger logger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
        switch (level.toLowerCase()) {
            case "debug":
                logger.setLevel(Level.DEBUG);
                break;
            case "info":
                logger.setLevel(Level.INFO);
                break;
            case "warn":
                logger.setLevel(Level.WARN);
                break;
            case "error":
                logger.setLevel(Level.ERROR);
                break;
            default:
                return R.fail("请输入正确的日志级别");
        }
        return R.ok("日志输出级别已切换为:"+level);
    }

}

3.3 运行结果展示      

3.3.1日志输出级别为INFO时

3.3.1.1获取日志输出级别

默认的输出级别是INFO,调用获取当前日志输出级别接口进行测试:

返回结果,可以看到当前级别为:info

{
  "code": 200,
  "msg": null,
  "data": "当前日志输出级别为:INFO"
}

3.3.1.2 测试日志输出级别

调用测试日志输出级别接口进行测试:

可以看到控制台输出结果为:

        优先级从高到低依次为:FATAL>ERROR>WARN>INFO>DEBUG>TRACE,只会输出高于或等于当前日志输出级别的日志。所以,DEBUG、TRACE优先级低,不会输出。结果输出正确。

3.3.2 切换日志输出级别为DEBUG

3.3.2.1 切换日志输出级别

调用更改日志输出级别接口:

返回结果为:

{
  "code": 200,
  "msg": null,
  "data": "日志输出级别已切换为:debug"
}

3.3.2.2 验证日志输出级别是否切换成功

调用获取日志输出级别接口:

返回结果为:

{
  "code": 200,
  "msg": null,
  "data": "当前日志输出级别为:DEBUG"
}

调用测试日志输出级别接口:

可以看到结果为:

        优先级从高到低依次为:FATAL>ERROR>WARN>INFO>DEBUG>TRACE,只会输出高于或等于当前日志输出级别的日志。所以,TRACE优先级低,不会输出。结果输出正确。

4. 总结

        本文介绍了在SpringBoot应用中如何动态设置Logback日志的输出级别,并且不影响服务正常运行。通过接口方式实现日志级别的动态调整,可以方便地适应不同环境、不同业务场景下的日志需求,提高开发和运维的效率。在实际应用中,还需要注意线程安全、配置刷新和权限控制等问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大手你不懂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值