Настраиваемое свойство log4net PatternLayoutConverter (с индексом)
Можно ли создать собственный шаблон 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>