2010-10-01 101 views
103

ho il seguente file logback.xml:Come cambiare livello di registrazione di radice di programmazione

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

Ora, al verificarsi di un evento specifico, voglio cambiare a livello di codice il livello del logger principale da di debug a errore. Non posso usare la sostituzione variabile, è obbligatorio farlo all'interno del codice.

Come può essere fatto? Grazie.

risposta

181

Prova questo:

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

Nota che si può anche dire logback eseguire periodicamente la scansione file di configurazione in questo modo:

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

Va notato che lo scopo della slf4j è quello di astrarre il quadro di registrazione, ma questo primo metodo elimina che facendo riferimento direttamente al quadro di registrazione. –

+3

Se si esegue questa operazione e si ottiene una classe ClassCastException, è molto probabile che vi siano più associazioni SLF4J sul classpath. L'output del registro indicherà questo e quali collegamenti sono presenti per consentire all'utente di determinare quale (i) è necessario (i) da escludere. – icfantv

+1

In risposta al commento di Tim, va anche notato che a volte stai solo facendo lo sviluppo e il registratore sta vomitando cose che non ti interessano e vuoi temporaneamente disattivarlo, quindi in questo caso non è così qualcosa di cui preoccuparsi. –

9

Presumo che si stia utilizzando il logback (dal file di configurazione).

Da logback manual, vedo

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

Forse questo può aiutare a cambiare il valore?

2

Come sottolineato da altri, è sufficiente creare mockAppender e quindi creare un'istanza LoggingEvent che essenzialmente ascolta l'evento di registrazione registrato/accade all'interno di mockAppender.

Ecco come appare come in prova:

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

Potresti includere le dichiarazioni di importazione? Ora non è possibile vedere quale implementazione di logger hai usato. –

+1

@AndreasLundgren - scuse per non aver inizialmente incluso le istruzioni di importazione. Ora ho aggiunto quelli. Saluti –

7

utilizzando logback 1.1.3 ho dovuto fare il seguente (codice 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

Penso che si può utilizzare per MDC modifica del livello di registrazione a livello di codice. Il codice seguente è un esempio per modificare il livello di registrazione sul thread corrente. Questo approccio non crea dipendenza dall'implementazione di logback (l'API SLF4J contiene 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"); 
Problemi correlati