> For the complete documentation index, see [llms.txt](https://www.onee.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.onee.io/blog/apollo-pei-zhi-zhong-xin-shi-zhan-chang-jing/dong-tai-bian-geng-ri-zhi-shu-chu-ji-bie.md).

# 动态变更日志输出级别

> Apollo（阿波罗）是携程框架部门研发的开源配置管理中心，能够集中化管理应用不同环境、不同集群的配置，配置修改后能够实时推送到应用端，并且具备规范的权限、流程治理等特性。
>
> 官方仓库：<https://github.com/ctripcorp/apollo/>

对于已经接入 Apollo 配置中心的 SpringBoot 项目来说，实现日志输出级别动态实时更新非常容易，只需要以下两步：

#### 第一步：在 Apollo 项目中添加配置 "log.level"，值为 "INFO" 即可，如下图所示：

![](https://cdn.jsdelivr.net/gh/onee-io/onee-resource/picgo/20210528163058.png)

#### 第二步：在 SpringBoot 项目中添加配置类 `LogbackConfig.java`，内容如下：

```java
import cn.hutool.core.util.StrUtil;
import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigService;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.context.annotation.Configuration;
 
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
 
/**
 * 日志配置
 *
 * @author onee
 */
@Slf4j
@Configuration
public class LogbackConfig {
 
    /**
     * 日志级别配置KEY
     */
    private static final String LOG_LEVEL_KEY = "log.level";
 
    /**
     * 默认日志输出级别
     */
    private static final LogLevel DEFAULT_LOG_LEVEL = LogLevel.INFO;
 
    /**
     * 日志系统
     */
    @Resource
    private LoggingSystem loggingSystem;
 
    /**
     * 初始化日志输出级别
     */
    @PostConstruct
    private void initLogLevel() {
        Config config = ConfigService.getAppConfig();
        setLogLevel(config.getProperty(LOG_LEVEL_KEY, LogLevel.INFO.name()));
    }
 
    /**
     * 监听日志级别变更事件
     *
     * @param changeEvent 变更事件
     */
    @ApolloConfigChangeListener()
    private void logLevelOnChange(ConfigChangeEvent changeEvent) {
        if (changeEvent.isChanged(LOG_LEVEL_KEY)) {
            setLogLevel(changeEvent.getChange(LOG_LEVEL_KEY).getNewValue());
        }
    }
 
    /**
     * 设置日志输出级别
     *
     * @param level 级别
     */
    private void setLogLevel(String level) {
        LogLevel logLevel = DEFAULT_LOG_LEVEL;
        if (StrUtil.isNotBlank(level)) {
            try {
                logLevel = LogLevel.valueOf(level.toUpperCase());
            } catch (Exception e) {
                log.error("日志级别错误，将使用默认日志输出级别：{}", DEFAULT_LOG_LEVEL);
            }
        }
        loggingSystem.setLogLevel("", logLevel);
        log.info("设置日志输出级别为:{}", logLevel);
    }
}
```

#### 测试

完成以上两步就可以实现日志级别的实时动态更新了，启动服务后，我们在 Apollo 中将 log.level 的值改为 DEBUG 并发布，可在控制台看到变更后有 debug 日志输出，如下图所示：

![](https://cdn.jsdelivr.net/gh/onee-io/onee-resource/picgo/20210528163329.png)

#### 建议

对于非必需的日志，如接口请求出入参等，可将日志级别改为 debug，平时 INFO 级别下不会输出，有问题时改为 DEBUG 级别进行排查，可有效减少日志体积。
