在日常项目开发中,排查问题,通常第一步是根据日志定位问题,故而,我们总是会在关键节点,尽可能多的输出日志,但是一旦系统上线,大量的日志输出,明显会影响系统的性能。
通常,我们知道可以调整日志级别,在线上用更高的日志级别(info warn error),但是变更日志级别,总是需要重新发版,如果能动态调整日志级别,并实时生效,这不失为一个不错的办法。
由此,springboot的 LoggingSystem 可以解决这个问题。具体用法如下:
@Autowired
private LoggingSystem loggingSystem;
@GetMapping("test1")
public String test(String logLevel){
LogLevel lv = LogLevel.DEBUG;
if (logLevel.equalsIgnoreCase("debug")){
lv = LogLevel.DEBUG;
}else if (logLevel.equalsIgnoreCase("info")){
lv = LogLevel.INFO;
}
loggingSystem.setLogLevel("ROOT", lv);
log.debug("test=====");
}
注入LoggingSystem, 并根据动态参数设置日志级别即可
loggingSystem.setLogLevel("ROOT", lv);
其中,logName默认为ROOT, 表示所有的log 通用这一规则,当然,如果在你的项目中,对log实例有定义,也可以传入自己定义的logName。
如果结合apollo ,动态配置日志级别的话,可以如下设置
@Component
@Slf4j
public class ApolloConfigListener {
@Resource
private RefreshScope refreshScope;
@Autowired
private LoggingSystem loggingSystem;
/**
* 监听apollo配置变化
*
* @param changeEvent 变化事件
*/
@ApolloConfigChangeListener(value = {ConfigConsts.NAMESPACE_APPLICATION})
public void onChange(ConfigChangeEvent changeEvent) {
for (String changedKey : changeEvent.changedKeys()) {
log.info("apollo changed namespace:{} Key:{} value:{}", changeEvent.getNamespace(), changedKey, changeEvent.getChange(changedKey));
if (changedKey.equalsIgnoreCase("log.level")){
setLogLevel(null,changeEvent.getChange(changedKey).toString());
}
}
refreshScope.refreshAll();
}
private void setLogLevel(String logName,String logLevel){
logLevel = StringUtils.isEmpty(logLevel) ? "info":logLevel;
LogLevel lv = LogLevel.INFO;
if (logLevel.equalsIgnoreCase("debug")){
lv = LogLevel.DEBUG;
}else if (logLevel.equalsIgnoreCase("info")){
lv = LogLevel.INFO;
}else if (logName.equalsIgnoreCase("warn")) {
lv = LogLevel.WARN;
}else if (logName.equalsIgnoreCase("error")){
lv = LogLevel.ERROR;
}
logName = StringUtils.isEmpty(logName) ? "ROOT":logName;
loggingSystem.setLogLevel(logName, lv);
}
}