【问题标题】:Logback logger logging twiceLogback 记录器记录两次
【发布时间】:2014-08-02 13:32:25
【问题描述】:

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

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

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

为了审计,我创建了一个特殊的命名记录器并记录到它:

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] 调试 com.gammay.example.Main - -> main()

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

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

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

【问题讨论】:

  • 关闭审计记录器的可加性。
  • @RaviH 对不起,你能解释一下吗?您的意思是删除审计记录器的附加程序吗?

标签: java slf4j logback


【解决方案1】:

如下所示更改审计记录器定义。请注意记录器定义中的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>

这将避免在根记录器中再次记录此内容。阅读 logback 配置文档了解更多信息。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,但我认为正确的解决方案与这里通过additivity 提出的不同。附图试图可视化两种不会导致重复日志的方法:

    1. 对于每个&lt;logger&gt;,您还添加一个&lt;appender&gt; 并禁用可加性。这就是“无加性”下的图表中显示的内容。结果是每个单独的记录器将日志直接传递给附加程序,而将它们传递给ROOT 记录器。

    2. 您指定&lt;logger&gt;s 和它们的日志级别,但对于除ROOT 记录器之外的所有记录器都省略appender-refs,并保持additivty on。这显示在“有加性”下。结果是来自com.foo 记录器的匹配日志被传递到ROOT 记录器并使用在那里指定的&lt;appender&gt;请注意,此时ROOT 记录器的日志级别过滤不再适用。这意味着即使com.foo 的日志级别为INFO 并且ROOT 记录器指定ERROR,日志仍然会显示,因为它已经被com.foo 匹配。

    【讨论】:

      【解决方案3】:

      解决方案:

      1. additivity="false" 添加到"AUDIT_LOGGER",如上述答案之一所述,不要从root logger 继承appender。

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

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

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

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

      <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>
      
      
      

      【讨论】:

        猜你喜欢
        • 2016-04-28
        • 1970-01-01
        • 1970-01-01
        • 2020-08-07
        • 1970-01-01
        • 2023-03-27
        • 1970-01-01
        • 1970-01-01
        • 2017-01-21
        相关资源
        最近更新 更多