2012-09-08 12 views
7

Próbuję napisać kod C#, który pobiera w czasie wykonywania wzorzec nazwy pliku logu log4net za pośrednictwem interfejsu API log4net.Jak programowo uzyskać wzorzec nazwy pliku log4net?

Oznacza to, że jeśli w log4net.config następujące appender jest zdefiniowana:

<appender name="MyAppender" type="log4net.Appender.RollingFileAppender"> 
    <file type="log4net.Util.PatternString" value="%date{yyyy}\%date{MM}\%date{dd}\%property{Id}.log" /> 
    <appendToFile value="true" /> 
    <rollingStyle value="Size" /> 
    <maxSizeRollBackups value="16" /> 
    <maximumFileSize value="1MB" /> 
    <staticLogFileName value="true" /> 
    <layout type="log4net.Layout.PatternLayout"> 
    <conversionPattern value="%message%newline" /> 
    </layout> 
</appender> 

Chciałbym dostać datę% {RRRR} \% date {MM} \% date} {dd \% właściwość {Id} .log w zmiennej łańcuchowej w kodzie (bez analizowania log4net.config jako zwykły XML).

Czy ktoś ma pomysł, aby wyciągnąć tę sztuczkę?

Z góry dziękuję.

Odpowiedz

2

Wartość tego wzorca będzie w postaci File instancji FileAppender, która jest częścią repozytorium rejestrowania.

Dojście do aplikanta można wykonać na kilka różnych sposobów.

  1. Jeśli masz już instancję ILogger (np co można uzyskać z LogManager.GetLogger()) potem jest właściwością Appenders na nim. W ten sposób otrzymasz wszystkie dodatki związane z tym konkretnym poziomem heurystyki logowania.
  2. Można również zadzwonić pod numer LogManager.GetRepository(), aby uzyskać obiekt Heirarchy zawierający całą dziedziczenie rejestratora i nadawcy. Metoda oczekuje złożenia, więc przeprowadź GetCallingAssembly(), aby uzyskać domyślny. Ta klasa ma metodę GetAppenders(), która zwraca wszystkich skonfigurowanych aplikacji, ale nie informuje, które z nich są powiązane z tymi rejestratorami.

Stamtąd, po prostu przejrzeć szuka appender prawidłowego typu (np FileAppender lub RollingFileAppender), a następnie odczytać to File nieruchomość.

+2

myślę, że nie działa. Właściwość pliku jest już oceniona w tym punkcie. Więc nie będzie już zawierać "% date {rrrr} \% date {MM} \% date {dd} ...", ale "2012 \ 09 \ ...". – Wolfgang

+0

@Michael Wolfgang ma absolutną rację: po pobraniu właściwość _File_ została już oceniona i nie mogłem uzyskać oryginalnej wartości wzorca. – Lev

+0

hrm. masz rację, zawsze używałem tego, aby po prostu uzyskać ścieżkę (której zazwyczaj nie deserujemy) i nigdy nie zauważyliśmy. Te dane muszą być dostępne gdzieś, ponieważ wzorzec jest ponownie obliczany w pewnym momencie, pozwól mi sięgnąć głębiej. –

0

Myślę, że chcesz podklasować RollingFileAppender i użyć swojej podklasy w pliku konfiguracyjnym zamiast w klasie bazowej. Pamiętaj, aby poprzedzić nazwę klasy pełnym obszarem nazw, aby log4net mógł go znaleźć.

Mam tylko podklasę UDPAppender w moim kodzie. Dodałem nadpisanie takiego:

public override void ActivateOptions() 
    { 
     base.ActivateOptions(); 
    } 

Kiedy wybuchła przed wywołaniem klasy bazowej, badałem „to” w oknie mieszkańców i zobaczyłem wartości dla członków „” THE UDPAppender.

+0

Niestety, instancja _RollingFileAppender_ jest już ustawiona z ocenianą nazwą pliku i nie jest świadoma wzorca nazwy pliku. Domyślam się, że ostatnim obiektem, który widzi ten wzorzec, jest instancja _log4net.Repository.Hierarchy.XmlHierarchyConfigurator_ w metodzie _ParseAppender() _. W takim przypadku jedynym sposobem na osiągnięcie tego, czego potrzebuję, jest samodzielne przeanalizowanie pliku konfiguracyjnego na własną rękę (fuj!) ... – Lev

+0

Och, źle to zrozumiałem. Chcesz sam wzór. Przypuszczam, że ktoś może zmienić wzorzec, a więc nie chcesz go ustawiać za pomocą kodu (tak byś wiedział o tym wcześniej)? – chrismead

0

Wyjaśnienie Michaela Edenfielda jest dobre. Oto realizacja.

private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 

string fileName = ((RollingFileAppender)log.Logger.Repository.GetCurrentLoggers() 
    .Where(e => e.Name == "Your namespace.class").ToList()[0] 
    .Repository.GetAppenders() 
    .Where(e => e.Name == "MyAppender").ToList()[0]).File.ToString(); 
0

mogę uzyskać wartość <file value> z następującego kodu:

((log4net.Appender.FileAppender) ((log4net.Appender.IAppender[]) 
      ((log4net.Repository.Hierarchy.Logger) 
       log.Logger).Appenders.SyncRoot)[0]).File 
Powiązane problemy