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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29322709/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:47:02  来源:igfitidea点击:

Unable to use Spring Property Placeholders in logback.xml

javaspringspring-bootlogback

提问by brmc72

I have a Spring Boot console app using Logback. All of the properties (for the app as well as for Logback) are externalized into a standard application.properties file in the classpath. These properties are picked up just fine in the app itself, but are not picked up in the logback.xml file. It appears as though the logback.xml is processed before Spring Boot fires up, therefore the EL placeholders are not processed.

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

Using the FileNamePattern as an example, in the application.properties, I have something like this:

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

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

and in logback.xml, I'll have this:

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

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

When running the app, I'll see errors such as:

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

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

Similar code works just fine in other Spring (not Spring Boot) apps, so I'm curious if Spring Boot just behaves a bit differently.

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

Solution:

解决方案:

Thanks for the reply @Gary! Good to know about the difference between Spring EL and Logback's variables...I had assumed it was Spring that was in charge of parsing those variables for me. I didhave the element, but that got me to thinking.

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

My application.properties file was outside of the jar, so Logback had no idea where to find it. By keeping my Spring-related properties in my external application.properties file, moving the logging-related properties into an application-internal.properties file (located insidethe jar), and pointing Logback to thatfile (<property resource="application-internal.properties" />) got everything working as expected!

我的 application.properties 文件在 jar 之外,所以 Logback 不知道在哪里可以找到它。通过保持我的春节,相关性在我的外部application.properties文件,移动测井相关性为application-internal.properties文件(位于里面的罐子),并指向的logback到文件(<property resource="application-internal.properties" />)得到的一切工作正常!

采纳答案by Gary Russell

${...}is not "Spring EL" in Spring; they are property placeholders.

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

I think you are confusing logback "variables" with Spring "Property Placeholders".

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

They just happen to use the same syntax ${...}.

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

logback knows nothing about the Spring property placeholder mechanism and vice-versa. You need to configure your logback variables according to the logback documentation and not in application.properties/ application.ymlwhich is strictly a Spring (boot) concept.

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

EDIT:

编辑:

After a quick look at the logback docs, adding

快速查看 logback 文档后,添加

<property resource="application.properties" />

to the logback.xmlshould work.

logback.xml应该工作。

回答by Lasse L

Since Spring Boot 1.3 you have a better way of getting spring properties into your logback-spring.xml configuration:

从 Spring Boot 1.3 开始,您可以更好地将 spring 属性放入 logback-spring.xml 配置中:

Now you can just add a "springProperty" element.

现在您可以添加一个“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

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

edit: thanks to Anders

编辑:感谢安德斯

.........

…………

回答by anders

As answered above you can access the spring boot properties using the <springProperty>element...but a thing to keep in mind is that the logback configuration file must be named logback-spring.xml, it doesn't work if you name the file logback.xml(I'm using spring-boot 1.3.5.RELEASE)

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

回答by Lukasz Frankowski

The solutions above work mostly for bootrap.properties. However, the only way to use properties from remote Spring Config Server in logback config I've currently found, is to apply them programatically:

上述解决方案主要适用于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);
    }


}

Hereis a good example how to customize logback with new appender this way.

是一个很好的示例,如何以这种方式使用新的 appender 自定义 logback。