How Does Spring Boot Load Its Logging System?

This article explains Spring Boot's logging architecture, the early initialization process driven by LoggingApplicationListener, the three‑layer design with SLF4J, bridge packages and Logback, configuration file loading order, differences between logback.xml and logback‑spring.xml, and common troubleshooting steps.

Java Tech Workshop
Java Tech Workshop
Java Tech Workshop
How Does Spring Boot Load Its Logging System?

Overview

Java developers use logging daily, but many only know the superficial steps of adding a starter, writing logback.xml, and using @Slf4j. The real reason many configurations fail is a lack of understanding of Spring Boot's logging loading mechanism.

Three‑Layer Architecture

1. SLF4J Facade

All application code and Spring itself depend on the SLF4J API. Calls such as LoggerFactory.getLogger() or Lombok's @Slf4j are independent of the underlying implementation.

2. Bridge Redirection

Spring Boot includes three bridge jars— jcl-over-slf4j, log4j-over-slf4j and jul-to-slf4j —that redirect calls from Commons Logging, Log4j 1.x and java.util.logging to SLF4J. The bridge classes have the same method signatures as the original frameworks and forward the calls to SLF4J, making the redirection transparent.

Principle: the bridge packages replace the original framework at load time, keeping upper‑level code unchanged.

3. Default Implementation (Logback)

Spring Boot pulls in spring-boot-starter-logging, which brings in Logback as the default implementation. Logback is performant, feature‑rich and natively supports SLF4J. To switch to Log4j2, exclude Logback and add spring-boot-starter-log4j2 —no code changes are required.

All dependencies' logs converge to a single file because they are funneled through the bridge layer to SLF4J, then to the chosen implementation.

Early Initialization – Before the Spring Container

The common misconception is that logging starts after the ApplicationContext is created. In fact, the logging system is one of the earliest components initialized, well before the container.

Reason: Spring itself emits a large amount of startup logs (environment, bean definitions, etc.). If logging were delayed until after the container, those early logs would be lost.

Driving Mechanism: LoggingApplicationListener

This listener is registered via spring.factories with a priority of Ordered.HIGHEST_PRECEDENCE + 20. It reacts to three key events:

ApplicationStartingEvent : early pre‑initialization before the environment is ready.

ApplicationEnvironmentPreparedEvent : full logging initialization after the environment is prepared.

ApplicationPreparedEvent : binding the logging system to the Spring container after bean definitions are loaded.

This staged design ensures that basic logging is available during startup, and Spring‑specific configuration is applied later.

Step‑by‑Step Loading Process (default Logback)

Step 1 – Application Run & Listener Registration

SpringApplication.run()

reads spring.factories, loads all ApplicationListener s, including LoggingApplicationListener, and publishes ApplicationStartingEvent to trigger the first phase.

Step 2 – Detect Implementation & Create LoggingSystem

The static method LoggingSystem.get(classLoader) uses a hard‑coded map to check the classpath for known logging factories in priority order (Logback → Log4j2 → JUL). The first match determines the concrete LoggingSystem implementation.

// Simplified LoggingSystem map
private static final Map<String, String> SYSTEMS;
static {
    Map<String, String> systems = new LinkedHashMap<>();
    systems.put("ch.qos.logback.classic.LoggerContext", "org.springframework.boot.logging.logback.LogbackLoggingSystem");
    systems.put("org.apache.logging.log4j.core.impl.Log4jContextFactory", "org.springframework.boot.logging.log4j2.Log4J2LoggingSystem");
    systems.put("java.util.logging.LogManager", "org.springframework.boot.logging.java.JavaLoggingSystem");
    SYSTEMS = Collections.unmodifiableMap(systems);
}

This explains why adding Logback to the classpath automatically activates it.

Step 3 – Environment Ready, Apply System Properties

When ApplicationEnvironmentPreparedEvent fires, LoggingSystemProperties.apply() writes Spring environment values to system properties such as logging.file.name, logging.pattern.console, and ${PID}. These properties can be referenced in configuration files via ${LOG_FILE}, etc.

Step 4 – Load Configuration Files

The LoggingSystem searches for configuration files in a defined order and stops at the first match. For Logback the order is: logging.config (explicitly set via YAML or command line) logback-spring.xml (Spring‑extended, recommended)

logback-spring.groovy
logback.xml

(native Logback) logback.groovy Spring Boot’s default configuration (fallback console output)

Difference between logback.xml and logback-spring.xml : logback.xml is loaded by Logback itself very early, before Spring’s environment is ready, so it cannot read application.yml values or Spring tags like <springProfile>. logback-spring.xml is loaded by LogbackLoggingSystem after the environment is prepared, fully supporting Spring placeholders, profiles and other extensions.

Key tip: never keep both files in the same project; use logback-spring.xml when you need Spring properties.

Step 5 – Apply Log Levels and Groups

After the configuration file is loaded, Spring applies logging.level.* and logging.group entries from application.yml to the logging system. This explains why a level defined in logback.xml can be overridden by the same logger defined in application.yml —the YAML configuration is applied later and has higher precedence.

Step 6 – Register Shutdown Hook & Bind to Container

Register a JVM shutdown hook to gracefully flush buffers and avoid log loss.

Register the LoggingSystem instance as a Spring bean, enabling runtime log‑level changes via Actuator.

At this point the logging system is fully initialized for the entire application lifecycle.

Configuration Priority Checklist

Command‑line arguments (e.g., -Dlogging.level.root=debug) – highest.

application.yml
logging.*

entries – applied after environment preparation. logging.config – explicit file path, overrides convention files. logback-spring.xml – Spring‑aware configuration, recommended. logback.xml – native Logback, loads early, limited features.

Spring Boot’s default configuration – fallback.

Common Troubleshooting Scenarios

Log level in YAML not taking effect : check whether logback.xml hard‑codes the level or contains typos.

Spring placeholders unresolved : likely using logback.xml; switch to logback-spring.xml.

Profile‑specific logging not working : again, logback.xml does not support <springProfile> tags.

ClassCastException or logging dead‑loop : both a real logging implementation and its bridge are present (e.g., log4j + log4j-over-slf4j). Keep only one side.

Switching to Log4j2 fails : exclude spring-boot-starter-logging, add spring-boot-starter-log4j2, and use log4j2-spring.xml. Do not keep Logback on the classpath.

Production logs disappear : a syntax error in the Logback file causes a WARN and fallback to default console output. Look for “Failed to configure” warnings.

Design Philosophy Summary

Abstraction : LoggingSystem hides concrete implementations, allowing seamless swaps.

Phased Initialization : early logging for startup visibility, later environment‑aware configuration.

Bridge Compatibility : unified handling of the fragmented Java logging ecosystem.

Extensibility : configuration files, runtime adjustments, and Actuator endpoints are all supported.

Spring Boot does not invent a new logging framework; it merely orchestrates existing ones with a clean architecture, making logging almost invisible to developers while providing powerful customization when needed.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaconfigurationloggingSpring Bootlogbackslf4jlog4j2
Java Tech Workshop
Written by

Java Tech Workshop

Focused on Java backend technologies, sharing fundamentals, multithreading, JVM, the Spring ecosystem, microservices, distributed systems, high concurrency, source‑code analysis, and practical experience. Continuously delivers high‑quality original content, interview guides, and learning roadmaps to help Java developers progress from beginner to advanced, enhancing technical skills and core competitiveness.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.