log4j2中LevelRangeFilter的注意點
阿新 • • 發佈:2018-12-22
LevelRangeFilter的注意點
在log4j2中,LevelRangeFilter的minLevel,maxLevel的配置是和log4j 1.x相反的;minLevel需要配置的是高級別,maxLevel配置的是低級別,如下:
<LevelRangeFilter minLevel="fatal" maxLevel="info" onMatch="ACCEPT" onMismatch="DENY"/>
如上邊的配置,是列印info到fatal級別的log,如果配置反過來,則不會輸出任何log。
如果不配置minLevel、maxLevel、onMatch和onMismatch的值,則會為其設定預設值,在LevelRangeFilter中的原始碼實現如下:
@PluginFactory public static LevelRangeFilter createFilter( // @formatter:off @PluginAttribute("minLevel") final Level minLevel, @PluginAttribute("maxLevel") final Level maxLevel, @PluginAttribute("onMatch") final Result match, @PluginAttribute("onMismatch") final Result mismatch) { // @formatter:on final Level actualMinLevel = minLevel == null ? Level.ERROR : minLevel; final Level actualMaxLevel = maxLevel == null ? Level.ERROR : maxLevel; final Result onMatch = match == null ? Result.NEUTRAL : match; final Result onMismatch = mismatch == null ? Result.DENY : mismatch; return new LevelRangeFilter(actualMinLevel, actualMaxLevel, onMatch, onMismatch); }
至於為什麼把最大最小level的值配置反了就會無法輸出,是因為在LevelRangeFilter中的原始碼實現如下:
private Result filter(final Level level) {
return level.isInRange(this.minLevel, this.maxLevel) ? onMatch : onMismatch;
}
可以看到,在呼叫filter方法進行過濾時,是呼叫了level#isInRange()
來判斷是否匹配該filter的。而在該方法中,實現如下:
public boolean isInRange(final Level minLevel, final Level maxLevel) { return this.intLevel >= minLevel.intLevel && this.intLevel <= maxLevel.intLevel; }
這裡通過對比Level物件的intLevel值(int)來判斷是否匹配,而這些Level物件也在Level這個類裡進行裡實例化:
static {
OFF = new Level("OFF", StandardLevel.OFF.intLevel());
FATAL = new Level("FATAL", StandardLevel.FATAL.intLevel());
ERROR = new Level("ERROR", StandardLevel.ERROR.intLevel());
WARN = new Level("WARN", StandardLevel.WARN.intLevel());
INFO = new Level("INFO", StandardLevel.INFO.intLevel());
DEBUG = new Level("DEBUG", StandardLevel.DEBUG.intLevel());
TRACE = new Level("TRACE", StandardLevel.TRACE.intLevel());
ALL = new Level("ALL", StandardLevel.ALL.intLevel());
}
可以看到,這些Level物件的intLevel值是由另一個列舉類StandardLevel
來提供的:
/**
* No events will be logged.
*/
OFF(0),
/**
* A severe error that will prevent the application from continuing.
*/
FATAL(100),
/**
* An error in the application, possibly recoverable.
*/
ERROR(200),
/**
* An event that might possible lead to an error.
*/
WARN(300),
/**
* An event for informational purposes.
*/
INFO(400),
/**
* A general debugging event.
*/
DEBUG(500),
/**
* A fine-grained debug message, typically capturing the flow through the application.
*/
TRACE(600),
/**
* All events should be logged.
*/
ALL(Integer.MAX_VALUE);
可以看到,Level級別越高,其對應的intLevel值越小,可以這樣理解:級別越高,能打印出來的日誌資訊就越少,所以其intLevel值就越小。
如果我們把LevelRangeFilter的minLevel、maxLevel配置反了,會導致level#isInRange()
返回false,最終也就沒有任何日誌得以輸出了。