Java项目开发调试或维护过程中,为方便问题快速定位,很多时候都会在代码中增加相关日志,但为了减少日志输出量,在生产环境通常都提高了日志的级别,导致生产环境出现问题时调试信息没有打印出来,排查定位问题比较困难。
那么,能否动态修改日志的级别?答案是肯定的。当出现问题时,动态降低日志级别,输出相关的调试信息;问题解决后,动态提高日志级别,屏蔽相关的调试信息。
以下代码在 log4j 1.2.17
版本上验证通过
package controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 动态修改j日志等级
* @author chengesheng@gmail.com
* @date 2017年6月17日 上午12:13:18
* @note Log4jController
*/
@Controller
@RequestMapping("/log4j")
public class Log4jController {
@RequestMapping(value = "/root/{level}", method = RequestMethod.GET)
@ResponseBody
public String updateRootLog4jLevel(HttpServletRequest request, HttpServletResponse response, @PathVariable("level") String levelName) {
Level level = Level.toLevel(levelName);
LogManager.getRootLogger().setLevel(level);
return "修改root的log4j{" + levelName + "}级别成功";
}
@RequestMapping(value = "/{package}/{level}", method = RequestMethod.GET)
@ResponseBody
public String updateLog4jLevel(HttpServletRequest request, HttpServletResponse response, @PathVariable("package") String packageName,
@PathVariable("level") String levelName) {
Level level = Level.toLevel(levelName);
LogManager.getLogger(packageName).setLevel(level);
return "修改package{" + packageName + "}的log4j{" + levelName + "}级别成功";
}
}
以下代码在 logback 1.2.3
版本上验证通过
package controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
/**
* 动态修改logback日志级别
* @author cgs1999@126.com
* @time 2020年4月7日 下午3:29:21
* @since 1.0.0
*/
@Controller
@RequestMapping("/logback")
public class LogbackController {
@RequestMapping(value = "/root/{level}", method = RequestMethod.GET)
@ResponseBody
public String updateRootLogbackLevel(HttpServletRequest request, HttpServletResponse response, @PathVariable("level") String levelName) {
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
loggerContext.getLogger(Logger.ROOT_LOGGER_NAME).setLevel(Level.toLevel(levelName));
return "修改root的logback{" + levelName + "}级别成功";
}
@RequestMapping(value = "/{package}/{level}", method = RequestMethod.GET)
@ResponseBody
public String updateLogbackLevel(HttpServletRequest request, HttpServletResponse response, @PathVariable("package") String packageName,
@PathVariable("level") String levelName) {
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
loggerContext.getLogger(packageName).setLevel(Level.toLevel(levelName));
return "修改package{" + packageName + "}的logback{" + levelName + "}级别成功";
}
}
通过浏览器访问下面地址进行验证
## 修改log4j的root的日志级别
http://<ip>:<port>/<contextPath>/log4j/root/DEBUG
http://<ip>:<port>/<contextPath>/log4j/root/INFO
http://<ip>:<port>/<contextPath>/log4j/root/ERROR
## 修改log4j的org.apache包的日志级别
http://<ip>:<port>/<contextPath>/log4j/org.apache/DEBUG
http://<ip>:<port>/<contextPath>/log4j/org.apache/INFO
http://<ip>:<port>/<contextPath>/log4j/org.apache/ERROR
## 修改logback的root的日志级别
http://<ip>:<port>/<contextPath>/logback/root/DEBUG
http://<ip>:<port>/<contextPath>/logback/root/INFO
http://<ip>:<port>/<contextPath>/logback/root/ERROR
## 修改logback的org.apache包的日志级别
http://<ip>:<port>/<contextPath>/logback/org.apache/DEBUG
http://<ip>:<port>/<contextPath>/logback/org.apache/INFO
http://<ip>:<port>/<contextPath>/logback/org.apache/ERROR