Backend Development 33 min read

Spring Boot Log4j2 Integration and Logger Level Hot Update

This article explains how Spring Boot integrates Log4j2, details the internal logging initialization process, describes logger and LoggerConfig relationships, and demonstrates how to hot‑update logger levels using LoggersEndpoint or custom endpoints without restarting the application.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Spring Boot Log4j2 Integration and Logger Level Hot Update

Logging is a familiar yet often overlooked component in Java development. While developers frequently print logs, the underlying mechanisms of frameworks like Log4j2 and Logback are rarely examined. Understanding how Spring Boot integrates Log4j2 can help extend logging functionality and even improve system throughput by adjusting logging strategies.

1. Simple Working Principle of Log4j2 – In Log4j2, the Logger object is a thin wrapper whose core is a LoggerConfig . The LoggerConfig determines which Appender s are used and the logger’s level. Configurations are defined in log4j2.xml , which is parsed into a Configuration object.

2. Spring Boot Logging Configuration – Spring Boot provides several properties to control logging:

logging:
  file:
    name: test.log
logging:
  file:
    path: /
logging:
  level:
    com.pww.App: warn

These properties map to system properties used by Log4j2, allowing developers to specify log file locations and logger levels without an explicit log4j2.xml .

3. Spring Boot Logging Startup Mechanism – The LoggingApplicationListener listens to three events:

ApplicationStartingEvent : loads the LoggingSystem class and calls beforeInitialize() to add a filter that blocks all logging before initialization.

ApplicationEnvironmentPreparedEvent : converts logging properties to system properties, creates logger groups, determines early logging levels, and finally calls initializeSystem() to start the logging framework.

ApplicationPreparedEvent : registers the initialized LoggingSystem , LogFile , and LoggerGroups as beans in the Spring context.

During initializeSystem() , Spring Boot checks the logging.config property. If absent, it searches for standard Log4j2 configuration files (e.g., log4j2.xml , log4j2-spring.xml ) on the classpath. If none are found, Spring Boot falls back to its bundled configuration files ( log4j2.xml or log4j2-file.xml ) located alongside the LoggingSystem implementation.

4. Loading Configuration – The core method in Log4J2LoggingSystem is:

protected void loadConfiguration(String location, LogFile logFile, List<String> overrides) { ... }

It loads the primary configuration and any additional files specified via logging.log4j2.config.override , merges them into a CompositeConfiguration if necessary, and starts the LoggerContext with the resulting configuration.

5. Logger Groups – Spring Boot defines LoggerGroup s (e.g., web , sql ) to manage multiple loggers together. Configuration examples:

logging:
  group:
    login:
      - com.lee.controller.LoginController
      - com.lee.service.LoginService
      - com.lee.dao.LoginDao
    common:
      - com.lee.util
      - com.lee.config

Groups can be assigned levels via logging.level , affecting all member loggers simultaneously.

6. Hot Updating Logger Levels – Changing logging.level normally requires an application restart. Spring Boot’s LoggersEndpoint (part of spring-boot-actuator ) enables runtime level changes via HTTP:

POST /actuator/loggers/{loggerName}
{ "configuredLevel": "DEBUG" }

The endpoint first attempts to locate a LoggerGroup ; if found, it updates each member logger’s level. Otherwise, it calls LoggingSystem.setLogLevel() for the individual logger.

Under the hood, Log4J2LoggingSystem.setLogLevel() converts Spring’s LogLevel to Log4j2’s Level , retrieves the corresponding LoggerConfig , and either updates its level or creates a new LevelSetLoggerConfig (a subclass of LoggerConfig ) when the logger does not yet exist. After modification, LoggerContext.updateLoggers() forces all loggers to re‑bind to the updated configuration.

7. Custom Hot‑Update Endpoint – To avoid pulling in the entire actuator dependency, a lightweight controller can directly use LoggingSystem :

@RestController
public class HotModificationLevel {
    private final LoggingSystem loggingSystem;
    public HotModificationLevel(LoggingSystem loggingSystem) { this.loggingSystem = loggingSystem; }
    @PostMapping("/logger/level")
    public void setLoggerLevel(@RequestBody SetLoggerLevelParam param) {
        loggingSystem.setLogLevel(param.getLoggerName(), param.getLoggerLevel());
    }
    public static class SetLoggerLevelParam {
        private String loggerName;
        private LogLevel loggerLevel;
        // getters and setters omitted
    }
}

This controller provides the same hot‑update capability without requiring the actuator module.

Conclusion – Spring Boot abstracts logging initialization through LoggingApplicationListener and LoggingSystem , allowing flexible configuration via convention, explicit logging.config , or built‑in defaults. Logger groups simplify bulk level management, and hot‑updating logger levels is straightforward using the actuator’s LoggersEndpoint or a custom endpoint that leverages LoggingSystem . Understanding the relationship between Logger , LoggerConfig , and LoggerContext is key to effectively controlling Log4j2 behavior in a Spring Boot application.

backendloggingSpring Bootlog4j2Hot UpdateLogger Level
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login 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.