2010-10-01 26 views
103

tengo el siguiente archivo logback.xml:Cómo cambiar el nivel de registro de raíz mediante programación

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

Ahora, ante la ocurrencia de un evento específico, quiero cambiar mediante programación el nivel de la raíz del registrador depuración a error. No puedo usar la sustitución de variables, es obligatorio que haga esto dentro del código.

¿Cómo se puede hacer? Gracias.

Respuesta

181

Prueba esto:

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

en cuenta que también puede decir logback para escanear periódicamente su archivo de configuración como esta:

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

Cabe señalar que el propósito de slf4j es abstraer el marco de registro, pero ese primer método que elimina haciendo referencia al marco de registro directamente. –

+3

Si hace esto y obtiene una ClassCastException, es muy probable que se deba a tener múltiples enlaces SLF4J en la ruta de clase. El resultado del registro indicará esto y qué enlaces están presentes para permitirle determinar cuál (es) necesita (n) excluir. – icfantv

+1

En respuesta al comentario de Tim, también se debe tener en cuenta que a veces solo estás desarrollando y el registrador está escupiendo cosas que no te interesan y solo quieres apagarlo temporalmente, por lo que en ese caso no es así. algo de qué preocuparse –

9

Supongo que está utilizando logback (desde el archivo de configuración).

De logback manual, veo

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

Tal vez esto puede ayudar a cambiar el valor?

2

Como se ha comentado en otras, sólo tiene que crear mockAppender y luego crear una instancia LoggingEvent que esencialmente escucha el evento de registro registrado/ocurre dentro de mockAppender.

Así es como se ve en la prueba:

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

¿Podría incluir sus declaraciones de importación? Ahora no es posible ver qué implementación de registrador usó. –

+1

@AndreasLundgren - disculpas por no incluir inicialmente las declaraciones de importación. Ahora he agregado esos. Aclamaciones –

7

usando logback 1.1.3 que tenía que hacer lo siguiente (código 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

Creo que se puede utilizar a MDC cambiar el nivel de registro programáticamente. El siguiente código es un ejemplo para cambiar el nivel de registro en el hilo actual. Este enfoque no crea dependencia a la implementación de logback (SLF4J API 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"); 
Cuestiones relacionadas