本文主要研究一下logback的DynamicThresholdFilter
public class DynamicThresholdFilter extends TurboFilter {
private Map<String, Level> valueLevelMap = new HashMap<String, Level>();
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
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration>
<configuration>
<turboFilter class="ch.qos.logback.classic.turbo.DynamicThresholdFilter">
<Key>userId</Key>
<DefaultThreshold>ERROR</DefaultThreshold>
<MDCValueLevelPair>
<value>user1</value>
<level>INFO</level>
</MDCValueLevelPair>
<MDCValueLevelPair>
<value>user2</value>
<level>TRACE</level>
</MDCValueLevelPair>
</turboFilter>
<appender name="LIST"
class="ch.qos.logback.core.read.ListAppender">
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="LIST" />
</root>
</configuration>
logback提供了DynamicThresholdFilter,它可以根据配置的key从MDC取值,再根据配置的MDCValueLevelPair去映射对应的level,达到动态log级别的效果。