log4j2匹配規則

1. level規則

logj42會先匹配是否符合Logger/Root的level,如果符合的話,再一一匹配Logger/Root下的AppenderRef的level是否匹配。

<Configuration status="DEBUG" updateCheck="false">
    <Appenders>
        <Console name="Console1" target="SYSTEM_OUT">
            <PatternLayout pattern="[%d] [%t] [%c\:%L] [%p] [%X{RequestID}] %m%n" charset="UTF-8"/>
            <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
        </Console>
        <Console name="Console2" target="SYSTEM_OUT">
            <PatternLayout pattern="[%d] [%t] [%c\:%L] [%p] [%X{RequestID}] %m%n" charset="UTF-8"/>
            <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="DEBUG">
            <AppenderRef ref="Console1" />
            <AppenderRef ref="Console2"/>
        </Root>
    </Loggers>
</Configuration>

log4j2會先匹配日誌級別是否符合Root的level級別,如果是,則一一匹配是否符合Console1Console2的level級別。
以上配置,logger.debug只會在Console1裏打印出來,logger.info則會Console1Console2兩個都打印出來。

2. additivity

log4j2會優先查找最優匹配的name,然後將日誌一級級往上拋,每一個name匹配的Logger/Root都會再打印一次日誌。

<Loggers>
    <Logger name="com.test" level="DEBUG">
        <AppenderRef ref="Console1"/>
    </Logger>
    <Logger name="org" level="DEBUG">
        <AppenderRef ref="Console1"/>
    </Logger>
    <Logger name="com" level="DEBUG">
        <AppenderRef ref="Console1"/>
    </Logger>
    <Root level="DEBUG">
        <AppenderRef ref="Console1"/>
    </Root>
</Loggers>

以上配置,如果在com.test包下調用logger.debug,會打印三次,因爲log4j2優先匹配到com.test,然後往上拋再匹配到com,繼續往上拋又匹配到Root,所以打印了三次。
可以通過配置additivity="false"阻止上拋,additivity默認爲true

<Loggers>
    <Logger name="org.test" level="DEBUG">
        <AppenderRef ref="Console1"/>
    </Logger>
    <Logger name="my.test" level="DEBUG">
        <AppenderRef ref="Console1"/>
    </Logger>
    <Logger name="com.test" level="DEBUG" additivity="false">
        <AppenderRef ref="Console1"/>
    </Logger>
    <Logger name="org" level="DEBUG" additivity="false">
        <AppenderRef ref="Console1"/>
    </Logger>
    <Logger name="my" level="DEBUG">
        <AppenderRef ref="Console1"/>
    </Logger>
    <Logger name="com" level="DEBUG">
        <AppenderRef ref="Console1"/>
    </Logger>
    <Root level="DEBUG">
        <AppenderRef ref="Console1"/>
    </Root>
</Loggers>

以上配置,如果在com.test包下調用logger.debug,只會打印一次;如果在org.test包下調用logger.debug,會打印兩次;如果在my.test包下調用logger.debug,會打印三次。

3. 繼承

Logger如果沒有配置AppenderRef,會默認繼承“有配置AppenderRef”的上一級的配置。

<Loggers>
    <Logger name="com.test" level="ERROR"/>
    <Root level="DEBUG">
        <AppenderRef ref="Console1"/>
    </Root>
</Loggers>

以上配置,最終的效果是,com.test包下level級別爲ERROR,其他包的級別爲DEBUG,但是隻會打印一次日誌,類似於 :

<Loggers>
    <Root if(name="com.test") { level="ERROR" } else { level="DEBUG" }>
        <AppenderRef ref="Console1"/>
    </Root>
</Loggers>

注:log4j2沒有if-else這種寫法,這裏只是表達最終的效果類似是這樣的。

<Loggers>
    <Logger name="com.test.test2" level="INFO"/>
    <Logger name="com.test" level="INFO"/>
    <Logger name="com" level="INFO" additivity="false">
        <AppenderRef ref="Console1"/>
    </Logger>
    <Root level="DEBUG">
        <AppenderRef ref="Console1"/>
        <AppenderRef ref="Console2"/>
    </Root>
</Loggers>

以上配置,com.test.test2包下打印日誌,最終會繼承name爲com的Logger的配置,因爲com是“有配置AppenderRef”中最優匹配com.test.test2的Logger。

4. 繼承+additivity

<Loggers>
    <Logger name="com.test" level="INFO"/>
    <Logger name="org.test" level="INFO"/>
    <Logger name="com" level="INFO">
        <AppenderRef ref="Console1"/>
    </Logger>
    <Logger name="org" level="INFO" additivity="false">
        <AppenderRef ref="Console1"/>
    </Logger>
    <Root level="DEBUG">
        <AppenderRef ref="Console1"/>
    </Root>
</Loggers>

以上配置,com.test包下打印日誌,會打印兩次,因爲com.test繼承了comLogger打印了一次,然後com上拋到Root又打印了一次;org.test包下打印日誌,只會打印一次,因爲org.test繼承了orgLogger打印了一次,而org上配置了additivity="false"

發佈了119 篇原創文章 · 獲贊 21 · 訪問量 101萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章