无法在logback.xml中使用Spring属性占位符

n6lpvg4x  于 2023-04-04  发布在  Spring
关注(0)|答案(5)|浏览(204)

我有一个使用Logback的Sping Boot 控制台应用程序。所有属性(用于应用程序以及Logback)都被外部化到classpath中的标准application.properties文件中。这些属性在应用程序本身中被很好地拾取,但在logback.xml文件中没有拾取。看起来好像logback.xml在Spring Boot启动之前被处理,因此EL占位符没有被处理。
使用FileNamePattern作为示例,在www.example.com中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(不是Sping Boot )应用程序中也能正常工作,所以我很好奇Spring Boot的行为是否有点不同。

溶液:

谢谢你的回复@加里!很高兴知道Spring EL和Logback的变量之间的区别......我以为是Spring负责为我解析这些变量。我确实有元素,但这让我思考。
我的application.properties文件在jar之外,所以Logback不知道在哪里可以找到它。通过将我的Spring相关属性保存在我的外部application.properties文件中,将与日志相关的属性移动到application-internal.properties文件(位于内部jar)中,并将Logback指向那个文件(<property resource="application-internal.properties" />),一切都按预期工作!

xtupzzrd

xtupzzrd1#

从Sping Boot 1.3开始,你有了一个更好的方法来将spring属性添加到logback-spring.xml配置中:
现在你可以添加一个“springProperty”元素。
属性 name 引用logback属性,属性 source 引用spring属性

<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
编辑:感谢Anders
.........

bjg7j2ky

bjg7j2ky2#

${...}不是Spring中的“Spring EL”;它们是属性占位符。
我认为你混淆了logback“变量”和Spring“属性占位符”。
它们只是碰巧使用相同的语法${...}
logback对Spring属性占位符机制一无所知,反之亦然。您需要根据logback文档配置logback变量,而不是application.properties/application.yml,这是严格的Spring( Boot )概念。

编辑:

在快速查看logback文档之后,添加

<property resource="application.properties" />

logback.xml应该可以用。

dvtswwa3

dvtswwa33#

如上所述,您可以使用<springProperty>元素访问spring Boot 属性......但需要记住的是,logback配置文件必须命名为logback-spring.xml,如果您将文件命名为logback.xml(我使用spring-boot 1.3.5.RELEASE),则不起作用。

6ss1mwsb

6ss1mwsb4#

上面的解决方案主要适用于bootrap.properties。然而,我目前发现的在logback config中使用远程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。

cs7cruho

cs7cruho5#

有一种方法可以将Spring属性Map到Logback属性,并在Conditions中使用它们:

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>

相关问题