Pytasz, jak to zrobić za pomocą atrybutu. @ Sugestia Jonathana wygląda na to, że prawdopodobnie będzie dobrze działać, ale możesz osiągnąć dobry wynik dzięki wykorzystaniu wbudowanych funkcji log4net.
Jeśli chcesz pogrupować klasy w "kategorie", możesz pobrać program rejestrujący na podstawie nazwy kategorii, a nie nazwy klasy. Po skonfigurowaniu formatu wyjściowego można użyć tokenu formatowania rejestratora, aby log4net zapisał nazwę rejestratora w danych wyjściowych.
Zazwyczaj można by odzyskać rejestratora na podstawie nazwy klasy, jak to:
public class Typical
{
private static readonly ILog logger =
LogManager.GetLogger
(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public void F()
{
logger.Info("this message will be tagged with the classname");
}
}
jest całkowicie dopuszczalne, aby odzyskać rejestratory podstawie arbitralnej nazwą jak to:
public class A
{
private static readonly ILog logger = LogManager.GetLogger("REF");
public void F()
{
logger.Info("this message will be tagged with REF");
}
}
public class B
{
private static readonly ILog logger = LogManager.GetLogger("REF");
public void F()
{
logger.Info("this message will be tagged with REF");
}
}
public class C
{
private static readonly ILog logger = LogManager.GetLogger("UMP");
public void F()
{
logger.Info("this message will be tagged with UMP");
}
}
W poprzednim przykładzie , klasy A i B są uważane za znajdujące się w tej samej "kategorii", więc odzyskały program rejestrujący o tej samej nazwie. Klasa C jest w innej kategorii, więc odzyskała rejestrator o innej nazwie.
Można skonfigurować rejestratory (w pliku config) z własnym „kategorii” hierarchii:
App
App.DataAccess
App.DataAccess.Create
App.DataAccess.Read
App.DataAccess.Update
App.DataAccess.Delete
App.UI
App.UI.Login
App.UI.Query
App.UI.Options
Można również skonfigurować format wyjściowy Rejestrator zalogować tylko część w pełni kwalifikowanej nazwy rejestratora. Coś takiego:
%logger:2
Aby uzyskać 2 ostatnie części pełnej nazwy.Na przykład, jeśli nazwa w pełni kwalifikowana klasie jest:
NameSpaceA.NameSpaceB.NameSpaceC.Class
Wtedy powyżej Format byłoby wyjście to jak nazwa Rejestrator:
NameSpaceC.Class
nie jestem 100% pewny o składni bo Haven” Użyłem tego i nie mogę znaleźć dobrego przykładu w tej chwili.
Jedną wadą tego podejścia jest to, że musisz zdefiniować i zapamiętać, jakie są twoje kategorie i musisz zdecydować, jaka kategoria jest dla każdej klasy (masz również ten problem, jeśli chcesz ozdobić każdą klasę atrybutem zawierającym jego kategoria). Ponadto, jeśli masz kilka klas w tej samej kategorii, nie możesz włączyć ani wyłączyć logowania ani zmienić poziomu rejestrowania dla podzbioru tych klas.
Może warto byłoby, aby zalogować jeden z nazw w hierarchii przestrzeni nazw:
Może ty „kategoryzacji” swoje klasy na podstawie ich nazw. Tak więc możesz chcieć zarejestrować bezpośrednią macierzystą przestrzeń nazw klasy jako jej kategorię.
Tak więc, dla w pełni kwalifikowanej nazwy klasy powyżej, możesz chcieć zarejestrować "NameSpaceC" jako "kategorię" lub nazwę rejestratora.
Nie jestem pewien, czy można to zrobić po wyjęciu z pudełka z log4net, ale można łatwo napisać PatternLayoutConverter, aby uzyskać nazwę rejestratora i usunąć nazwę klasy i wszelkie przestrzenie nazw "wyższego poziomu".
Oto link do przykładu niestandardowego PatternLayoutConverter. Pobiera parametr, który w moim przypadku chciałbym użyć do wyszukania wartości w słowniku. W tym przypadku parametr mógłby reprezentować przesunięcie od END w pełni kwalifikowanej nazwy rejestratora (taka sama interpretacja jak parametr wbudowanego obiektu układu logger nazwa wbudowanego log4net), ale można dodać dodatkowy kod, aby logować TYLKO pojedynczą przestrzeń nazw w tym indeks.
Custom log4net property PatternLayoutConverter (with index)
Ponownie, biorąc pod uwagę to pełną nazwę klasy:
NameSpaceA.NameSpaceB.NameSpaceC.Class
Można rozważyć natychmiastowe nazw rodzic być "kategoria". Jeśli zdefiniowano niestandardowy PatternLayoutConverter, category
i zajęło to parametr, a następnie konfiguracja może wyglądać następująco:
%category
Domyślnie byłoby zwrócić podciąg między ostatnim a przedostatnim '.'
znaków. Podany parametr może zwrócić dowolną dyskretną przestrzeń nazw w górę łańcucha.
PatternLayoutConverter może wyglądać mniej więcej tak (niesprawdzone):
class CategoryLookupPatternConverter : PatternLayoutConverter
{
protected override void Convert(System.IO.TextWriter writer, LoggingEvent loggingEvent)
{
//Assumes logger name is fully qualified classname. Need smarter code to handle
//arbitrary logger names.
string [] names = loggingEvent.LoggerName.Split('.');
string cat = names[names.Length - 1];
writer.Write(setting);
}
}
Albo, używając właściwości Option, aby uzyskać n-tej nazwy przestrzeni nazw (w stosunku do końca):
class CategoryLookupPatternConverter : PatternLayoutConverter
{
protected override void Convert(System.IO.TextWriter writer, LoggingEvent loggingEvent)
{
//Assumes logger name is fully qualified classname. Need smarter code to handle
//arbitrary logger names.
string [] names = loggingEvent.LoggerName.Split('.');
string cat;
if (Option > 0 && Option < names.Length)
{
cat = names[names.Length - Option];
}
else
{
string cat = names[names.Length - 1];
}
writer.Write(setting);
}
}
Pomysł z @ Jonathan jest całkiem fajny, ale dodaje trochę dodatkowego kodowania z twojej strony, aby zdefiniować i utrzymać nowe opakowanie loggera (ale wiele osób robi to i nie uważa tego za szczególnie uciążliwe obciążenie). Oczywiście, moje niestandardowe pomysły PatternLayoutConverter wymagają również niestandardowego kodu z Twojej strony.
Kolejną wadą jest to, że GetCategory wygląda tak, że wywołanie każdego połączenia rejestracyjnego może być dość kosztowne.
log4net przy użyciu hierarchii rejestratorów dla takiej cechy –
Jaka jest kategoria faktycznie reprezentująca, tj. W jaki sposób obiekty logujące się do tej samej kategorii będą powiązane? Teoretycznie możesz zrobić to wszystko w config przez powiązania między rejestratorami i aplikantami, które odpowiadają każdej kategorii, np. Wszystkie logowania z obiektów w przestrzeniach nazw X, Y i Z używają aplikacji dostarczającej reprezentującej kategorię A. Jednak w zależności od odpowiedzi na moje pierwsze pytanie, które może stać się uciążliwe. –
Co staram się tutaj osiągnąć, to aby pliki dziennika były łatwiejsze do analizowania, gdy są używane w określonych klasach. Na przykład, jeśli klasa A i klasa B są ze sobą powiązane i chciałbym szczególnie, aby wszystkie linie powiązane z klasami A i B zostały usunięte z głównego pliku dziennika. Moje doświadczenie, które zwykle znajdowałem w ten sposób, było dla mnie bardzo pomocne. – tonyjy