2010-04-29 10 views
6

Mamy klasę "log", która używa Relection.MethodBase do wysyłania aktualnych informacji o klasie do dziennika.Używanie klasy StackTrace w środowisku produkcyjnym do uzyskania informacji o metodach wywoływania

Rzeczy z reflect.MethodBase dzieje się w samej klasie.

Chciałbym jednak przenieść te rzeczy do pojedynczej zewnętrznej klasy "log" typu singleton.

W tym scenariuszu klasa dziennika zewnętrznego musi uzyskać informacje o wezwaniu, a nie bieżące informacje o metodzie. Do tego celu używam stacktrace, którego nie ma w przestrzeni nazw Reflection.

Czy mogę zagwarantować, że "ta" konkretna informacja (metoda wywołania) będzie dostępna w środowisku produkcyjnym?

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

Pozdrawiam!

Odpowiedz

7

Tak, nawet w wersji "release" bez żadnych PDB będziesz miał nazwy metod w ślad stosu. Ale osobiście uważam to za code smell. Sugeruje to bardzo delikatną ścieżkę kodu (na przykład, co się stanie, jeśli stworzysz metodę WriteLine, która wywołuje metodę Write, czy w takim przypadku patrzysz na wywołującego dzwoniącego?). Prawdopodobnie nie jest tani, aby zrobić migawkę śledzenia stosu przy każdym wywołaniu rejestrowania.

Niedawno na moją klasę trafiłem na posted a question about using MEF to inject a logger i chciałem powiązać nazwę typu z danymi dziennika. MEF działało całkiem dobrze, ponieważ mogłem zaimportować instancję ILogger dla każdej klasy, która chciała go użyć, a gdy instancja ILogger została zaimportowana, ustawiłbym jej właściwość Category na nazwę bieżącej klasy. Bez refleksów, bez śladu stosu. Dla mnie to działało całkiem nieźle.

+0

uzgodnione. Jakieś lepsze rekomendacje? Idealnie nie chciałbym umieszczać refleksji w innych klasach, chciałbym żeby logger obsługiwał to wewnętrznie ... jakieś pomysły? – andy

+0

Kiedy pisałeś, właśnie zredagowałem swoją odpowiedź, aby wskazać metodę, której użyłem. – Josh

3

Josh ma rację. Pobieranie śladów stosu jest bardzo kosztowne i należy ich unikać. Trudno jest dokładnie zrozumieć, co robisz, ale brzmi to raczej źle. Moją pierwszą propozycją byłoby przyjrzenie się Twojemu środowisku produkcyjnemu i zobaczenie, jakie usługi logowania są już dostępne i jak z nich korzystać.

Jeśli nie możesz, to będę szukał już dostępnych interfejsów API, takich jak Log4j, SLF4j i rejestracja Commons, aby zobaczyć, w jaki sposób możesz z nich korzystać. Wreszcie, jeśli nadal nie nadaje się do użytku, możesz przynajmniej spojrzeć na ich źródło, aby zobaczyć, jak one działają. Również źródło JUnit wykorzystuje analizę śladów, jeśli dobrze pamiętam, więc istnieje inne źródło pomysłów.

Ale moim ostatnim słowem byłoby zachować rzeczy tak proste, jak to możliwe. Nie omijaj tworzenia śladów stosu. Ogólnie rzecz biorąc, naprawdę martwisz się nimi tylko wtedy, gdy wystąpi wyjątek, a następnie zostanie Ci przekazany. Nie musisz nic robić, tylko przekazać dalej.

+0

Tak, używam log4net, które wciąż musisz przekazać informacje refleksyjne do, i chcę, aby rejestrator to obsłużyć. jednak +1 za wskazanie tego, co oczywiste, że przegapiłem! Dbaj tylko o to, jeśli to błąd, dobry punkt! – andy

Powiązane problemy