Change Logback Log Level Programmatically at Runtime via a REST API in Spring Boot
In this tutorial, we will show you how to change Logback log level programmatically at runtime via a REST API in Spring Boot.
The required Logback dependencies for this example are Logback Core, Logback Classic, SLF4J. However, these Logback dependencies are available by default if our Spring Boot project uses spring-boot-starter-web dependency.
Follow the steps below to complete this example:
- Spring Boot expects logback.xml configuration file under the resources folder of the application. Let the configuration in the logback.xml file be the following:
- Create a LoggingService.java interface with a method to change the log level:
- Create an implementation class of the above LoggingService interface:
- Create a controller with a REST API endpoint that allows to change logging level for the application package as shown in the example below:
- You can run your application and test the API by making a PUT request as shown in the example below:
package com.example.logback.service;
public interface LoggingService {
void changeLogLevel(String level, String packageName);
}
package com.example.logback.service.impl;
import java.util.Arrays;
import java.util.List;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import com.example.logback.service.LoggingService;
public class LoggingServiceImpl implements LoggingService {
@Override
public void changeLogLevel(String level, String packageName) throws Exception {
List<String> validLevels = Arrays.asList("TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF");
if (!validLevels.contains(level.toUpperCase())) {
throw new Exception("Invalid Log level");
}
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
ch.qos.logback.classic.Logger classicLogger = loggerContext.getLogger(packageName);
System.out.println(packageName + " current logger level: " + classicLogger.getLevel());
System.out.println(" You entered: " + level);
classicLogger.setLevel(Level.toLevel(level));
}
}
package com.example.logback.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.PutMapping;
import com.example.logback.service.LoggingService;
@RestController
@RequestMapping(path = "/logging")
public class LoggingController {
@Autowired
private LoggingService loggingService;
@PutMapping(path = "/change-log-level")
public void changeLogLevel(@RequestParam(name = "level", defaultValue = "info") String level,
@RequestParam(name = "packageName", defaultValue = "com.example.service.impl.TransactionServiceImpl") String packageName) {
try {
loggingService.changeLogLevel(level, packageName);
} catch (Exception e) {
e.printStackTrace();
}
}
}
