2016-04-17 8 views
1

Ich habe eine Anwendung, mit mehreren Teilen.Wie sollte log4net die "Quelle" für einen "EventLogAppender" in der Anwendung RICHTIG einstellen ...?

Ich benutze log4net durchweg, um Ereignisse zu protokollieren, und ich möchte, dass diese Ereignisse eine QUELLE haben, die WHERE in der Anwendung entspricht, von der sie kamen (du weißt wie "SOURCE" impliziert). Also habe ich ein Protokoll unter "Anwendungs- und Dienstprotokolle" und log4net wie erwartet eingerichtet.

enter image description here

Im log4net Konfiguration hat ein Element „applicationname“, die den in die Dokumentation nach gibt „Den Namen des Protokolls des Nachricht gespeichert werden.“

Das Beispiel aus der Dokumentation zeigt

<applicationName value="MyApp" /> 

Log4Net den Wert von „application“ verwendet, um Ereignisse zu protokollieren. Laut den Dokumenten im log4net-Quellcode sollte die "ApplicationName-Eigenschaft verwendet werden, um Ereignisse zu unterscheiden".

Also unter der Annahme, LogName richtig eingestellt ist, würde ich erwarten, meine "LogName" unter "Anwendungen und Dienste Protokolle" in der Ereignisanzeige, und dann muss ich nur die applicationName, um die Quelle richtig zu bekommen. Allerdings scheint der Anwendungsname nur in der Konfiguration festgelegt werden ... Aber das bedeutet, dass alle Ereignisse unter der gleichen Quelle protokollieren:

enter image description here

Wie soll der Name der Quelle gesetzt werden ...? Gibt es einen alternativen Weg, dies zu tun?

Antwort

1

Ich habe keine Antwort gefunden, also habe ich die Quelle für log4net heruntergeladen und entschieden, es herauszufinden.

Das folgende Codefragment setzt den Anwendungsnamen in log4net

private static void SetEventSource(string sourceName) 
    { 
     var repository = LogManager.GetRepository(); 
     if (repository != null) 
     { 
      var appender = repository.GetAppenders().Where(x => x.Name == "eventLogAppender").FirstOrDefault(); 
      if (appender is log4net.Appender.EventLogAppender) 
      { 
       var eventAppender = (log4net.Appender.EventLogAppender)appender; 
       eventAppender.ApplicationName = sourceName; 
       eventAppender.ActivateOptions(); 
      } 
     } 
    } 

Ich habe eine Aufzählung von „LoggingSources“, so dass ich durch diesen nur Schleife, wenn die Anwendung gestartet wird, um sicherzustellen, dass die Protokollquelle vorhanden ist.

public static void ConfigureWindowsEvents() 
    { 
     // Create event log sources for each of our Logging types 
     var loggingEvents = Enum.GetValues(typeof(LoggingSources)); 
     foreach (var item in loggingSources) 
     { 
      string source = item.ToString(); 

      if (!EventLog.SourceExists(source)) 
      { 
       EventLog.CreateEventSource(source, EVENT_LOG_NAME); 
      } 
     } 
    } 

Und dann, wenn ich ein Ereignis protokollieren ich die Quelle gesetzt, und Ereignis-ID

public static void SetThreadContextAndLog(LoggingSources eventId, Action logAction) 
    { 
     if (logAction != null) 
     { 
      log4net.ThreadContext.Properties[EVENT_ID_KEY] = (int)eventId; 
      try 
      { 
       SetEventSource(eventId.ToString()); 
       logAction(); 
      } 
      finally 
      { 
       log4net.ThreadContext.Properties[EVENT_ID_KEY] = DEFAULT_EVENT_ID; 
      } 
     } 
    } 

Aufruf der Methode wie folgt ...

public static void LogEvent(LoggingSources pEvent, string pMessage, EventLogEntryType pEventType) 
    { 
     SetThreadContextAndLog(pEvent,() => 
     { 
      if (pEventType == EventLogEntryType.Warning) 
      { 
       Log.Warn(pMessage); 
      } 
     }); 
    } 

Dies führt zu der Quelle und Ereignis-ID wird korrekt eingestellt ...

enter image description here

Es ist ein bisschen eine Faff, aber ich kann nicht eine bessere Möglichkeit sehen, die Protokollquelle zu setzen, ohne einen benutzerdefinierten Appender ...