美文网首页
Spring动态修改日志级别

Spring动态修改日志级别

作者: 十毛tenmao | 来源:发表于2021-01-17 23:38 被阅读0次

    线上系统的日志级别一般使用INFO或者WARN,但是在遇到问题的时候,希望拿到更低级别的日志,方便定位问题。所以需要一种动态调整日志级别的方法。

    常用方法

    • 开启logback的自动扫描更新
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration scan="true" scanPeriod="60 seconds" debug="false">
    
    • 自定义api
      但是这种方式只能逐台服务器来更新,比较麻烦,也因为负载均衡的原因,也不容易控制
    @RequestMapping(value = "/setlevel")
    public String updateLogbackLevel(@RequestParam(value = "level") String level,
                                     @RequestParam(value = "packageName", defaultValue = "-1") String packageName) throws Exception {
        ch.qos.logback.classic.LoggerContext loggerContext = (ch.qos.logback.classic.LoggerContext) LoggerFactory.getILoggerFactory();
        Logger logger = null
        if (packageName.equals("-1")) {
            // 默认值-1,更改全局日志级别;否则按传递的包名或类名修改日志级别。
            logger = loggerContext.getLogger("root")
        } else {
            logger = loggerContext.getLogger(packageName)
        }
        logger.setLevel(ch.qos.logback.classic.Level.toLevel(level));
        return logger.getLevel();
    }
    
    • Spring Boot引入Actuator
      修改日志级别 通过 http://localhost:8080/actuator/{loggers} 端点提供的 POST 请求,修改包路径com.xxx.aa的日志级别为DEBUG:
      发送POST 请求到 http://localhost:8080/actuator/loggers/com.xxx.aa,其中请求 Body 的内容如下:
    {
        "configuredLevel": "DEBUG"
    }
    
    • 集成Spring Cloud Admin来动态修改配置
      如果使用Spring Cloud Admin作为配置中心的话,这种方式是最推荐的,但是在实际项目中,Spring Cloud Admin用的比较少

    配置中心实时下发(推荐)

    很多开源的配置中心都支持@Value配置的实时更新,比如百度disconf,携程Apollo。使用配置中心可以让所有的服务器同步更新日志级别。

    @Slf4j
    @Configuration
    public class TenmaoConfiguration {
        public static final Gson GSON = new Gson();
    
        private static final Type LOGGER_LEVEL_TYPE = new TypeToken<List<LoggerLevel>>() {
        }.getType();
    
        @Value("${logback.levels}")
        public void updateLogbackLevel(String levels) throws Exception {
            log.info("logback.levels: {}", levels);
            List<LoggerLevel> logbackLevels = GSON.fromJson(levels, LOGGER_LEVEL_TYPE);
            if (CollectionUtils.isEmpty(logbackLevels)) {
                return;
            }
            logbackLevels.forEach(LoggerLevel::checkAndConvert);
            ch.qos.logback.classic.LoggerContext loggerContext = (ch.qos.logback.classic.LoggerContext) LoggerFactory.getILoggerFactory();
            for (LoggerLevel entry : logbackLevels) {
                Logger logger = loggerContext.getLogger(entry.getLoggerName());
                logger.setLevel(entry.getLevel());
            }
        }
    
        @Data
        private static class LoggerLevel {
            private String loggerName;
            private String levelName;
            private Level level;
    
            public void checkAndConvert() {
                if (!Strings.isNullOrEmpty(levelName)) {
                    level = Level.valueOf(levelName);
                } else {
                    level = null;
                }
            }
        }
    }
    
    • 配置内容示例(json格式的字符串)
    [
      {
        "loggerName": "root",
        "levelName": "INFO"
      },{
          "loggerName": "com.tenmao.mvc.controller",
          "levelName": "DEBUG"
      }
    ]
    

    参考

    相关文章

      网友评论

          本文标题:Spring动态修改日志级别

          本文链接:https://www.haomeiwen.com/subject/whqtzktx.html