2010-06-08 20 views
5

Ich versuche, eine benutzerdefinierte log4net Logger/Logmanager zu implementieren, so dass ich eine neue Ebene hinzufügen kann. Ich möchte auch das Schema der Zieltabelle haben (ich verwende einen AdoNetAppender und SQL Server 2008), um einige optionale Felder zu haben; Zum Beispiel wird die Ebene, die ich hinzufüge, verwendet, um die Verwendung zu verfolgen, und eines der Felder muss eine Dauer sein (um zu sagen, wie lange etwas gedauert hat). Andere Ebenen (INFO, DEBUG, FATAL usw.) haben jedoch keinen Wert für die Dauer. Ich muss also in der Lage sein, in die Tabelle mit nicht allen Feldern, die Werte enthalten, einzufügen - vorzugsweise ohne alle Standardniveaus neu zu protokollieren, um zu protokollieren, um einen Nullwert für die irrelevanten Felder zu übergeben. Im Idealfall würde log4net automatisch NULL für Eigenschaftswerte übergeben, die für ein bestimmtes Protokollierungsereignis nicht gefunden werden können.Log4net benutzerdefinierte Eigenschaften nicht funktioniert

Der Code in meinem benutzerdefinierten Logger ist wie folgt:

public void Usage(TimeSpan? duration, DateTime? startTime, DateTime? endTime, string message) 
    { 
     if (IsUsageEnabled) 
     { 
      LoggingEvent loggingEvent = new LoggingEvent(GetType(), Logger.Repository, Logger.Name, _currentUsageLevel, 
       message, null); 
      if (startTime.HasValue) 
      { 
       loggingEvent.Properties["StartTime"] = startTime.Value; 
      } 
      else 
      { 
       loggingEvent.Properties["StartTime"] = DBNull.Value; 
      } 

      if (endTime.HasValue) 
      { 
       loggingEvent.Properties["EndTime"] = endTime.Value; 
      } 
      else 
      { 
       loggingEvent.Properties["EndTime"] = DBNull.Value; 
      } 

      if (duration.HasValue) 
      { 
       loggingEvent.Properties["Duration"] = duration.Value.TotalMilliseconds; 
      } 
      else 
      { 
       loggingEvent.Properties["Duration"] = DBNull.Value; 
      } 

      Logger.Log(loggingEvent); 
     } 
    } 

(die Zuordnungen zu DBNull.Value wurden in der Hoffnung, fügt hinzu, dass der log4net Pass nulls helfen würde, wenn der Wert nicht übergeben wurde, aber ich hoffe, dass sie kann entfernt werden).

Die appender Config ist wie folgt:

<appender name="SQLAppender" type="log4net.Appender.AdoNetAppender"> 
    <bufferSize value="1" /> 
    <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> 
    <connectionString value="my connection string (which actually gets replaced at runtime with a connection string retrieved from a config database)" /> 
    <commandText value="INSERT INTO MyTable ([Date],[Thread],[Level],[Logger],[Message],[Exception], [Login], [StartTime], [EndTime], [Duration]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception, @login, @start_time, @end_time, @duration)" /> 
    <parameter> 
    <parameterName value="@log_date" /> 
    <dbType value="DateTime" /> 
    <layout type="log4net.Layout.RawTimeStampLayout" /> 
    </parameter> 
    <parameter> 
    <parameterName value="@thread" /> 
    <dbType value="String" /> 
    <size value="255" /> 
    <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%thread" /> 
    </layout> 
    </parameter> 
    <parameter> 
    <parameterName value="@log_level" /> 
    <dbType value="String" /> 
    <size value="50" /> 
    <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%level" /> 
    </layout> 
    </parameter> 
    <parameter> 
    <parameterName value="@logger" /> 
    <dbType value="String" /> 
    <size value="255" /> 
    <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%logger" /> 
    </layout> 
    </parameter> 
    <parameter> 
    <parameterName value="@message" /> 
    <dbType value="String" /> 
    <size value="4000" /> 
    <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%message" /> 
    </layout> 
    </parameter> 
    <parameter> 
    <parameterName value="@exception" /> 
    <dbType value="String" /> 
    <size value="4000" /> 
    <layout type="log4net.Layout.ExceptionLayout" /> 
    </parameter> 
    <parameter> 
    <parameterName value="@login" /> 
    <dbType value="String" /> 
    <size value="255" /> 
    <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%property{CurrentLogin}" /> 
    </layout> 
    </parameter> 
    <parameter> 
    <parameterName value="@start_time" /> 
    <dbType value="DateTime" /> 
    <layout type="log4net.Layout.PatternLayout" 
     value="%property{StartTime}" /> 
    </parameter> 
    <parameter> 
    <parameterName value="@end_time" /> 
    <dbType value="DateTime" /> 
    <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%property{EndTime}" /> 
    </layout> 
    </parameter><parameter> 
    <parameterName value="@duration" /> 
    <dbType value="Double" /> 
    <layout type="log4net.Layout.PatternLayout"> 
     <conversionPattern value="%property{Duration}" /> 
    </layout> 
    </parameter> 
</appender> 

Wenn ich versuche, etwas mit meiner benutzerdefinierten Ebene anzumelden, es funktioniert nur, wenn ich in der Dauer, Startzeit und Endzeit passieren. Für alles andere - einschließlich der Standardstufen - scheint es im Hintergrund zu versagen, ohne Hinweise im Ausgabefenster (obwohl die Protokollierung mit Standardstufen Ausnahmen auslöst, die angeben, dass String nicht in DateTime oder Double konvertiert werden kann).

Gibt es irgendeinen Grund, warum irgendjemand sehen könnte, warum dies so still stünde?

Antwort

7

Ich habe es endlich herausgefunden, nachdem ich einige log4net-Quellen verfolgt habe. Das Problem war, dass ich ein PatternLayout zum Rendern der benutzerdefinierten Parameter verwendete. Dieses Layout erzwingt null auf die Zeichenfolge "(null)", die Probleme verursacht, wenn Sie versuchen, es beispielsweise in ein Nullable datetime Feld in der Tabelle einzufügen. Die Lösung ist einfach: Anstatt das PatternLayout-Layout zu verwenden, verwenden Sie log4net.Layout.RawPropertyLayout. Dies wird eine Null-Eigenschaft als null übergeben, was Sie wollen.

+0

musste es wie folgt verwenden: new RawPropertyLayout {Key = propertyName} – xhafan

Verwandte Themen