Thank you for the new integrated structured logging in Spring Boot 3.4. I have been very satisfied with its behaviour and the ergonomics of using it contrasted with having to wire that up, myself.
I would like to be able to explicitly disable it, though. I have a situation where, for safety purposes, the setting is distributed widely with
logging.structured.format.console=ecs
for correct default behaviour, but that leads to developers being unable to view plain text logs anywhere, namely during development, on account of the settings having no non-structured override option. The JSON logs are a lot more difficult to parse so that one use case has suffered considerably.
Before 3.4, we relied on a local
logging.config=
to disable a similarly distributed configuration and that worked well enough. Unfortunately there is no analogue for logging.structured.format.console
that lets us do the same.
Comment From: mhalbritter
Hello! Doesn't setting logging.structured.format.console=
work for you?
Comment From: commonquail
Ah... well, arguably, yes, but it looks to be not entirely by design. I misremembered the exact behaviour but I should have phrased this request differently.
With logging.structured.format.console=
Spring Boot 3.4.3 gives the following stack trace after which point logging proceeds in a non-structured manner (shown). However, the application does not use the usual default configuration and does not seem to respect the value of logging.config
at that point. It is also evident that the empty value, although effective, is not formally part of the API.
2025-05-12T08:47:35.030874Z main ERROR Could not create plugin of type class org.springframework.boot.logging.log4j2.StructuredLogLayout for element StructuredLogLayout: java.lang.IllegalArgumentException: Unknown format ''. Values can
be a valid fully-qualified class name or one of the common formats: [ecs, gelf, logstash] java.lang.IllegalArgumentException: Unknown format ''. Values can be a valid fully-qualified class name or one of the common formats: [ecs, gelf, logstash]
at org.springframework.boot.logging.structured.StructuredLogFormatterFactory.get(StructuredLogFormatterFactory.java:133)
at org.springframework.boot.logging.log4j2.StructuredLogLayout$Builder.build(StructuredLogLayout.java:102)
at org.springframework.boot.logging.log4j2.StructuredLogLayout$Builder.build(StructuredLogLayout.java:74)
at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:124)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:1180)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:1099)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:1091)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:1091)
at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:695)
at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:270)
at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:319)
at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:673)
at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:332)
at org.apache.logging.log4j.core.async.AsyncLoggerContext.start(AsyncLoggerContext.java:90)
at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.loadConfiguration(Log4J2LoggingSystem.java:278)
at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.load(Log4J2LoggingSystem.java:250)
at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.loadConfiguration(Log4J2LoggingSystem.java:244)
at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithSpecificConfig(AbstractLoggingSystem.java:67)
at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:58)
at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.initialize(Log4J2LoggingSystem.java:231)
at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:335)
at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:298)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:246)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:223)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138)
at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:81)
at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:64)
at java.base/java.lang.Iterable.forEach(Iterable.java:75)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:63)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:353)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:313)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350)
at example.Application.main(Application.java:10)
2025-05-12T08:47:35.032873800Z main ERROR Unable to invoke factory method in class org.springframework.boot.logging.log4j2.StructuredLogLayout for element StructuredLogLayout: java.lang.IllegalStateException: No factory method found for
class org.springframework.boot.logging.log4j2.StructuredLogLayout java.lang.IllegalStateException: No factory method found for class org.springframework.boot.logging.log4j2.StructuredLogLayout
at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.findFactoryMethod(PluginBuilder.java:268)
at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:140)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:1180)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:1099)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:1091)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:1091)
at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:695)
at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:270)
at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:319)
at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:673)
at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:332)
at org.apache.logging.log4j.core.async.AsyncLoggerContext.start(AsyncLoggerContext.java:90)
at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.loadConfiguration(Log4J2LoggingSystem.java:278)
at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.load(Log4J2LoggingSystem.java:250)
at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.loadConfiguration(Log4J2LoggingSystem.java:244)
at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithSpecificConfig(AbstractLoggingSystem.java:67)
at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:58)
at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.initialize(Log4J2LoggingSystem.java:231)
at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:335)
at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:298)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:246)
at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:223)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138)
at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:81)
at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:64)
at java.base/java.lang.Iterable.forEach(Iterable.java:75)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:63)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:353)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:313)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350)
at example.Application.main(Application.java:10)
Starting Application using Java 21.0.1 with PID 12328 (<...>\target\classes started by <...> in <...>)
No active profile set, falling back to 1 default profile: "default"
Tomcat initialized with port 8080 (http)
Starting service [Tomcat]