-
Notifications
You must be signed in to change notification settings - Fork 41.5k
Description
Use case:
Application on certain environments should write logs into the file. In order to turn this on/off we provide property in application.yml configuration which tells for which spring profile it is allowed or not allowed (like '!prod' for example).
The logback-spring.xml configuration for such case looks as follows:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/> <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<springProperty scope="context" name="allowed-profiles" source="logback.allowed-profiles"/> <springProfile name="${allowed-profiles}">
<appender name="ROLLING-FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
</appender>
</springProfile>
<root>
<appender-ref ref="CONSOLE"/>
<springProfile name="${allowed-profiles}">
<appender-ref ref="ROLLING-FILE"/>
</springProfile>
</root></configuration>
In the Spring-Boot version 1.5.x it doesn't work. From the source code (org.springframework.boot.logging.logback.SpringProfileAction) there is a piece of logic which isn't applied:
private boolean acceptsProfiles(InterpretationContext ic, Attributes attributes) {
String[] profileNames = StringUtils.trimArrayElements(StringUtils .commaDelimitedListToStringArray(attributes.getValue(NAME_ATTRIBUTE)));
if (profileNames.length != 0) {
for (String profileName : profileNames) {
OptionHelper.substVars(profileName, ic, this.context);
}
return this.environment != null &&
this.environment.acceptsProfiles(profileNames);
}
return false;
}
Here OptionHelper.substVars(profileName, ic, this.context)
should return substituted value from the properties or from environment variables. But it isn't assigned to anything and in the next check where environment accepts profiles it still passes expression but not actual value.
The change like that could fix it:
String[] profiles = new String[profileNames.length];
for (int i = 0; i < profileNames.length; i++) {
profiles[i] = OptionHelper.substVars(profileNames[i], ic, this.context);
}
return this.environment != null &&
this.environment.acceptsProfiles(profiles);