聊聊logback的DynamicThresholdFilter

2023-11-14 12:45:09 浏览数 (2)

本文主要研究一下logback的DynamicThresholdFilter

DynamicThresholdFilter

代码语言:javascript复制
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

addMDCValueLevelPair

代码语言:javascript复制
    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添加配置

MDCValueLevelPair

ch/qos/logback/classic/turbo/MDCValueLevelPair.java

代码语言:javascript复制
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属性

decide

代码语言:javascript复制
    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

示例

代码语言:javascript复制
<?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级别的效果。

0 人点赞