Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically change log level for every class in a specific package

I'm working on a project that uses SLF4J + Logback, and I was hoping to find a way to configure the log level of different scopes by using a REST API call. The call takes in an object with the scope (class, package, or root path) and the desired logging level. Each class in my project that has a logger uses a static Logback logger.

I used other Stack Overflow answers & the Logback manual to find the solution to change the logging level for a single class:

LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
Logger target = loggerContext.getLogger(DESIRED_CLASS_PATH);
target.setLevel(DESIRED_LOGGING_LEVEL);

This works for that class. However, I tried to use the root logger to change all of the loggers for all of the classes in my project, using this:

Logger rootLogger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
rootLogger.setLevel(DESIRED_LOGGING_LEVEL);

This only changes the root logger, and when I try to print out the log level for any class inside the project, it is not the desired logging level. I tried declaring a logger in the logback.xml file that declared a package logger (the package in which all of my classes and subpackages are contained) and tried modifying that to change the subclass loggers, but this did not work. Here is my logback.xml file:

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
        </layout>
    </appender>

    <root level="info">
        <appender-ref ref="STDOUT"/>
    </root>

    <logger name="my.uppermost.package" level="info" additivity="false">
        <appender-ref ref="STDOUT"/>
    </logger>
</configuration>

Am I misunderstanding the code or abilities of Logback? If not, is there a way in which I could enter in a package path to my REST API call and update ALL of the loggers for the classes contained in that package?

like image 213
dgupta Avatar asked Jul 17 '18 15:07

dgupta


People also ask

How do you change the logger level?

To change log levels as a root user, perform the following: To enable debug logging, run the following command: /subsystem=logging/root-logger=ROOT:change-root-log-level(level=DEBUG) To disable debug logging, run the following command: /subsystem=logging/root-logger=ROOT:change-root-log-level(level=INFO)

How do you change the log level at log4j2 runtime?

If you wish to change the root logger level, do something like this : LoggerContext ctx = (LoggerContext) LogManager. getContext(false); Configuration config = ctx. getConfiguration(); LoggerConfig loggerConfig = config.


1 Answers

You can get the list of existing logger and filter them by name :

LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();

for(logger : loggerContext.getLoggerList()) {
 if(logger.getName().startWith("my.target.package.")) {
  logger.setLevel(DESIRED_LOGGING_LEVEL);
 }
}

Note that it will change the log level only of logger that already exist. If some object in my.target.package register a logger later, its log level will be whatever is configured in logback.xml

like image 125
Thibault Urien Avatar answered Oct 03 '22 07:10

Thibault Urien