logback 中如何以编程方式更改 root 日志记录级别

我有以下 logback.xml 文件:






%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n








现在,当特定事件发生时,我想以编程方式将 root logger 的级别从 debug更改为 error。我不能使用变量替换,而且是强制性的。

怎么才能做到? 谢谢。

177163 次浏览

我假设您正在使用 logback (来自配置文件)。

回程手册,我明白了

Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);

也许这能帮你改变价值?

试试这个:

import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;


Logger root = (Logger)LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
root.setLevel(Level.INFO);

注意,还可以像下面这样告诉 logback 定期扫描配置文件:

<configuration scan="true" scanPeriod="30 seconds" >
...
</configuration>

正如其他人指出的那样,您只需创建 mockAppender,然后创建一个 LoggingEvent实例,该实例基本上监听在 mockAppender中注册/发生的日志事件。

下面是它在测试中的样子:

import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.Appender;


@RunWith(MockitoJUnitRunner.class)
public class TestLogEvent {


// your Logger
private Logger log = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);


// here we mock the appender
@Mock
private Appender<ILoggingEvent> mockAppender;


// Captor is generic-ised with ch.qos.logback.classic.spi.LoggingEvent
@Captor
private ArgumentCaptor<LoggingEvent> captorLoggingEvent;


/**
* set up the test, runs before each test
*/
@Before
public void setUp() {
log.addAppender(mockAppender);
}


/**
* Always have this teardown otherwise we can stuff up our expectations.
* Besides, it's good coding practise
*/
@After
public void teardown() {
log.detachAppender(mockAppender);
}




// Assuming this is your method
public void yourMethod() {
log.info("hello world");
}


@Test
public void testYourLoggingEvent() {


//invoke your method
yourMethod();


// now verify our logging interaction
// essentially appending the event to mockAppender
verify(mockAppender, times(1)).doAppend(captorLoggingEvent.capture());


// Having a generic captor means we don't need to cast
final LoggingEvent loggingEvent = captorLoggingEvent.getValue();


// verify that info log level is called
assertThat(loggingEvent.getLevel(), is(Level.INFO));


// Check the message being logged is correct
assertThat(loggingEvent.getFormattedMessage(), containsString("hello world"));
}
}

使用 logback 1.1.3我必须执行以下操作(Scala 代码) :

import ch.qos.logback.classic.Logger
import org.slf4j.LoggerFactory
...
val root: Logger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME).asInstanceOf[Logger]

我认为您可以使用 MDC 以编程方式更改日志记录级别。下面的代码是在当前线程上更改日志记录级别的示例。此方法不创建对日志回退实现的依赖关系(SLF4JAPI 包含 MDC)。

<configuration>
<turboFilter class="ch.qos.logback.classic.turbo.DynamicThresholdFilter">
<Key>LOG_LEVEL</Key>
<DefaultThreshold>DEBUG</DefaultThreshold>
<MDCValueLevelPair>
<value>TRACE</value>
<level>TRACE</level>
</MDCValueLevelPair>
<MDCValueLevelPair>
<value>DEBUG</value>
<level>DEBUG</level>
</MDCValueLevelPair>
<MDCValueLevelPair>
<value>INFO</value>
<level>INFO</level>
</MDCValueLevelPair>
<MDCValueLevelPair>
<value>WARN</value>
<level>WARN</level>
</MDCValueLevelPair>
<MDCValueLevelPair>
<value>ERROR</value>
<level>ERROR</level>
</MDCValueLevelPair>
</turboFilter>
......
</configuration>
MDC.put("LOG_LEVEL", "INFO");

我似乎成功地做到了

org.jboss.logmanager.Logger logger = org.jboss.logmanager.Logger.getLogger("");
logger.setLevel(java.util.logging.Level.ALL);

然后从 netty 获得详细的日志记录,下面已经完成了

org.slf4j.impl.SimpleLogger.setLevel(org.slf4j.impl.SimpleLogger.TRACE);

这是控制器

@RestController
@RequestMapping("/loggers")
public class LoggerConfigController {


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


@GetMapping()
public List<LoggerDto> getAllLoggers() throws CoreException {
    

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

List<Logger> loggers = loggerContext.getLoggerList();
    

List<LoggerDto> loggerDtos = new ArrayList<>();
    

for (Logger logger : loggers) {
        

if (Objects.isNull(logger.getLevel())) {
continue;
}
        

LoggerDto dto = new LoggerDto(logger.getName(), logger.getLevel().levelStr);
loggerDtos.add(dto);
}
    

if (LOGGER.isDebugEnabled()) {
LOGGER.debug("All loggers retrieved. Total of {} loggers found", loggerDtos.size());
}
    

return loggerDtos;
}


@PutMapping
public boolean updateLoggerLevel(
@RequestParam String name,
@RequestParam String level
)throws CoreException {
    

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

Logger logger = loggerContext.getLogger(name);
    

if (Objects.nonNull(logger) && StringUtils.isNotBlank(level)) {
        

switch (level) {
case "INFO":
logger.setLevel(Level.INFO);
LOGGER.info("Logger [{}] updated to [{}]", name, level);
break;
                

case "DEBUG":
logger.setLevel(Level.DEBUG);
LOGGER.info("Logger [{}] updated to [{}]", name, level);
break;
                

case "ALL":
logger.setLevel(Level.ALL);
LOGGER.info("Logger [{}] updated to [{}]", name, level);
break;
                

case "OFF":
default:
logger.setLevel(Level.OFF);
LOGGER.info("Logger [{}] updated to [{}]", name, level);
}
}
    

return true;
}

}