【问题标题】:Unable to use Spring Property Placeholders in logback.xml无法在 logback.xml 中使用 Spring 属性占位符
【发布时间】:2015-06-02 01:57:04
【问题描述】:

我有一个使用 Logback 的 Spring Boot 控制台应用程序。所有属性(对于应用程序以及 Logback)都被外部化到类路径中的标准 application.properties 文件中。这些属性在应用程序本身中可以很好地获取,但不会在 logback.xml 文件中获取。看起来好像在 Spring Boot 启动之前处理了 logback.xml,因此不处理 EL 占位符。

以 FileNamePattern 为例,在 application.properties 中,我有这样的内容:

log.filePattern=/%d{yyyy/MM-MMMM/dd-EEEE}

在 logback.xml 中,我会有这个:

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <FileNamePattern>${log.logDirectory}${log.filePattern}.log
    </FileNamePattern>
</rollingPolicy>

运行应用时,我会看到如下错误:

ERROR in ch.qos.logback.core.joran.spi.Interpreter@24:25 - 
RuntimeException in Action for tag [rollingPolicy]
java.lang.IllegalStateException: FileNamePattern
[log.logDirectory_IS_UNDEFINEDlog.filePattern_IS_UNDEFINED.log]
does not contain a valid DateToken

类似的代码在其他 Spring(不是 Spring Boot)应用程序中也能正常工作,所以我很好奇 Spring Boot 的行为是否有点不同。

解决方案:

感谢@Gary 的回复!很高兴知道 Spring EL 和 Logback 的变量之间的区别……我以为是 Spring 负责为我解析这些变量。我确实拥有该元素,但这让我开始思考。

我的 application.properties 文件在 jar 之外,所以 Logback 不知道在哪里可以找到它。通过将与 Spring 相关的属性保存在我的外部 application.properties 文件中,将与日志记录相关的属性移动到 application-internal.properties 文件(位于 inside jar 中),并将 Logback 指向 文件 (&lt;property resource="application-internal.properties" /&gt;) 让一切都按预期工作!

【问题讨论】:

    标签: java spring spring-boot logback


    【解决方案1】:

    从 Spring Boot 1.3 开始,您有一种更好的方式将 spring 属性添加到 logback-spring.xml 配置中:

    现在您可以添加一个“springProperty”元素。

    <springProperty name="destination" source="my.loggger.extradest"/>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>${destination}</file>
            ...
        </file>
    </appender>
    

    https://github.com/spring-projects/spring-boot/commit/055ace37f006120b0006956b03c7f358d5f3729f

    编辑:感谢安德斯

    …………

    【讨论】:

    • 有没有对应的 logback-spring.groovy ^^?
    • 这东西的 DOC 在哪里?
    • @MatthewPayne 你有没有找到如何在 groovy 中做到这一点
    • 这不是一个万无一失的解决方案。如果您通过包含外部文件将 logback-spring.xml 文件外部化,然后将 sya, "maxSize" 从 100MB 更改为 2KB,您将看到文件被创建为 destination_IS_UNDEFINED.log。那是因为正如@Gary Russell 在他的回答中所解释的那样。
    【解决方案2】:

    ${...} 不是 Spring 中的“Spring EL”;它们是属性占位符。

    我认为您将 logback“变量”与 Spring“属性占位符”混淆了。

    他们只是碰巧使用了相同的语法${...}

    logback 对 Spring 属性占位符机制一无所知,反之亦然。您需要根据 logback 文档配置您的 logback 变量,而不是 application.properties / application.yml 这严格来说是一个 Spring(引导)概念。

    编辑:

    快速查看 logback 文档后,添加

    <property resource="application.properties" />
    

    logback.xml 应该可以工作。

    【讨论】:

    • 这里是“logback docs”的链接:logback.qos.ch/manual/configuration.html#variableSubstitution
    • @Gary 我想要可配置的文件模式扩展名。这可能吗?或者我想用外部 logback.xml 覆盖内部 logback.xml。这可能吗?
    • 对于外部文件(不在类路径中,但在文件系统中可用):
    • 感谢您丢失的巫毒(财产资源的东西)。仅供参考:“application.yml”也可以工作......正如我在这里记录的那样:stackoverflow.com/questions/33186668/…
    【解决方案3】:

    如上所述,您可以使用 &lt;springProperty&gt; 元素访问 spring boot 属性...但要记住的是 logback 配置文件必须命名为 logback-spring.xml,如果您命名它不起作用文件logback.xml(我正在使用spring-boot 1.3.5.RELEASE

    【讨论】:

    • 使用logback-dev.xmllogback-prod.xmlspring-boot 1.3.3.RELEASE 为我工作
    • 如果仍然无法正常工作,请检查应用配置名称,它应该是 application.properties,或者您为应用指定的任何名称。在这种情况下,额外的@PropertySource-es 似乎不起作用
    • 还有一件事要记住:至少对我来说,直到我将 application.properties 重命名为 bootstrap.properties 后它才起作用
    【解决方案4】:

    上述解决方案主要适用于bootrap.properties。但是,在我目前发现的 logback 配置中使用远程 Spring Config Server 属性的唯一方法是以编程方式应用它们:

    @Component
    public class LoggerConfiguration implements ApplicationListener<EnvironmentChangeEvent> {
    
        @Autowired protected Environment environment;
    
        @Override
        public void onApplicationEvent(EnvironmentChangeEvent event) {
            // enviroment here has already loaded all properties and you may alter logback config programatically
            ch.qos.logback.classic.Logger rootLogger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
        }
    
    
    }
    

    Here 是一个很好的例子,如何通过这种方式使用新的 appender 自定义 logback。

    【讨论】:

      【解决方案5】:

      有一种方法可以将 Spring 属性映射到 Logback 属性并在条件中使用它们:

      logback-spring.xml
      
      <?xml version="1.0" encoding="UTF-8"?>
      <configuration>
      <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
      <springProperty scope="context" name="ACTIVE_PROFILE" source="spring.profiles.active"/>
      <!--   defined in the application-prod.properties/>-->
      <springProperty scope="context" name="SPRING_WRITER_DISABLED" source="writer.disabled"/>
      <property name="LOGBACK_WRITER_DISABLED" value="${SPRING_WRITER_DISABLED}"/>
      
      <if condition='property("LOGBACK_WRITER_DISABLED").equals("false")'>
          <then>
              <appender name="testappender" class="ch.qos.logback.core.rolling.RollingFileAppender">
                  <file>${ACTIVE_PROFILE}/${HOSTNAME}/testappender.log</file>
                  <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                      <fileNamePattern>
                          {ACTIVE_PROFILE}/${HOSTNAME}/testappender-%d{yyyy-MM-dd}.%i.log
                      </fileNamePattern>
                      <maxFileSize>300MB</maxFileSize>
                      <maxHistory>3</maxHistory>
                      <totalSizeCap>1GB</totalSizeCap>
                  </rollingPolicy>
                  <encoder>
                      <pattern>%msg%n</pattern>
                  </encoder>
              </appender>
              <logger name="testappender" level="INFO" additivity="false">
                  <appender-ref ref="testappender"/>
              </logger>
          </then>
      </if>
      </configuration>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-07-16
        • 2018-06-15
        • 2011-09-22
        • 1970-01-01
        • 2019-04-15
        • 1970-01-01
        • 2013-05-05
        相关资源
        最近更新 更多