2010-06-08 3 views
5

Я пытаюсь реализовать собственный loglog loglog/logmanager, чтобы добавить новый уровень. Я также хочу иметь схему целевой таблицы (я использую AdoNetAppender и SQL Server 2008), чтобы иметь некоторые необязательные поля; например, уровень, который я добавляю, используется для отслеживания использования, а одно из полей должно быть продолжительностью (чтобы рассказать нам, сколько времени прошло). Однако другие уровни (INFO, DEBUG, FATAL и т. Д.) Не будут иметь значения для Duration. Поэтому мне нужно иметь возможность вставлять в таблицу не все поля, имеющие значения - желательно без необходимости повторного выполнения всех стандартных уровней регистрации, чтобы передать нулевое значение для нерелевантных полей. В идеале log4net автоматически передает NULL для значений свойств, которые он не может найти для конкретного события регистрации.log4net пользовательские свойства не работают

Код в моем пользовательском регистратор выглядит следующим образом:

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); 
     } 
    } 

(присвоения DBNull.Value были добавлены в надежде, что это будет способствовать Log4Net пассу аннулирует, когда значение не было принято, но я надеюсь, что они могут быть удалены).

Appender конфигурации выглядит следующим образом:

<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> 

Когда я пытаюсь что-то войти с моей пользовательской точки зрения, это работает только, если я прохожу в продолжительности, STARTTIME и Конечное время. Для всего остального - включая уровни по умолчанию - он, кажется, терпит неудачу, без каких-либо подсказок в окне вывода (хотя регистрация с уровнями по умолчанию генерирует исключения, говорящие, что он не может преобразовать String в DateTime или Double).

Любая причина, по которой кто-нибудь может понять, почему это не так тихо?

ответ

7

Я, наконец, понял это, проследив через некоторый источник log4net. Проблема заключалась в том, что я использовал PatternLayout для рендеринга пользовательских параметров. Этот макет заставляет null строке "(null)", что вызывает проблемы, если вы пытаетесь вставить ее в, скажем, поле с нулевым значением datetime в таблице. Решение прост: вместо использования макета PatternLayout используйте log4net.Layout.RawPropertyLayout. Это передаст свойство null как null, которое вы хотите.

+0

должен был использовать его следующим образом: new RawPropertyLayout {Key = propertyName} – xhafan

Смежные вопросы