2010-04-29 1 views
6

Nous avons une classe « log » qui utilise Relection.MethodBase pour envoyer l'information de classe actuelle dans le journal.Utilisation de la classe StackTrace dans un environnement de production pour obtenir les informations d'appeler la méthode

La réflexion.MethodBase se produit dans la classe elle-même.

Cependant, je voudrais passer ce genre de choses à une seule classe de type singleton « log » externe.

Dans ce scénario, la classe journal externe doit obtenir l'information APPELER, pas l'information actuelle de la méthode. J'utilise stacktrace pour ce faire, qui n'est pas dans l'espace de noms Reflection.

Puis-je garantir que des informations spécifiques « que » (méthode d'appel) sera là dans un environnement de production?

var stackTrace = new StackTrace(); 
return LogManager.GetLogger(stackTrace.GetFrame(1).GetMethod().DeclaringType); 

cheers!

Répondre

7

Oui, même dans un « libérer » construire sans vous de PDB aurez les noms de méthode dans une trace de la pile. Mais personnellement, je considérerais cela comme un code smell. Cela implique un chemin de code très fragile (par exemple, que se passe-t-il si vous créez une méthode WriteLine qui appelle une méthode Write, regardez-vous l'appelant de l'appelant dans ce cas?). Il n'est probablement pas bon marché de prendre un instantané de la trace de la pile à chaque appel de journalisation.

J'ai récemment posted a question about using MEF to inject a logger dans ma classe et je voulais associer un nom de type avec les données du journal ainsi. MEF fonctionnait assez bien pour moi car j'étais capable d'importer une instance d'ILogger pour chaque classe qui voulait l'utiliser et quand l'instance d'ILogger était importée, je définissais sa propriété Category au nom de la classe actuelle. Pas de réflexion, pas de trace de pile. Cela a très bien fonctionné pour moi.

+0

convenu. Une meilleure recommandation? Idéalement, je ne voudrais pas mettre des choses de réflexion dans d'autres classes, j'aimerais que l'enregistreur les gère en interne ... des idées? – andy

+0

En écrivant que je viens d'éditer ma réponse pour pointer vers une méthode que j'ai utilisée. – Josh

3

Josh a raison. Prendre des traces de pile est très coûteux et devrait être évité. C'est un peu difficile de comprendre exactement ce que vous faites, mais cela semble plutôt mauvais. Ma première suggestion serait de jeter un autre regard sur votre environnement de production et de voir quels services de journalisation sont déjà en place et comment vous pouvez les utiliser.

Si vous ne pouvez pas, alors je serais à la recherche dans les API déjà disponibles telles que Log4j, SLF4j et la connexion Commons pour voir comment vous pourriez les utiliser. Enfin, s'il n'est toujours pas utilisable, vous pouvez au moins regarder leur source pour voir comment ils font les choses. La source de JUnit empile aussi l'analyse des traces si je me souviens bien, donc il y a une autre source d'idées. Mais mon dernier mot serait de garder les choses aussi simples que possible. Ne faites pas le tour en créant des traces de pile. D'une manière générale, vous ne vous souciez vraiment que d'une exception et ensuite elle vous est remise. Vous n'avez rien d'autre à faire que de le transmettre.

+0

ouais J'utilise log4net, auquel vous devez encore transmettre des informations de réflexion, et je veux que l'enregistreur gère cela. cependant +1 pour souligner l'évidence que j'ai raté! seulement s'en soucier si c'est une erreur, bon point! – andy

Questions connexes