如何将活动的Spring配置文件注入到Logback中

12

我正在使用一个Spring Boot项目。

环境:

ch.qos.logback:logback-core:jar:1.1.5
ch.qos.logback:logback-classic:jar:1.1.5
org.springframework.boot:spring-boot-starter-logging:jar:1.3.3.RELEASE

在我的项目中,我正在使用带有application.yml(application-dev.yml和application-production.yml)的属性。

由于Logback Spring扩展程序在Spring之前启动,因此我无法将spring.profiles.active注入到logback.xml文件中。

这是我的logback.xml文件的简化版本:

<configuration scan="true">

   <property name="LOG_PATH" value="/var/log/" />
   <property name="APP_NAME" value="xyz" />
   <property name="PROFILE" value="-${spring.profiles.active}" />
   <property name="CHARSET" value="utf-8" />
   <property name="PATTERN" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />

   <appender name="APP-FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <file>${LOG_PATH}${APP_NAME}${PROFILE}.log</file>
      <encoder>
         <charset>${CHARSET}</charset>
         <Pattern>${PATTERN}</Pattern>
      </encoder>
   </appender>

   <logger name="a.b.c" level="INFO">
      <appender-ref ref="APP-FILE" />
   </logger>

   <root level="INFO">
      <appender-ref ref="APP-FILE"/>
   </root>

我要找的配置项是 spring.profiles.active

我的目标是在目录/var/log中有一个日志文件,它要么是xyz-dev,要么是xyz-production,但是实际上我得到的是xyz-spring.profiles.active_IS_UNDEFINED.log

方案:

1 - 使用组件如下:

@Component
public class InitializationService implements ApplicationListener<ContextRefreshedEvent> {

// inject spring profile active into logback.xml

}

当然不起作用,因为logback Spring扩展在Spring Boot应用程序之前启动。

2- 在logback.xml文件中使用类似这样的属性

<file>${LOG_PATH}${APP_NAME}${PROFILE}.log</file>

结果是 xyz-spring.profiles.active_IS_UNDEFINED.log


如果PROFILE是具有键值对的活动配置文件的属性,则它应该正常工作。 - davidxxx
我要查找的PROFILE是在application.yml或通过命令行定义的属性spring.profiles.active - Leonel
3个回答

23
这个回答可能有点晚了,但我通过将我的 "logback.xml" 文件重命名为 "logback-spring.xml" 成功记录了Spring配置文件,并像这个简化版本一样访问了配置文件中的profile。
<springProperty scope="context" name="ACTIVE_PROFILE" source="spring.profiles.active"/>

<appender name="GRAYLOG" class="com.github.pukkaone.gelf.logback.GelfAppender">

    <additionalField>environment=${ACTIVE_PROFILE}</additionalField>

</appender>

<root level="WARN">
    <appender-ref ref="GRAYLOG" />
</root>

看起来"logback-spring.xml"可以获取配置文件信息。

具体的文档在这里


它对我来说完美地工作了,但我不需要重命名我的logback.xml文件。谢谢!! - abanet

5
  • 由于您正在使用Spring Boot,您可以定义logging.file=blah.log。请参见官方文档
  • 或者您可以使用vanilla Logback并传递系统变量:-DLOG_FILE=blah.log

为什么您不应该使用配置文件:

您尝试做的不是Spring配置文件创建的目的。它们需要在启动期间开启/关闭bean以激活/取消激活行为。在一般情况下,不建议使用配置文件,因为测试和生产环境中的内容不同(尽管有时没有其他选择)。请参见原始公告中的注意事项部分。

您使用配置文件的另一个问题是可以同时激活多个配置文件。配置文件是用于启用/禁用小的不相关部分。例如:spring.profiles.active=cache-off,perf-monitoring-on或类似的内容。

尽管如此,您仍然可以定义一个配置文件并在该配置文件中设置logging.file=prod.log属性。这仍然是非常不好的,也不应该使用配置文件的方式,但这是更好的。


“Profiles is not recommended practice in general since what you test and what works in production is different” 的意思是通常不建议使用配置文件,因为测试和生产环境中的实际情况不同。 在你引用的注意事项部分,我没有这样的理解。它更多地是说:“在两个配置文件之间注册的bean集应该更相似而不是不同。” 我同意这一点。 通常,Web应用程序必须通过多个环境(开发、集成等)移动,每个环境都有特定的要求(操作系统、URL、数据库等),忽略这些是一个不好的做法。 - davidxxx
@davidhxxx,URL、数据库等不应该在配置文件中定义。这些需要作为系统变量、环境变量、JNDI或应用程序特定的配置文件来定义。同时,请不要只看文章中的一部分,它还说:“如果有更简单的方法可以完成工作,请不要使用配置文件”。 - Stanislav Bashkyrtsev
我不会仅从文章中摘取一部分。如果有更简单的方法可以完成工作,就不要使用配置文件。这并不意味着URL、数据库信息等不应该在配置文件中。此外,你说这些信息可以在特定于应用程序的配置文件中。 但是,在Spring Boot中,配置文件也可以与特定于应用程序的配置文件一起使用,当服务器启动或通过属性注释在运行时检索时可以加载。配置文件不仅限于Java代码。 - davidxxx
抱歉,我指的是“外部”的应用程序特定配置文件。如果您想要一个全面的答案,解释为什么使用配置文件来配置应用程序是一个不好的选择,您可以提出一个问题。我无法在评论中提供详细的解释。 - Stanislav Bashkyrtsev

3
这是我在项目中所做的。在你的logback.xml文件中。
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>

<property resource="application.properties"/>

您可以使用在您的application.properties文件中定义的属性。${MY-PROPERTY} 在我的application.properties中,我有一个记录文件名的属性。

这不适用于application.yml => YAML属性文件,因为yaml文件是在logback初始化之后解释的。


在我的项目中,我正在使用带有application.yml(application-dev.yml和application-production.yml)的属性...那么你有其他方法吗? - Leonel
不好意思,我尝试了一下,似乎是行不通的。也许可以切换回属性文件,但是要注意如果有特殊字符的话(属性文件不支持 utf-8)。https://dev59.com/54nda4cB1Zd3GeqPDb5r - David G.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接