Logback 和 Spring Boot 的新 springProperty 查找机制不起作用

Logback and Spring Boot's new springProperty lookup mechanism not working

我正在使用 Spring 通过 spring-cloud Brixton.M2​​ 引导 1.3.0.RC1,但无法将 spring 引导属性拉入 logback.xml正如此功能所暗示的那样签入 Support springProperty in logback configurations

我正在使用 .yml 文件并想从 bootstrap.yml 或 application.yml.

中提取应用程序名称

logback-spring.xml:

<configuration>
      <springProperty scope="context" name="myappName" source="spring.application.name"/>
      <contextName>${myappName}</contextName>
      <appender name="logFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
         <file>logs/${myappName}.log</file>
         ... 
      </appender>
      ...
</configuration>

此处的文档 Spring Boot Logback extensions 帮助不大。

另一个 Whosebug 问题 比较老,对我也不起作用。任何见解都会有所帮助。

根据请求,这里是正在使用的相关依赖树

[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:1.3.0.RC1:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:1.3.0.RC1:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:1.3.0.RC1:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:1.3.0.RC1:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:1.3.0.RC1:compile
[INFO] |  |  |  +- ch.qos.logback:logback-classic:jar:1.1.3:compile
[INFO] |  |  |  |  \- ch.qos.logback:logback-core:jar:1.1.3:compile
[INFO] |  |  |  +- org.slf4j:jcl-over-slf4j:jar:1.7.12:compile
[INFO] |  |  |  +- org.slf4j:jul-to-slf4j:jar:1.7.12:compile
[INFO] |  |  |  \- org.slf4j:log4j-over-slf4j:jar:1.7.12:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.16:runtime

根据第二次信息请求,实际发生的是 logback 属性 myappName 没有得到值。我知道这是值变成 "myappName_IS_UNDEFINED" 并且我的日志文件被命名为 "myappName_IS_UNDEFINED.log" 并且 %contextName 被设置为 "myappName_IS_UNDEFINED".

如果我将 "spring.application.name" 放在 "application.properties" 中(而不是 "bootstrap.properties",它对我有用,因为日志系统是在 bootstrap 属性不存在的阶段初始化的但我相信可用)。我不认为 logback 会让你设置 "context" 名称,但 YMMV。

为未来的读者提供我的分析和解决方案...我尝试在 bootstrap.yml 中使用 spring.application.name 个值,然后 application.yml,然后 application.properties 但是 none 有效。我以为是因为我用了logback.xml,但是转成logback-spring.xml结果没有变化。查看提交的代码 here,通过 this.environment.getProperty(source) 提取值取决于何时加载 属性 源与何时解释 logback-spring.xml 文件。不确定为什么 Dave Syer 能够让它工作,但我的 .xml 变量是在本地 属性 源添加到环境之前填充的。

如果我通过 SpringApplication.setDefaultProperties() 设置值 ,则 填充在 .xml 文件中。因此,这就是我选择的路线。

  • 构建了一个 SpringApplicationRunListener
  • SpringApplicationRunListener.started() 中,我通过 new ClassPathResource("/bootstrap.yml")
  • 读入了 bootstrap.yml(我要求所有框架用户使用 spring.application.name)
  • 根据值
  • 在 HashMap 中设置新的 属性、service.log.name
  • 用那个 HashMap
  • 调用了 SpringApplication.setDefaultProperties()
  • 然后我可以在 logback-spring.xml 文件中使用 ${myappName}

我承认这不是一个完美的解决方案,但目前可以使用,并且很可能会在未来的 springBoot 版本中继续使用。我对进一步的想法持开放态度,但想提供一个适用于具有相同经验的其他人的解决方案。

我正在使用 Spring Boot 1.3.1,但我遇到了同样的问题。

我最后发现 属性 必须同时设置在 application.yml 和 bootstrap.yml 中。仅将其设置为一个或另一个是行不通的。仅将其作为 -D 参数传递也有效。

虽然有双重配置有点麻烦,尤其是当它也按配置文件配置时。

也许两个阶段都需要 logback 配置,属性 值不会继续。

首先,无论文件是xml还是groovy格式,你的logback配置文件名都要带-spring后缀。

在 spring 中,首选配置中心,然后是命令行参数,然后是 bootstrap.yml 中的本地属性和所有本地 属性 文件。

如果多个配置文件中有很多属性,第一个不管值是多少都会生效。

顺便说一句,请确保在 EnvironmentPrepared 事件之前没有以编程方式进行登录设置,因为登录设置将被重置。同时,如果有多个 spring 上下文,logback 设置将为每个上下文重置几次。

请检查这些规则并确保每一步都在控制之中。

对我来说,它只能使用命令行 属性,比如 --property.value=asd.

为了访问 spring 应用程序名称,您必须首先在 logback-spring.xml 中定义 spring 属性,如下所示:

<springProperty scope="context" name="MyApp" source="com.app.star"/>

因此,如果您要访问上面的源代码,那么从逻辑上讲,它必须在 application.yml 文件中定义如下:

com: app: star: HelloWorld

# Logging Configurations logging: config: "classpath:logback-spring.xml"


现在在 logback-spring.xml 中,appName 将被设置为 'HelloWorld',您可以使用 {MyApp} 访问它。

希望以上解释对您有所帮助。

我只在 bootstrap.properties 更新后它对我有用。 application.properties 中的更新不起作用,也不需要。

kafka.host.name=xxxxx
kafka.host.port=9092

在Logback.xml

<springProperty scope="context" name="kafkaHostName" source="kafka.host.name" /> 

<springProperty scope="context" name="kafkaHostPort" source="kafka.host.port" />

  <appender name="asyncXSPKafkaAppender" class="com.github.danielwegener.logback.kafka.KafkaAppender">
        <encoder class="com.github.danielwegener.logback.kafka.encoding.LayoutKafkaMessageEncoder">
            <layout class="ch.qos.logback.classic.PatternLayout">
                <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </layout>
        </encoder>
        <topic>logstash_logs</topic>
        <keyingStrategy class="com.github.danielwegener.logback.kafka.keying.RoundRobinKeyingStrategy" />
        <deliveryStrategy class="com.github.danielwegener.logback.kafka.delivery.AsynchronousDeliveryStrategy" />
        <producerConfig>bootstrap.servers=**${kafkaHostName}:${kafkaHostPort}**</producerConfig>
        <producerConfig>retries=2</producerConfig>
    </appender>

我们的解决方案是将 logback(-spring).xml 重命名为例如logback-delayed.xml 这样它就不会在 Spring Cloud Config 之前被读取,然后稍后从 Cloud Config 存储库中的配置文件中显式激活它,例如:

logging:
    config: classpath:logback-delayed.xml
    prop-to-fill-in-logback-delayed.xml: whatever

在logback中声明变量-delayed.xml

<springProperty scope="context" name="localName" source="prop-to-fill-in-logback-delayed.xml"/>

在logback中使用变量-delayed.xml

<file>${localName}.log</file>

您只需将其添加到您的 logback 文件中即可:

<property resource="application.properties" />

我有同样的问题,通过将我需要的属性从 application.properties 移动到 bootstrap.properties

解决了这个问题