2010-10-01 5 views
103

Mam następujący plik logback.xml:Jak zmienić poziom rejestrowania korzeniowy programowo

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

Teraz po wystąpieniu określonego zdarzenia, chcę programowo zmienić poziom rejestratora głównego z debugowania do error. Nie mogę użyć substytucji zmiennych, jest to obowiązkowe, że robię to w ramach kodu.

Jak to zrobić? Dzięki.

Odpowiedz

181

Spróbuj tego:

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

pamiętać, że można również powiedzieć logback okresowo skanuje plik konfiguracyjny tak:

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

Należy zauważyć, że celem slf4j jest abstrakcyjnym dala ramach rejestrowania, ale to pierwsza metoda eliminuje że poprzez odniesienie ramy rejestrowania bezpośrednio. –

+3

Jeśli to zrobisz i uzyskasz wyjątek ClassCastException, najprawdopodobniej jest to spowodowane posiadaniem wielu powiązań SLF4J w ścieżce klas. Dane wyjściowe dziennika będą wskazywać to i które wiązania są obecne, aby umożliwić określenie, które z nich należy wykluczyć. – icfantv

+1

W odpowiedzi na komentarz Tima, należy również zauważyć, że czasami po prostu pracujesz nad rozwojem, a program rejestrujący wypluwa rzeczy, które Cię nie interesują i chwilowo chcesz je wyłączyć, a więc w takim przypadku o coś się martwić. –

9

Zakładam, że korzystasz z funkcji logback (z pliku konfiguracyjnego).

Od logback manual widzę

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

Być może to pomoże Ci zmienić wartość?

2

Jak wskazano przez innych, po prostu stworzyć mockAppender a następnie utworzyć instancja LoggingEvent, która zasadniczo nasłuchuje zarejestrowanego zdarzenia rejestrowania/dzieje się wewnątrz mockAppender.

Oto jak to wygląda w teście:

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

Czy możesz dołączyć swoje instrukcje importu? Teraz nie można zobaczyć, z jakiej implementacji rejestratora korzystałeś. –

+1

@AndreasLundgren - przepraszamy za początkowe dołączenie instrukcji importu. Dodałem je teraz. Twoje zdrowie –

7

użyciu logback 1.1.3 musiałem wykonać następujące czynności (kod Scala):

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

myślę, że można użyć do MDC zmiana poziomu logowania programowo. Poniższy kod jest przykładem do zmiany poziomu rejestrowania w bieżącym wątku. Takie podejście nie powoduje zależności od implementacji logback (SLF4J API zawiera 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");