Как программно изменить уровень корневого журналирования

У меня есть следующий файл 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>

Теперь, после появления определенного события, я хочу программным образом изменить уровень корневого регистратора от отладки до ошибки. Я не могу использовать подстановку переменных, обязательно, чтобы я делал это в коде.

Как это можно сделать? Спасибо.

Ответ 1

Попробуйте следующее:

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

Обратите внимание, что вы также можете сообщить журналу о периодическом сканировании вашего файла конфигурации следующим образом:

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

Ответ 2

Я предполагаю, что вы используете logback (из файла конфигурации).

Из журнал регистрации, я вижу

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

Возможно, это может помочь вам изменить значение?

Ответ 3

используя logback 1.1.3 Мне пришлось сделать следующее (Scala code):

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

Ответ 4

Как указывалось другими, вы просто создаете 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 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"));
}
}

Ответ 5

Я думаю, вы можете использовать MDC для изменения уровня ведения журнала программно. Приведенный ниже код является примером изменения уровня ведения журнала на текущем потоке. Этот подход не создает зависимости от реализации репликации (API SLF4J содержит 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");