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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3837801/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 05:39:49  来源:igfitidea点击:

How to change root logging level programmatically for logback

javalogginglogback

提问by Kai Sternad

I have the following logback.xml file:

我有以下 logback.xml 文件:

<configuration debug="true"> 

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

<root level="debug">
  <appender-ref ref="STDOUT" />
</root>
</configuration>

Now, upon the occurrence of a specific event, I want to programmatically change the level of the root logger from debugto error. I can't use variable substitution, it is mandatory that I do this within the code.

现在,在发生特定事件时,我想以编程方式将根记录器的级别从debug更改为error。我不能使用变量替换,我必须在代码中执行此操作。

How can it be done ? Thanks.

怎么做到呢 ?谢谢。

采纳答案by dogbane

Try this:

尝试这个:

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

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

Note that you can also tell logback to periodically scan your config file like this:

请注意,您还可以告诉 logback 定期扫描您的配置文件,如下所示:

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

回答by Raghuram

I assume you are using logback (from the configuration file).

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

From logback manual, I see

logback 手册中,我看到

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

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

Perhaps this can help you change the value?

也许这可以帮助您更改值?

回答by Simple-Solution

As pointed out by others, you simply create mockAppenderand then create a LoggingEventinstance which essentially listens to the logging event registered/happens inside mockAppender.

正如其他人所指出的那样,您只需创建mockAppender然后创建一个LoggingEvent实例,该实例本质上侦听在 内部注册/发生的日志记录事件mockAppender

Here is how it looks like in test:

这是它在测试中的样子:

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"));
}
}

回答by Todor Kolev

using logback 1.1.3 I had to do the following (Scala code):

使用 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]

回答by SATO Yusuke

I think you can use MDC to change logging level programmatically. The code below is an example to change logging level on current thread. This approach does not create dependency to logback implementation (SLF4J API contains MDC).

我认为您可以使用 MDC 以编程方式更改日志记录级别。下面的代码是在当前线程上更改日志记录级别的示例。这种方法不会创建对 logback 实现的依赖(SLF4J API 包含 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");

回答by user7610

I seem to be having success doing

我似乎成功了

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

Then to get detailed logging from netty, the following has done it

然后从netty获取详细的日志,下面已经做到了

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