2010-08-16 5 views
6

Desidero eseguire il retrofit di slf4j con Logback in un'applicazione legacy. La cosa buona è che l'applicazione legacy ha il proprio framework di registrazione. Quindi tutto ciò che dovevo fare è modificare il framework di registrazione per accedere a slf4j anziché a log4j.Wrapping dell'API slf4j

Ha funzionato come un sogno. Ero felice, fino a quando ho notato la posizione Logback registrato per ogni evento del registro:

Logger.java:... 

Yikes! Questo non avrebbe aiutato molto i miei colleghi sviluppatori quando cercavo di capire da dove proveniva un evento del registro.

Come posso dire a Logback di apparire alcuni livelli in cima allo stack per la posizione effettiva da registrare?

La classe Logger è una classe di utilità con metodi come questo:

public static void debug(String clazz, String message) { 
    org.slf4j.Logger logger = LoggerFactory.getLogger(clazz); 
    logger.debug(message); 
} 
+1

domanda simile: http: // stackoverflow.com/questions/1486233/java-logging-show-the-source-line-number-of-the-caller-not-the-logging-helper-m – Thilo

+0

ha funzionato quando stava usando log4j? Penso che da quando hai aggiornato una classe di registrazione esistente, non hai aggiunto un frame aggiuntivo allo stack di chiamate, quindi la versione di log4j avrebbe dovuto presentare lo stesso problema. – Thilo

+1

log4j espone un metodo di log nella sua API pubblica che sembra un frame in più nello stack mentre slf4j non lo fa. Quindi sì, ha funzionato con log4j. –

risposta

10

Trovato la soluzione alla fonte di jcl-over-slf4j. La maggior parte delle implementazioni di slf4j (tra cui logback) utilizzano logger che implementano LocationAwareLogger, che ha un metodo di registro che si aspetta che il nome di classe completo della classe involucro logger come uno dei suoi argomenti:

private static final String FQCN = Logger.class.getName(); 


public static void debug(String clazz, String message) { 
    org.slf4j.Logger logger = LoggerFactory.getLogger(clazz); 
    if (logger instanceof LocationAwareLogger) { 
     ((LocationAwareLogger) logger).log(null, FQCN, LocationAwareLogger.DEBUG_INT, message, null, null); 
    } else { 
     logger.debug(message); 
    } 
} 
5

Vedi le varie implementazioni XXX-over-SLF4J per come farlo.

Fondamentalmente si desidera sostituire il proprio framework attuale di logger completamente. Non avvolgere slf4j.

Edit:

Un altro approccio potrebbe essere la scrittura del proprio layout sottoclasse quella che usate ora, che ha un significato rivista del% m, l% campi, ecc, che salta lo stack frame in più.

+2

Ho considerato questa soluzione, ma al momento non esiste un budget per sostituire più di 10000 dichiarazioni di log sparse su oltre 50 progetti. –

+0

Non è necessario modificare le istruzioni del registro, ma il codice che chiama (che si spera sia in una libreria) –

+1

Il framework del logger ha oltre 10000 chiamate di metodo da tutti i progetti. Quindi, se ho sostituito il framework del logger, non dovrei sostituire anche tutte le chiamate di metodo? –