2010-08-16 7 views
6

Ich möchte Slf4j mit Logback in eine Legacy-Anwendung nachrüsten. Gut, dass die Legacy-Anwendung ihr eigenes Logging-Framework hat. Alles, was ich tun musste, ist, das Logging-Framework so zu ändern, dass es nach slf4j statt log4j loggt.Wrapping der slf4j API

Es funktionierte wie ein Traum. Ich war glücklich, bis ich den Ort Logback für jedes Log-Ereignis protokolliert:

Logger.java:... 

Huch! Das würde meinen Entwicklerkollegen nicht viel helfen, wenn sie herausfinden wollten, woher ein Log-Ereignis kam.

Wie kann ich Logback sagen, um ein paar Ebenen im Stapel nach dem tatsächlichen Standort zu suchen, um zu loggen?

Der Logger-Klasse ist eine Utility-Klasse mit Methoden wie folgt aus:

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

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

+0

funktionierte das, wenn es log4j verwendete? Ich würde denken, da Sie eine vorhandene Protokollierungsklasse aktualisiert haben, haben Sie dem Aufrufstapel keinen zusätzlichen Rahmen hinzugefügt, sodass die log4j-Version das gleiche Problem aufweisen sollte. – Thilo

+1

log4j legt eine Protokollmethode in seiner öffentlichen API offen, die einen zusätzlichen Frame im Stapel darstellt, während slf4j dies nicht tut. Also ja, es hat mit log4j funktioniert. –

Antwort

10

Gefunden die Lösung mit Blick auf die Quelle von jcl-over-slf4j. Die meisten Implementierungen von slf4j (einschließlich logback) verwenden Loggern, die LocationAwareLogger implementieren, die eine Log-Methode hat, das den vollständig qualifizierten Klassennamen des Verpackungs Logger-Klasse als eines seiner Argumente erwartet:

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

Siehe die verschiedenen XXX-over-slf4j Implementierungen, wie es zu tun.

Grundsätzlich möchten Sie Ihre aktuelle Logger-Framework vollständig ersetzen. Nicht wrap slf4j.

Edit:

Ein weiterer Ansatz könnte Ihr eigenes Layout Subklassen die man schreiben Sie jetzt verwenden, die eine überarbeitete Bedeutung des% m,% l etc Felder, die den zusätzlichen Stapelrahmen überspringt.

+2

Ich habe diese Lösung in Betracht gezogen, aber derzeit gibt es kein Budget, um 10000+ Log-Anweisungen zu ersetzen, die in mehr als 50 Projekten verstreut sind. –

+0

Sie müssen die Protokollanweisungen nicht ändern, aber den Code, der aufgerufen wird (der sich hoffentlich in einer Bibliothek befindet) –

+1

Das Logger-Framework verfügt über 10000 Methodenaufrufe von allen Projekten. Wenn ich also das Logger-Framework ersetzen würde, müsste ich nicht auch alle Methodenaufrufe ersetzen? –