业务背景

有时候不同环境需要的日志级别不同,比如测试环境我们可能希望 DEBUG 级别,便于问题的定位。

那么问题来了,如何动态的修改日志级别?

思路

(1)手动修改:本地测试改为 debug,生产时改回来。

这个缺点比较明显,不够方便。

(2)不同的 profile

类似于 springboot 的 profile,指定不同环境的配置。

这个其实也有一定的要求,比如有些配置放在配置中心就比较麻烦。

(3)动态修改

可以提供一个接口,根据需要动态修改。

比如查问题时,将指定的类设置为 DEBUG,问题定位改成可以改回去。

当然这个灵活的特性也可以通过 Arthas 等工具实现,不过本文核心内容在于实现一个简单的修改方式。

方案1:动态接口

  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@RestController public class LogController { private static Logger logger = LoggerFactory.getLogger(LogController.class); @RequestMapping(value = "logLevel/{logLevel}") public String changeLogLevel(@PathVariable("logLevel") String logLevel) { try { LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); loggerContext.getLogger("org.mybatis").setLevel(Level.valueOf(logLevel)); loggerContext.getLogger("org.springframework").setLevel(Level.valueOf(logLevel)); } catch (Exception e) { logger.error("动态修改日志级别出错", e); return "fail"; } return "success"; } }

比较推荐这种方式。

方案2:配置文件调整

修改logback.xml配置文件:在configuration根节点配置属性scan和scanPeriod,scan为true时,配置文件被修改会被重新加载,scanPeriod定义了扫描文件变化的周期,默认6000毫秒,即一分钟。

这种做法的好处是不用自己写修改日志级别的逻辑;坏处是要手动更改配置文件,排错完成后需改回原来的配置。

示例配置如下:

  [xml]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="UTF-8" ?> <configuration scan="true" scanPeriod="6000"> <property name="LOG_HOME" value="/export/logs/cmdb/" /> <property name="APP_NAME" value="cmdb" /> <property name="LOG_FILE_EXPIRE_TIME" value="180" /> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | ${APP_NAME} - %p | %thread | %c | line:%L - %m%n</pattern> </encoder> </appender> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}${APP_NAME}.%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>${LOG_FILE_EXPIRE_TIME}</maxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} | ${APP_NAME} - %p | %thread | %c | line:%L - %m%n</pattern> </encoder> </appender> <root> <level value="INFO" /> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE" /> </root> </configuration>

方案3:springboot 引入 Actuator

依赖

  [xml]
1
2
3
4
5
6
7
8
9
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>

配置文件调整

如果是 springboot1.X,

  [yml]
1
management.security.enabled=false

如果是springboot2.X,则参考如下配置

  [yml]
1
2
3
4
5
6
7
8
management: endpoint: health: show-details: "ALWAYS" endpoints: web: exposure: include: "*"

查看级别

我们可以发送 GET 请求到 http://localhost:8080/actuator/loggers 来获取支持的日志等级,以及系统(ROOT)默认的日志等和各个包路径(com.xxx.aa等)对应的日志级别。

修改日志级别

通过 http://localhost:8080/actuator/loggers 端点提供的 POST 请求,修改包路径com.xxx.aa的日志级别为DEBUG:

发送 POST 请求到 http://localhost:8080/actuator/loggers/com.xxx.aa,其中请求 Body 的内容如下:

  [json]
1
2
3
{ "configuredLevel": "DEBUG" }

再用 GET 访问 http://localhost:8080/loggers/com.xxx.aa 查看当前的日志级别:

  [json]
1
2
3
4
{ "configuredLevel": "DEBUG", "effectiveLevel": "INFO" }

方案四-集成 springcloudadmin 来动态修改配置

springcloudadmin 安装部署我就不做描述了,网上很多。

依赖

1、引入 admin 依赖

  [xml]
1
2
3
4
5
6
7
8
<dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-starter-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>

登录

登录 springcloudadmin,找到指定的服务中某一个节点

这个待验证。

拓展阅读

JVM-Arthas Java 诊断工具-33

MDC

参考资料

logback动态设置某个类的日志级别

Logback动态修改日志级别的方法