简述
生产环境日志级别一般比较高,用作服务性能优化,但不利于问题排查,通过动态修改日志级别,可以打印出想要的日志,用完再调整回去,简单实用;
以下是单节点的动态调整例子,基于springboot3服务验证过的;
(如果想要在分布式或集群环境进行批量调整,可以通过统一的配置中心或其他方案实现)
maven坐标
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<version>3.2.2</version>
<scope>compile</scope>
</dependency>
实例代码
package com.gjw.demo.controller
import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
import ch.qos.logback.classic.LoggerContext
import com.example.demo.common.extension.log
import com.example.demo.common.result.BaseResult
import com.example.demo.common.result.R
import com.example.demo.common.result.SingleResult
import org.slf4j.LoggerFactory
import org.springframework.web.bind.annotation.*
import java.util.*
/**
* 日志级别动态跳转
*/
@RestController
@RequestMapping("/log")
class LoglevelController {
/**
* 测试日志输出级别
*/
@GetMapping("/test")
fun testLogLeve(): BaseResult {
/**
* 日志输出级别的优先级通常按照其重要性和详细程度进行排序。一般而言,
* 优先级从高到低依次为:FATAL>ERROR>WARN>INFO>DEBUG>TRACE。
* 这个顺序反映了不同级别日志信息的紧急程度和详细程度。
* 输出规则是:只有等于或高于该级别的日志信息才会被输出
*/
log.trace("------我是trace---------");
log.debug("------我是debug---------");
log.info("-------我是info----------");
log.warn("-------我是warn----------");
log.error("------我是error---------");
return R.ok("测试成功,请去控制台查看日志输出");
}
/**
* 获取当前日志输出级别
* @param packageName 包名, 默认为根
*/
@GetMapping("/now")
fun getLocalLoggerLevel(@RequestParam(required = false) packageName: String?): SingleResult<String> {
val pgName = packageName ?: Logger.ROOT_LOGGER_NAME
// 获取 LoggerContext
val loggerContext: LoggerContext = LoggerFactory.getILoggerFactory() as LoggerContext
// 获取 Logger 实例
val rootLogger: Logger = loggerContext.getLogger(pgName)
// 获取当前日志级别
val currentLevel = rootLogger.level
// 输出当前日志级别
log.debug("当前日志输出级别为:" + currentLevel.levelStr)
return R.ok("当前日志输出级别为:" + currentLevel.levelStr) {
this.data = "$pgName : ${currentLevel.levelStr}"
}
}
/**
* 更改日志输出级别
* @param level 日志级别
* @param packageName 包名, 默认为根
*/
@GetMapping("/change/{level}")
fun loggerLevelChange(
@PathVariable("level") level: String,
@RequestParam(required = false) packageName: String?
): SingleResult<String> {
val pgName = packageName ?: Logger.ROOT_LOGGER_NAME
// 获取 LoggerContext
val loggerContext = LoggerFactory.getILoggerFactory() as LoggerContext
// 获取 Logger 实例
val logger = loggerContext.getLogger(pgName)
when (level.lowercase(Locale.getDefault())) {
"debug" -> logger.level = Level.DEBUG
"info" -> logger.level = Level.INFO
"warn" -> logger.level = Level.WARN
"error" -> logger.level = Level.ERROR
else -> return R.fail("请输入正确的日志级别")
}
return R.ok("日志输出级别已切换为:$level") {
this.data = "$pgName : $level"
}
}
}