Logback 记录器记录两次

gam*_*may 6 java logback slf4j

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

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

static final Logger logger = LoggerFactory.getLogger(Main.class);
logger.debug("-> main()");
Run Code Online (Sandbox Code Playgroud)

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

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

登录配置:

<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>
Run Code Online (Sandbox Code Playgroud)

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

14:41:57.975 [main] 调试 com.gammay.example.Main - -> main()

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

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

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

Rav*_*viH 11

更改审计记录器定义,如下所示。注意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>
Run Code Online (Sandbox Code Playgroud)

这将避免在根记录器中再次记录。阅读 logback 配置文档以获取更多信息。


fre*_*oma 8

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

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

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

上述两种场景中从记录器到附加器的数据流的可视化