Spring Boot
runtime logging
log level
application configuration
dynamic logging

How do I change log level in runtime without restarting Spring Boot application

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Changing log levels at runtime is a practical way to debug production issues without restarting services. In Spring Boot, you can do this safely through Actuator or programmatic APIs. The important part is not only changing levels, but also controlling scope, security, and rollback.

Actuator-Based Runtime Log Control

The most common method uses the Actuator loggers endpoint. First, include Actuator and expose the endpoint.

xml
1<dependency>
2  <groupId>org.springframework.boot</groupId>
3  <artifactId>spring-boot-starter-actuator</artifactId>
4</dependency>
yaml
1management:
2  endpoints:
3    web:
4      exposure:
5        include: loggers

Check current logger state:

bash
curl http://localhost:8080/actuator/loggers/com.example.service

Set logger to debug:

bash
curl -X POST http://localhost:8080/actuator/loggers/com.example.service \
  -H "Content-Type: application/json" \
  -d '{"configuredLevel":"DEBUG"}'

Reset to inherited level:

bash
curl -X POST http://localhost:8080/actuator/loggers/com.example.service \
  -H "Content-Type: application/json" \
  -d '{"configuredLevel":null}'

Changes apply immediately, no restart needed.

Programmatic Changes with LoggingSystem

If you need internal admin workflows, use LoggingSystem from application code.

java
1import org.springframework.boot.logging.LogLevel;
2import org.springframework.boot.logging.LoggingSystem;
3import org.springframework.stereotype.Service;
4
5@Service
6public class DynamicLoggingService {
7    private final LoggingSystem loggingSystem;
8
9    public DynamicLoggingService(LoggingSystem loggingSystem) {
10        this.loggingSystem = loggingSystem;
11    }
12
13    public void enableDebug(String loggerName) {
14        loggingSystem.setLogLevel(loggerName, LogLevel.DEBUG);
15    }
16
17    public void reset(String loggerName) {
18        loggingSystem.setLogLevel(loggerName, null);
19    }
20}

This is useful when the change should be triggered from an internal endpoint or admin console.

Secure the Control Path

Runtime log controls are operationally sensitive. If exposed without protection, an attacker can increase log volume and potentially leak sensitive information.

Minimum safeguards:

  • Require authentication and strict authorization.
  • Limit access to internal networks.
  • Audit who changed which logger and when.
  • Add rate limiting for repeated changes.

Spring Security example for actuator protection:

java
1@Bean
2SecurityFilterChain actuatorSecurity(HttpSecurity http) throws Exception {
3    return http
4        .securityMatcher("/actuator/**")
5        .authorizeHttpRequests(auth -> auth
6            .requestMatchers("/actuator/loggers/**").hasRole("OPS")
7            .anyRequest().authenticated())
8        .httpBasic(Customizer.withDefaults())
9        .build();
10}

Scope Changes Carefully

Do not set root logger to debug unless absolutely necessary. Prefer package-level or class-level changes.

Good:

  • 'com.example.payment'
  • 'com.example.payment.retry.RetryService'

Risky:

  • 'ROOT'

Narrow scope reduces performance impact and makes logs easier to analyze.

Multi-Instance and Cloud Behavior

In distributed deployments, changing one instance does not automatically change others. If you run many replicas, decide whether changes should be:

  • Instance-local for targeted debugging.
  • Cluster-wide through an orchestrated control plane.

If you need cluster-wide behavior, combine runtime changes with service discovery or an operations script that applies updates across instances.

Rollback and Time-Limited Debugging

Verbose logging can increase latency, storage usage, and log-ingestion cost. Define rollback policy before enabling debug.

A practical workflow:

  1. Record baseline logger level.
  2. Enable debug on narrow namespace.
  3. Collect evidence for a fixed window.
  4. Restore previous level automatically.

You can implement time-limited changes using scheduled tasks:

java
1@Scheduled(fixedDelay = 60000)
2public void enforceLoggingExpiry() {
3    // check active temporary overrides and restore expired entries
4}

Operational Verification

Keep a short runbook with known logger names for critical modules so responders do not waste time guessing package paths during incidents. After changing levels, verify effect quickly:

  • Confirm endpoint returns expected configured level.
  • Confirm new debug lines appear for target package only.
  • Monitor request latency and log throughput.

Without verification, teams often assume logging changed while the target logger name was incorrect.

Common Pitfalls

  • Exposing /actuator/loggers publicly without authorization.
  • Enabling debug at root level during peak traffic.
  • Forgetting to revert temporary logging changes.
  • Assuming one instance change affects all replicas.
  • Using incorrect logger names and collecting no useful output.

Summary

  • Spring Boot supports live log-level changes without restart.
  • Actuator loggers endpoint is the fastest operational approach.
  • 'LoggingSystem is useful for internal admin-driven control.'
  • Secure, audit, and scope logging changes carefully.
  • Always plan rollback to avoid long-running verbose logging.

Course illustration
Course illustration

All Rights Reserved.