本文主要研究一下logback的DynamicThresholdFilter
public class DynamicThresholdFilter extends TurboFilter {
private Map valueLevelMap = new HashMap();
private Level defaultThreshold = Level.ERROR;
private String key;
private FilterReply onHigherOrEqual = FilterReply.NEUTRAL;
private FilterReply onLower = FilterReply.DENY;
//......
}
DynamicThresholdFilter继承了TurboFilter,它定义了valueLevelMap、defaultThreshold为ERROR,onHigherOrEqual为NEUTRAL,onLower为DENY
public void addMDCValueLevelPair(MDCValueLevelPair mdcValueLevelPair) {
if (valueLevelMap.containsKey(mdcValueLevelPair.getValue())) {
addError(mdcValueLevelPair.getValue() + " has been already set");
} else {
valueLevelMap.put(mdcValueLevelPair.getValue(), mdcValueLevelPair.getLevel());
}
}
addMDCValueLevelPair方法可以根据MDCValueLevelPair往valueLevelMap添加配置
ch/qos/logback/classic/turbo/MDCValueLevelPair.java
public class MDCValueLevelPair {
private String value;
private Level level;
public String getValue() {
return value;
}
public void setValue(String name) {
this.value = name;
}
public Level getLevel() {
return level;
}
public void setLevel(Level level) {
this.level = level;
}
}
MDCValueLevelPair定义了value及level属性
public FilterReply decide(Marker marker, Logger logger, Level level, String s, Object[] objects,
Throwable throwable) {
String mdcValue = MDC.get(this.key);
if (!isStarted()) {
return FilterReply.NEUTRAL;
}
Level levelAssociatedWithMDCValue = null;
if (mdcValue != null) {
levelAssociatedWithMDCValue = valueLevelMap.get(mdcValue);
}
if (levelAssociatedWithMDCValue == null) {
levelAssociatedWithMDCValue = defaultThreshold;
}
if (level.isGreaterOrEqual(levelAssociatedWithMDCValue)) {
return onHigherOrEqual;
} else {
return onLower;
}
}
decide方法先从mdc获取key对应的mdcValue,然后根据mdcValue去valueLevelMap获取对应的level,如果获取不到则取defaultThreshold;如果要打印的level大于等于levelAssociatedWithMDCValue则返回NEUTRAL,否则返回DENY
userId
ERROR
user1
INFO
user2
TRACE
logback提供了DynamicThresholdFilter,它可以根据配置的key从MDC取值,再根据配置的MDCValueLevelPair去映射对应的level,达到动态log级别的效果。