Logback中使用TurboFilter實現日誌級別等內容的動態修改

可能看到這個標題,讀者會問:要修改日誌的級別,不是直接修改log.xxx就行了嗎?爲什麼要搞那麼複雜呢?因此,先說一下場景,爲何要經過TurboFilter去動態的修改日誌級別。咱們在使用Java開發各類項目的時候必然的會引入不少框架,這些框架經過堆疊的方式完成所要提供的業務服務(一個服務請求在進入後會在這些框架中兜一圈,而後返回結果),當一個比較底層的框架在處理過程當中拋出了異常以後,這個異常會不斷的向上傳遞。這個時候,有的框架直接throw,繼續向上拋,而有的在throw以前還會本身打印一下error日誌,這就致使了當出現異常的時候,每每會出現一連串相似的錯誤日誌記錄。若是對接了錯誤日誌告警,就會出現重複告警的現象。爲了解決相似這樣的問題,修改源碼從新編譯最直接,可是不可取。因此但願能夠有更好的手段去控制這些已經被編碼固化的日誌打印信息。當咱們使用Logback的時候,TurboFilter就是解決該問題的工具之一。html

TurboFIlter不一樣於以前在[《Logback中如何自定義靈活的日誌過濾規則》]一文中介紹的那些經過ch.qos.logback.core.filter.Filter接口實現的過濾器。ch.qos.logback.core.filter.Filter實現的過濾器是與Appender綁定的,而TurboFIlter是與日誌上下文綁定的,它會過濾全部的日誌請求,而且TurboFIlter的方法中提供了豐富的可訪問信息用來進行控制和改寫。java

好比下面的實現,經過繼承ch.qos.logback.classic.turbo.TurboFilter類,並重寫decide方法,將org.springframework.cloud.sleuth.instrument.web.ExceptionLoggingFilter類中本來要打印的ERROR日誌DENY掉(過濾掉),同時以WARN級別打印一封相同的內容,這樣就實現了對已定義日誌的動態修改。web

public class ForceWarnFilter extends TurboFilter {

    @Override
    public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable throwable) {
        if (level == Level.ERROR && logger.getName().equals("org.springframework.cloud.sleuth.instrument.web.ExceptionLoggingFilter")) {
            logger.warn(marker, format, params);
            return FilterReply.DENY;
        }
        return FilterReply.NEUTRAL;
    }

}
複製代碼

爲了讓上面定義的過濾器生效,須要在logback的配置xml中增長以下配置:spring

<configuration>
    <turboFilter class="com.didispace.log.filter.ForceWarnFilter" />

    ......
</configuration>
複製代碼

或者也能夠在應用主類中增長:框架

LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
lc.addTurboFilter(new MyTurboFilter());
複製代碼

更多關於Logback過濾器的內容可參考官方文檔:logback.qos.ch/manual/filt…ide

相關文章
相關標籤/搜索