Настраиваемое свойство log4net PatternLayoutConverter (с индексом) - PullRequest
5 голосов
/ 18 октября 2010

Можно ли создать собственный шаблон PatternLayoutConverter log4net, который позволяет настраивать значение индекса?Я знаю о строке преобразования "property", которая позволяет вам писать код следующим образом:

ThreadContext.Properties["ID"] = yourID;

И указывать так:

%property{ID} 

что значение должно быть включено в вывод.

Что если значения, которые я хочу записать, находятся в каком-то другом «словаре»?Я полагаю, что я мог бы написать некоторую логику для копирования этих значений из словаря в один из контекстов log4net, а затем просто использовать встроенный токен %property.Что если я хочу, чтобы log4net регистрировал значения непосредственно из моего «словаря» на основе значения индекса, указанного в файле конфигурации?

Могу ли я написать свой собственный PatternLayoutConverter, который позволил бы мне настроить что-то вроде этого:

%myproperty{ID}

А затем вытащить соответствующее значение "ID" из моего собственного "словаря"?

Для всех, кто интересуется, довольно легко сделать то же самое с NLog:

  [LayoutRenderer("MyGDC")]
  class GdcLayoutRenderer : LayoutRenderer
  {
    [RequiredParameter]
    [DefaultParameter]
    public string Item { get; set; }

    protected override void Append(StringBuilder builder, LogEventInfo logEvent)
    {
      string msg = GDC.Get(this.Item);
      builder.Append(msg);
    }

    protected override int GetEstimatedBufferSize(LogEventInfo logEvent)
    {
      return 10;
    }
  }

И настроен так:

Скажите NLog о любых сборках с расширениями:

  <extensions>
    <add assembly="NLog.Extensions"/>
  </extensions>

Используйте свойство "indexed" в макете:

  <layout="${longdate} | ${MyGDC:item=name} | ${message}"/>

В этом примере я на самом деле использую объект GDC NLog в качестве своего «словаря», но я демонстрирую, как я смог написать свой собственный «индексируемый» LayoutRenderer (более или менее эквивалентный PatternLayoutConverter log4net) для доступа к индексируемому значениюпо значению в файле конфигурации.

[РЕДАКТИРОВАТЬ] Я получил ответ, который я хотел.Я включил код для моего образца PatternLayoutRenderer здесь.В моем тесте у меня есть статический словарь в моем основном классе формы, где я могу хранить «настройки приложения».Я создал PatternLayoutConverter, который может принимать ключ в качестве параметра, чтобы преобразователь мог найти правильное значение в словаре.Я мог бы достичь той же функциональности, используя объекты контекста log4net (или NLog), но в нашем приложении у нас могут быть некоторые настройки или информация о сеансе, которые приложение будет хранить для других целей, и мы хотим иметь возможность добавить это крегистрация выходных данных.Поскольку он уже будет иметь структуру поиска, было бы неплохо иметь возможность ссылаться на данные напрямую, а не копировать их явно в log4net (или контекст NLog).

В любом случае, вот код:

namespace Log4NetTest
{
  class KeyLookupPatternConverter : PatternLayoutConverter
  {
    protected override void Convert(System.IO.TextWriter writer, LoggingEvent loggingEvent)
    {
      //Use the value in Option as a key into the "application settings" stored on the main form.
      string setting;
      if (Form1.AppSettings.TryGetValue(Option, out setting))
      {
        writer.Write(setting);
      }
    }
  }
}

Конфигурация макета:

  //Log the "sessionid" and "userid" values from our "application settings" object
  <layout type="log4net.Layout.PatternLayout">
    <param name="ConversionPattern" value="%d [%t] %-5p [session = %KLPC{sessionid}] [user = %KLPC{userid}] %m%n"/>
    <converter>
      <name value="KLPC" />
      <type value="Log4NetTest.KeyLookupPatternConverter" />
    </converter>
  </layout>

1 Ответ

5 голосов
/ 19 октября 2010

Я не пробовал, но это должно работать. В log4net вы можете передать строку параметров в конвертер шаблонов следующим образом:

%converterName{converterOptions}

Например, конвертер шаблонов даты можно использовать так:

%date{HH:mm:ss,fff}

Это означает, что вы можете написать свой конвертер шаблонов так, как вы предлагали. Простой пример такого преобразователя можно найти здесь .

В методе Convert вы можете получить доступ к строке свойства со свойством 'Option' (определенным в классе PatternConverter) и использовать контекст потока, чтобы получить нужную запись из словаря. Вы также можете реализовать интерфейс IOptionHandler, если ваши параметры состоят не только из словарного ключа: таким образом, вы можете анализировать параметры при активации конфигурации log4net.

...