2010-08-16 5 views
6

Je veux rétroadapter slf4j avec Logback dans une application héritée. La bonne chose est, l'application héritée a son propre cadre de journalisation. Donc tout ce que je devais faire est de modifier le cadre de journalisation pour se connecter à slf4j au lieu de log4j.Habillage de l'API slf4j

Cela a fonctionné comme un rêve. J'étais heureux, jusqu'à ce que j'ai remarqué l'emplacement Logback connecté pour chaque événement de journal:

Logger.java:... 

Yikes! Cela n'allait pas aider beaucoup mes collègues développeurs en essayant de comprendre d'où venait un événement de journal.

Comment puis-je demander à Logback de rechercher quelques niveaux dans la pile pour que l'emplacement réel soit enregistré?

La classe de l'enregistreur est une classe utilitaire avec des méthodes comme celle-ci:

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

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

+0

fait ce travail quand il utilisait log4j? Je pense que depuis que vous avez mis à jour une classe de journalisation existante, vous n'avez pas ajouté d'image supplémentaire à la pile d'appels, donc la version de log4j aurait dû présenter le même problème. – Thilo

+1

log4j expose une méthode log dans son API publique qui recherche un cadre supplémentaire dans la pile, contrairement à slf4j. Alors oui, cela a fonctionné avec log4j. –

Répondre

10

Trouvé la solution en regardant la source de jcl-over-slf4j. La plupart des implémentations de slf4j (y compris logback) utilisent des enregistreurs qui mettent en œuvre LocationAwareLogger, qui a une méthode de journal qui attend le nom complet de la classe de la classe de l'enregistreur d'emballage comme l'un de ses arguments:

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

Voir les différentes implémentations XXX-over-SLF4J sur la façon de le faire.

Fondamentalement, vous voulez remplacer votre infrastructure de journalisation actuelle complètement. Ne pas envelopper slf4j.

Edit:

Une autre approche pourrait être en train d'écrire votre propre mise en page sous-classement celui que vous utilisez maintenant, ce qui a une signification révisée du% m,% l champs etc, qui saute le cadre supplémentaire de la pile.

+2

J'ai considéré cette solution, mais actuellement il n'y a pas de budget pour remplacer 10000+ relevés de journaux dispersés sur plus de 50 projets. –

+0

Vous n'avez pas besoin de modifier les instructions du journal, mais le code qu'il appelle (qui, espérons-le, se trouve dans une bibliothèque) –

+1

La structure du consignateur contient plus de 10000 appels de méthode de tous les projets. Donc, si je remplaçais la structure de l'enregistreur, n'aurais-je pas à remplacer tous les appels de méthode? –

Questions connexes