Spring Boot uses logback as the logging framework by default. logback provides an interface to get logger and modify logger logging levels.

Actually actuator also provides endpoint for managing logs. You can check the official documentation for details.

LogController

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package io.springboot.log.controller;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;

@RestController
@RequestMapping("/log")
public class LogController {

    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(LogController.class);

    @GetMapping("/test")
    public void test() {
        LOGGER.debug("level -- debug");
        LOGGER.info("level -- info");
        LOGGER.warn("level -- warn");
        LOGGER.error("level -- warn");
    }

    /**
        * 
        * Get all loggers and the corresponding log levels.
        * 
        * @return
        */
    @GetMapping(produces = "application/json; charset=utf-8")
    public Object log() {

        // Get the LoggerContext of the Logback
        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
        // Get all loggers of the system
        List<Map<String, String>> loggers = loggerContext.getLoggerList().stream()
                // There are too many loggers, and they are filtered here for demonstration purposes. Only the logger of the current controller is returned.
                .filter(logger -> logger.getName().equals(LogController.class.getName()))
                // Mapping to map
                .map(logger -> {
                    Map<String, String> retVal = new LinkedHashMap<>();
                    // logger name & logger validity level
                    retVal.put(logger.getName(), logger.getEffectiveLevel().levelStr);
                    return retVal;
                }).collect(Collectors.toList());
        return loggers;
    }

    /**
        * Setting the log level
        * 
        * @param loggerName Logger Name
        * @param level      Log level
        * @return
        */
    @GetMapping(path = "/set", produces = "text/plain; charset=utf-8")
    public Object set(@RequestParam("logger") String loggerName, @RequestParam("level") String level) {
        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();

        Logger logger = loggerContext.exists(loggerName);
        if (logger == null) {
            return "Logger does not exist." + loggerName;
        }

        Level newLevel = Level.toLevel(level, null);
        if (newLevel == null) {
            return "Not a legal log level::" + level;
        }

        logger.setLevel(newLevel);

        return "OK";
    }
}

Test

Get the logger’s log level.

1
2
3
4
5
6
7
curl http://localhost:8080/log

[
    {
        "io.springboot.log.controller.LogController": "INFO"
    }
]

Set the logger’s log level.

1
2
3
curl http://localhost:8080/log/set?logger=io.springboot.log.controller.LogController&level=debug

OK

Get the logging level of the logger again. The modification has taken effect.

1
2
3
4
5
6
7
curl http://localhost:8080/log

[
    {
        "io.springboot.log.controller.LogController": "DEBUG"
    }
]