我有一个使用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不知道在哪里找到它。通过在我的外部application.properties文件中保留与Spring相关的属性,将与日志相关的属性移动到application-internal.properties文件(位于内部 jar中),并将Logback指向那个文件(<property resource="application-internal.properties" />
)让一切按预期工作!
答案 0 :(得分:50)
从Spring Boot 1.3开始,您可以更好地将spring属性添加到logback-spring.xml配置中:
现在你可以添加一个&#34; springProperty&#34;元件。
<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
.........
答案 1 :(得分:32)
${...}
不是&#34; Spring EL&#34;在春天;他们是财产占位符。
我认为你混淆了logback&#34;变量&#34;与Spring&#34;房产占位符&#34;。
他们碰巧使用相同的语法${...}
。
logback对Spring属性占位符机制一无所知,反之亦然。您需要根据logback文档配置您的logback变量,而不是application.properties
/ application.yml
,这是严格的Spring(启动)概念。
修改强>
快速查看logback文档后,添加
<property resource="application.properties" />
到logback.xml
应该有用。
答案 2 :(得分:8)
如上所述,您可以使用<springProperty>
元素访问spring引导属性...但需要记住的是,logback配置文件必须命名为logback-spring.xml
,它不会&#39 ;如果您将文件命名为logback.xml
(我使用spring-boot 1.3.5.RELEASE
),则无效
答案 3 :(得分:1)
上述解决方案主要适用于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。
答案 4 :(得分:0)
有一种方法可以将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>