在使用log4j2的時候,通常都須要不一樣的日誌分類打印不一樣的日誌等級,以下面的配置app
<!-- 用於指定log4j自動從新配置的監測間隔時間,單位是秒 --> <configuration debug="off" monitorInterval="10"> <Properties> <Property name="log-path">server_logs</Property> </Properties> <Appenders> <Console name="console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %t-%T %-5level %class{36} - %msg%xEx%n" /> </Console> </Appenders> <Loggers> <logger name = "com.mygame" level="debug"> <appender-ref ref="console" /> </logger> <root level="error"> <appender-ref ref="console" /> </root> </Loggers> </configuration>
這個配置的目標是,沒有指定logger的時候,日誌輸出使用root,而root的級別是error,但願com.mygame包下面的日誌輸出debug級別。可是這樣運行以後,發現日誌輸出了兩遍,我是在從消息隊列中接收消息以後打印的日誌,害得我覺得一個消息被處理了兩次。spa
這種狀況是log4j2的機制問題,在Log4j2中,logger是有繼承關係的,root是根節點,而上面配置中添加的logger就是root的子節點,在log4j2中,有個additivity的屬性,它是子Logger 是否繼承 父Logger 的 輸出源(appender) 的標誌位。具體說,默認狀況下子Logger會繼承父Logger的appender,也就是說子Logger會在父Logger的appender裏輸出。如果additivity設爲false,則子Logger只會在本身的appender裏輸出,而不會在父Logger的appender裏輸出。因爲上面的配置com.mygame的logger和root都輸出到console中了,因此會顯示輸出了兩條日誌。debug
要打破這種傳遞性,也很是簡單,在logger中添加 additivity = "false",以下所示:日誌
<Loggers> <logger name = "com.mygame" level="debug" additivity = "false"> <appender-ref ref="console" /> </logger> <root level="error"> <appender-ref ref="console" /> </root> </Loggers>