合并 Spring 引导和 Logback 的日志记录配置

Merge logging config of Spring boot and Logback

我遇到以下情况:一个 spring 启动应用程序使用 logback 和几个已在 application.yml

中配置的日志记录属性

我想添加其他配置选项,这些选项只能通过 logback.xml 文件使用,但是一旦我将此文件添加到类路径(不管它是命名为 logback.xml 还是 logback-spring.xml) 它覆盖了 application.yml 中的所有内容,并且所有日志记录 levels/patterns 和那里定义的其他选项停止生效 - 似乎在添加 logback.xml 之后 appication.yml 中的所有选项都是忽略了,我需要在 xml 文件而不是 yml 中重新添加它们。

我的问题是:是否可以合并这两个配置?我的意思是我只需要向 logback.xml 添加一个选项,我不想强​​制每个其他开发人员都应该学习 logback.xml 语法,同时他们已经熟悉 application.yml 配置日志记录的方法。

更新1

我想做的一件事是启用 logback JMX 访问,因此我创建了一个包含以下内容的 logback-spring.xml 文件:

<configuration debug="true">
   <jmxConfigurator />
</configuration>

在我引入这个文件后,即使我在 application.yml 文件中有 logging.level.root: info,我也会丢失所有来自 webapp 的日志记录。

我还想继续使用 application.yml 中定义的根日志记录级别和模式。我还想配置几个特定于 logback 的 turboFilters,据我所知,只能通过 logback 配置文件来定义。

更新 2

@devatherock 和@Ashish Patil asnwers 都帮助我解决了这个问题,我已经意识到可以通过 springPropertylogback.xml 中包含 spring 配置元素,但我有不认为它是一个可行的解决方案,因为我将不得不以这种方式重写多个元素,从而使 logback.xml 更难阅读。

但是正如@devatherock 提到的——默认情况下配置文件 ARE 合并是因为 logback 需要在其配置中存在 appender 和 root logger。即使存在于 logback.xml 文件中,根记录器级别仍将被 application.yml 设置覆盖(这是需要的)但 pattern 属性 不会,我们必须使用springProperty 为此。

所以虽然这两个答案都有帮助,但实际上@devatherock 的标志对我更有帮助,我被包括在内接受他的回答。

我创建了一个示例项目 spring-boot-logback,它在 logback.xmlapplication.yml

中指定了日志记录配置

root 日志级别在 logback.xml 中设置为 WARN,如下所示:

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

    <root level="WARN">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

有一个控制器方法可以处理 /hello,带有 DEBUGINFO 日志行。控制器 class 的日志级别在 application.yml 文件中设置为 DEBUG,如下所示:

logging:
  level:
    io.github.devatherock.demo.controller: DEBUG

我启动了应用程序并点击了 /hello 控制器端点。以下是我看到的日志行:

  .   ____          _            __ _ _
 /\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.6.7)

08:41:45.051 [http-nio-8080-exec-1] DEBUG i.g.d.d.controller.HelloController - Debug log in sayHello method
08:41:45.052 [http-nio-8080-exec-1] INFO  i.g.d.d.controller.HelloController - Info log in sayHello method

None 的应用程序启动日志存在,因为根日志级别在 logback.xml 中设置为 WARN。来自控制器的调试和信息日志行都存在,因为控制器日志级别已在 application.yml 中设置为 DEBUG。因此我们可以确认来自 logback.xml 和 application.yml 的日志记录配置被应用没有任何问题

更新 1:

看起来如果指定了 logback.xml,它至少需要有附加程序、编码器和附加程序到根日志级别的附件,以便使用 spring 覆盖日志配置引导的 logging.* 属性起作用。一旦我用 jmxConfigurator 指定了这样一个 logback.xml 文件,我就能够在 application.yml 中调整根目录和控制器日志级别。下面是新的 logback.xmlapplication.yml 文件:

logback.xml 与 jmxConfigurator:

<configuration>
    <jmxConfigurator />
    <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 level="INFO">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

application.yml root 日志级别:

logging:
  level:
    root: WARN
    io.github.devatherock.demo.controller: DEBUG

使用 springProperty 可能适合您的要求。

假设,您有 application.yml 如下所示:

logging:
  level:
    root: DEBUG
...  // other configs

现在你想要在 logback.xml 之后强制执行 application.yml 的配置,那么你可以在你的 logback.xml:

中添加 springProperty
<configuration>
    <jmxConfigurator />
    <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>
    <springProperty scope="context" name="loggerProperty" source="logging.level.root"/>
    
    <root level="${loggerProperty}">
        <appender-ref ref="STDOUT" />
    </root>
    ... //other configurations.
</configuration>

现在,当您启动 spring-boot 时,您可以看到 application.yml 的配置值正在被读取而不是覆盖。

因此,通过这种方式,您可以在 logbackapplication.yml.

中配置尽可能多的属性

基本上,您是从您的 logback 引用 Environment 属性(在您的 application.properties / application.yml 中定义)。

此处 logging.level.root 是环境 属性,它定义为 application.yml 并且您在 logback.xml 中通过给它命名 loggerProperty 来引用它。然后,您将在您的 logback 中使用此 loggerProperty,以便使用它而不是 logback 的默认值。