logback.xml
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
application.yml
logging:
level:
root: WARN
org.springframework: INFO
com.my.app(自己应用的包路径): DEBUG
当 logback.xml 和 application.yml 共同对日志级别做配置时,application.yml的logging 优先级大于 logback.xml 中的 。
application.yml logging 日志级别更加细粒度,比如 debug 模式,我们有时发现非常恐惧,因为有大量的 spring debug 日志输出,很容易使自己的 debug 日志被淹没在茫茫人海中,但是如果将正常的日志输出(为了方便筛选,抓眼球)设置成 error 或 warn 的话,就又显得不是特别规范,所以利用 logging 的特性,可以只对自己的包下设置成 debug 级别,spring 设置成 info 级别,这样一来就可以两全其美 。
将logging.level.com.my.app=DEBUG
配置到 apollo,可以实现由apollo配置来控制日志打印级别,但是这种方式的配置更改生效需要重启项目。创建以下bean可实现不重启项目的情况下通过apollo配置真正动态更改日志级别
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* 自动刷新apollo配置
*/
@Slf4j
@Component
public class LogLevelChanged {
private final static String PREFIX = "logging.level.";
@ApolloConfigChangeListener(value = {"app"})
public void onChange(ConfigChangeEvent changeEvent) {
log.info("================Apollo refresh start ===========================");
Map<String, String> logMap = new HashMap<>();
for (String changeKey : changeEvent.changedKeys()) {
changeKey = changeKey.trim();
ConfigChange configChange = changeEvent.getChange(changeKey);
String oldValue = configChange.getOldValue();
String newValue = configChange.getNewValue();
if (changeKey.startsWith(PREFIX)) {
logMap.put(changeKey.substring(PREFIX.length()), newValue);
} else {
continue;
}
log.info("changedKey:{},oldValue={}, newValue:{}", changeKey, oldValue, newValue);
}
changeLogLevel(logMap);
log.info("================Apollo refresh end ===========================");
}
private void changeLogLevel(Map<String, String> logMap) {
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
for (String key : logMap.keySet()) {
Logger logbackLogger = loggerContext.getLogger(key);
logbackLogger.setLevel(Level.toLevel(logMap.get(key)));
}
}
}
参考文章: