Hi Community,
I have the following spring-logback.xml configuration
<?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 name="appName" source="info.build.name"/>
<springProfile name="">
<appender name="LOGSTASH_CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<customFields>{"appName":"${appName}"}</customFields>
</encoder>
</appender>
<appender name="ASYNC_LOGSTASH_CONSOLE" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>1024</queueSize>
<discardingThreshold>0</discardingThreshold>
<appender-ref ref="LOGSTASH_CONSOLE"/>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
</appender>
</springProfile>
<springProfile name="sentry">
<springProperty name="sentryDSN" source="sentry.dsn"/>
<appender name="SENTRY" class="com.getsentry.raven.logback.SentryAppender">
<dsn>${sentryDSN}</dsn>
<minLevel>ERROR</minLevel>
<ravenFactory>com.getsentry.raven.DefaultRavenFactory</ravenFactory>
</appender>
</springProfile>
<root level="INFO">
<springProfile name="docker">
<appender-ref ref="ASYNC_LOGSTASH_CONSOLE"/>
</springProfile>
<springProfile name="!docker">
<appender-ref ref="CONSOLE"/>
</springProfile>
<springProfile name="sentry">
<appender-ref ref="SENTRY"/>
</springProfile>
</root>
</configuration>
Before upgrading to Spring Boot 3.0.0 application successfully logged to the console. However, after upgrade, it stopped doing this.
If I use this configuration
<?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 name="appName" source="info.build.name"/>
<springProfile name="">
<appender name="LOGSTASH_CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<customFields>{"appName":"${appName}"}</customFields>
</encoder>
</appender>
<appender name="ASYNC_LOGSTASH_CONSOLE" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>1024</queueSize>
<discardingThreshold>0</discardingThreshold>
<appender-ref ref="LOGSTASH_CONSOLE"/>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
</appender>
</springProfile>
<springProfile name="sentry">
<springProperty name="sentryDSN" source="sentry.dsn"/>
<appender name="SENTRY" class="com.getsentry.raven.logback.SentryAppender">
<dsn>${sentryDSN}</dsn>
<minLevel>ERROR</minLevel>
<ravenFactory>com.getsentry.raven.DefaultRavenFactory</ravenFactory>
</appender>
</springProfile>
<root level="INFO">
<springProfile name="!docker">
<appender-ref ref="CONSOLE"/>
</springProfile>
</root>
</configuration>
then the app successfully logs message to the console.
Comment From: philwebb
It's hard to say if this is a Spring Boot issue or related to the fact that Spring Boot 3.0 upgrades to Logback 1.4.x. Please could you provide a sample application as a zip file or GitHub project so that we can take a look.
Comment From: tarasmurzenkovv
@philwebb thank you for your response. I've attached archive with the project that reproduces this behavior. logging.zip
With only this
<root level="INFO">
<springProfile name="!docker">
<appender-ref ref="CONSOLE"/>
</springProfile>
</root>
it successfully prints to the console.
With this, no output is observed
<root level="INFO">
<springProfile name="docker">
<appender-ref ref="ASYNC_LOGSTASH_CONSOLE"/>
</springProfile>
<springProfile name="!docker">
<appender-ref ref="CONSOLE"/>
</springProfile>
<springProfile name="sentry">
<appender-ref ref="SENTRY"/>
</springProfile>
</root>
By saynig
related to the fact that Spring Boot 3.0 upgrades to Logback 1.4.x
could you give me the hints where it could be an issue?
Comment From: philwebb
At first I thought that this was a bug with Logback, but I think it's actually an intentional limitation.
With the upgrade to Logback 1.4 (see #12649) in Spring Boot 3.0 we needed to refactor the way that <springProfile> works so that it now uses a ModelHandler. This makes it work in a similar way to Logback's <if> tag.
If you try and create a similar configuration to yours using <if> you'll get a much better error. For example, using a logback.xml file of:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="test" value="test" />
<appender name="CONSOLE1"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>1 - %msg%n</pattern>
</encoder>
</appender>
<if condition='property("test").contains("ignore")'>
<then>
<appender name="CONSOLE2"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>2 - %msg%n</pattern>
</encoder>
</appender>
</then>
</if>
<root level="INFO">
<appender-ref ref="CONSOLE1" />
<if condition='property("test").contains("ignore")'>
<then>
<appender-ref ref="CONSOLE2" />
</then>
</if>
</root>
</configuration>
Results in
14:37:41,297 |-WARN in IfNestedWithinSecondPhaseElementSC - <if> elements cannot be nested within an <appender>, <logger> or <root> element
14:37:41,297 |-WARN in IfNestedWithinSecondPhaseElementSC - See also http://logback.qos.ch/codes.html#nested_if_element
14:37:41,303 |-WARN in IfNestedWithinSecondPhaseElementSC - Element <root> at line 20 contains a nested <if> element at line 22
You can read more about this limitation at https://logback.qos.ch/codes.html#nested_if_element
We have the same limitation, but we don't currently have a nice SanityChecker providing details.
For your application, you can follow the advice in https://logback.qos.ch/codes.html#nested_if_element and change your config to use:
<springProfile name="docker">
<root level="INFO">
<appender-ref ref="ASYNC_LOGSTASH_CONSOLE" />
</root>
</springProfile>
<springProfile name="!docker">
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</springProfile>
<springProfile name="sentry">
<root level="INFO">
<appender-ref ref="SENTRY" />
</root>
</springProfile>
Comment From: philwebb
I'll leave this open to see if we can add a similar SanityChecker.
Comment From: tarasmurzenkovv
Thank you for the support =)