Skip to content

Capability to disable structured logging #45407

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
commonquail opened this issue May 9, 2025 · 2 comments
Open

Capability to disable structured logging #45407

commonquail opened this issue May 9, 2025 · 2 comments
Labels
for: team-meeting An issue we'd like to discuss as a team to make progress status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged

Comments

@commonquail
Copy link

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.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label May 9, 2025
@mhalbritter
Copy link
Contributor

mhalbritter commented May 9, 2025

Hello! Doesn't setting logging.structured.format.console= work for you?

@mhalbritter mhalbritter added the status: waiting-for-feedback We need additional information before we can continue label May 9, 2025
@commonquail
Copy link
Author

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]

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels May 12, 2025
quaff added a commit to quaff/spring-boot that referenced this issue May 13, 2025
@philwebb philwebb added the for: team-meeting An issue we'd like to discuss as a team to make progress label May 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: team-meeting An issue we'd like to discuss as a team to make progress status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants