Dynamic Logback Log Level in Spring Boot
There are times where we want to create a dynamic configuration for our logging level. Lets say for most of cases, logger with level INFO is sufficient enough, but we want a much more detail logger such as DEBUG or TRACE for debugging purpose.
We can achieve that condition by using a dynamic configuration in Logback. This is how we do it, we’ll start with using a specific logging library called Logback.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.edw</groupId>
<artifactId>springboot-and-logback-xml</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.4</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
And create a file called logback.xml,
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="APP_LOG_LEVEL" value="${APP_LOG_LEVEL:-INFO}" />
<property name="ROOT_LOG_LEVEL" value="${ROOT_LOG_LEVEL:-WARN}" />
<appender name="CONSOLE"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<logger name="com.edw" level="${APP_LOG_LEVEL}" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>
<root level="${ROOT_LOG_LEVEL}">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
We can test by using below Java code where we create two different logging line with different log level,
package com.edw.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
@RestController
public class IndexController {
private static final Logger logger = LoggerFactory.getLogger(IndexController.class);
@GetMapping("/")
public HashMap getIndexPage() {
logger.debug("we are at index page using {}", "DEBUG");
logger.info("we are at index page using {}", "INFO");
return new HashMap() {{
put("hello", "world");
}};
}
}
We can run the project using default command and see default log outputs
$ java -jar springboot-and-logback-xml-1.0-SNAPSHOT.jar . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.0.4) 14:12:49.321 [main] INFO com.edw.Main - Starting Main v1.0-SNAPSHOT using Java 17.0.6 with PID 13480 14:12:49.326 [main] INFO com.edw.Main - No active profile set, falling back to 1 default profile: "default" 14:12:51.122 [main] INFO com.edw.Main - Started Main in 2.283 seconds (process running for 2.983) 14:13:02.489 [http-nio-8080-exec-1] INFO com.edw.controller.IndexController - we are at index page using INFO
However for a much more detail outputs, we can use below command with configured “APP_LOG_LEVEL” and “ROOT_LOG_LEVEL”
$ java -DAPP_LOG_LEVEL=DEBUG -DROOT_LOG_LEVEL=INFO -jar springboot-and-logback-xml-1.0-SNAPSHOT.jar . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.0.4) 14:15:40.353 [main] INFO com.edw.Main - Starting Main v1.0-SNAPSHOT using Java 17.0.6 with PID 9004 14:15:40.356 [main] DEBUG com.edw.Main - Running with Spring Boot v3.0.4, Spring v6.0.6 14:15:40.357 [main] INFO com.edw.Main - No active profile set, falling back to 1 default profile: "default" 14:15:41.774 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8080 (http) 14:15:41.788 [main] INFO o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"] 14:15:41.789 [main] INFO o.a.catalina.core.StandardService - Starting service [Tomcat] 14:15:41.789 [main] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.5] 14:15:41.903 [main] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext 14:15:41.905 [main] INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1449 ms 14:15:42.365 [main] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"] 14:15:42.404 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path '' 14:15:42.425 [main] INFO com.edw.Main - Started Main in 2.604 seconds (process running for 3.422) 14:17:29.454 [http-nio-8080-exec-1] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet' 14:17:29.455 [http-nio-8080-exec-1] INFO o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet' 14:17:29.456 [http-nio-8080-exec-1] INFO o.s.web.servlet.DispatcherServlet - Completed initialization in 1 ms 14:17:29.490 [http-nio-8080-exec-1] DEBUG com.edw.controller.IndexController - we are at index page using DEBUG 14:17:29.492 [http-nio-8080-exec-1] INFO com.edw.controller.IndexController - we are at index page using INFO
For Kubernetes delployments, we can also use below environment variables
env: - name: APP_LOG_LEVEL value: DEBUG - name: ROOT_LOG_LEVEL value: INFO



