Logback logger记录两次

时间:2014-06-12 09:20:35

标签: java slf4j logback

我想在我的应用程序中使用slf4j + logback用于两个目的 - 日志和审计。

对于日志记录,我以正常方式登录:

static final Logger logger = LoggerFactory.getLogger(Main.class);
logger.debug("-> main()");

对于Audit,我创建了一个特殊的命名记录器并记录到它:

static final Logger logger = LoggerFactory.getLogger("AUDIT_LOGGER");
Object[] params =
    { new Integer(1) /* TenantID */, new Integer(10) /* UserID */, msg};
logger.info("{}|{}|{}", params);

logback配置:

<logger name="AUDIT_LOGGER" level="info">
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS}|%msg%n
            </pattern>
        </encoder>
    </appender>
</logger>

<root level="all">
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>
</root>

问题: 通过审计记录器记录的消息出现两次 - 一次在AUDIT_LOGGER下,一次在根记录器下。

  

14:41:57.975 [main] DEBUG com.gammay.example.Main - - &gt; main()的

     

14:41:57.978 | 1 | 10 |欢迎来到主

     

14:41:57.978 [主要] INFO AUDIT_LOGGER - 1 | 10 |欢迎来到主

如何确保审核记录仅在审核记录器下出现一次?

3 个答案:

答案 0 :(得分:4)

更改审核记录器定义,如下所示。注意记录器定义中的additivity="false"标志。

<logger name="AUDIT_LOGGER" level="info" additivity="false">
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS}|%msg%n
            </pattern>
        </encoder>
    </appender>
</logger>

这样可以避免在root logger中再次记录此内容。阅读logback配置文档以获取更多信息。

答案 1 :(得分:0)

我遇到了同样的问题,但是我认为正确的解决方案与通过additivity提出的解决方案不同。所附图表试图直观显示不会导致重复日志的两种方法:

  1. 还为每个<logger>添加一个appender-ref并禁用可加性。这就是图中“无可加性”下显示的内容。结果是每个记录器都将日志直接传递到附加程序,而不将它们传递到ROOT记录器。

  2. 您指定了<logger>及其日志级别,但对appender-refs记录器以外的所有记录器都省略了ROOT,并保持了可添加性。这显示在“具有加性”下。结果是将来自com.foo记录器的匹配日志传​​递到ROOT记录器,并使用在那里指定的appender-refs请注意,此时,ROOT记录器的日志级别过滤不再适用。这意味着即使com.foo的日志级别为INFO,并且ROOT记录器指定了ERROR,该日志仍然显示,因为它已经被com.foo匹配

Visualization of the data flow from logger to appender in the two scenarios described above

答案 2 :(得分:0)

解决方案:

  1. 按照上面的答案之一所述,将additivity="false"添加到"AUDIT_LOGGER"中,以不继承root记录器的附加程序。

  2. appender中删除"AUDIT_LOGGER"元素。这将导致"AUDIT_LOGGER"root记录器继承附加程序。

  3. 请小心包括其他配置文件,这也可能导致重复记录。就我而言,我必须删除base.xml include块,该块定义了根记录器和附加器。

<include resource="org/springframework/boot/logging/logback/base.xml">

注意:我建议在记录器之外定义附加器,并通过appender-ref元素对其进行引用。这样,您可以让多个记录器引用同一个附加程序。请参阅登录文档。

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
  <encoder>
    <pattern>%d{HH:mm:ss.SSS}|%msg%n</pattern>
  </encoder>
</appender>

<logger name="AUDIT_LOGGER" level="info" additivity="false">
  <appender-ref ref="STDOUT" />
</logger>