在使用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>