Насколько я знаю, такая возможность не существует в log4net (или NLog в этом отношении). У меня есть идея, которая должна работать. Я не знаю, хорошая ли это идея или нет, я оставлю это на ваше усмотрение ...
Вкратце, вы могли бы написать собственный PatternLayoutConverter ( см. Этот пост для одного примера того, как это сделать ). Этот конвертер будет искать «контекст» в вашем собственном статическом словаре (аналогично контекстам статического словаря, которые уже есть у log4net). «Контекст» будет храниться по имени регистратора. Значение в словаре будет другой словарь, который будет содержать ваши переменные.
Это немного более сложный процесс, чем я сейчас собираюсь затронуть, но я постараюсь дать хороший псевдокод, чтобы показать, как он может работать ...
UPDATE:
Я добавил реализацию, которая работает (по крайней мере, в минимальном тестировании, которое я сделал). Я определил «контекст» для хранения пакета свойств для каждого регистратора. Я также реализовал PatternLayoutConverter для получения свойств для данного регистратора.
(Кажется, форматирование кода не учитывает отступы).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using log4net.Util;
using log4net.Layout.Pattern;
using log4net.Core;
namespace Log4NetTest
{
//
// Context container for loggers.
// Indexable by logger or logger name.
//
public interface IContext
{
IContextProperties this [ILog logger] { get; }
IContextProperties this [string name] { get; }
}
//
// Context properties for a specific logger.
//
public interface IContextProperties
{
object this [string key] { get; set; }
void Remove( string key );
void Clear( );
}
//
// Static class exposing the logger context container.
//
public static class LoggerProperties
{
private static readonly IContext context = new LoggerContext();
public static IContext Properties { get { return context; } }
}
internal class LoggerContext : IContext
{
private readonly IDictionary<string, IContextProperties> dict = new Dictionary<string, IContextProperties>();
#region IContext Members
//
// Get the properties asociated with this logger instance.
//
public IContextProperties this [ILog logger]
{
get
{
ILoggerWrapper w = logger as ILoggerWrapper;
ILogger i = w.Logger;
return this[i.Name];
}
}
//
// Get the properties associated with this logger name.
//
public IContextProperties this [string name]
{
get
{
lock (dict)
{
IContextProperties props;
if ( dict.TryGetValue( name, out props ) ) return props;
props = new LoggerContextProperties();
dict [name] = props;
return props;
}
}
}
#endregion
}
//
// Implementation of the logger instance properties.
//
internal class LoggerContextProperties : IContextProperties
{
private readonly IDictionary<string, object> loggerProperties = new Dictionary<string, object>();
#region IContextProperties Members
public object this [string key]
{
get
{
lock ( loggerProperties )
{
object value;
if ( loggerProperties.TryGetValue( key, out value ) ) return value;
return null;
}
}
set
{
lock ( loggerProperties )
{
loggerProperties [key] = value;
}
}
}
public void Remove( string key )
{
lock ( loggerProperties )
{
loggerProperties.Remove( key );
}
}
public void Clear( )
{
lock ( loggerProperties )
{
loggerProperties.Clear();
}
}
#endregion
}
public class LoggerContextPropertiesPatternConverter : PatternLayoutConverter
{
protected override void Convert( System.IO.TextWriter writer, LoggingEvent loggingEvent )
{
IContextProperties props = LoggerProperties.Properties[loggingEvent.LoggerName];
object value = props[Option];
if (value != null)
{
writer.Write(value);
}
else
{
writer.Write("{0}.{1} has no value", loggingEvent.LoggerName, Option);
}
}
}
}
Сконфигурируйте appender для использования PatternLayoutConverter:
<appender name="debug" type="log4net.Appender.DebugAppender">
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %logger %-5p [LOGPROP = %LOGPROP{test}] %m%n"/>
<converter>
<name value="LOGPROP" />
<type value="Log4NetTest.LoggerContextPropertiesPatternConverter" />
</converter>
</layout>
</appender>
Как установить свойства для логгера:
ILog loga = LogManager.GetLogger("A");
ILog logb = LogManager.GetLogger("B");
ILog logc = LogManager.GetLogger("C");
LoggerProperties.Properties[loga]["test"] = "abc";
LoggerProperties.Properties[logb]["test"] = "def";
LoggerProperties.Properties[logc]["test"] = "ghi";
loga.Debug("Hello from A");
logb.Debug("Hello from B");
logc.Debug("Hello from C");
Выход:
A: 2011-07-19 10:17:07,932 [1] A DEBUG [LOGPROP = abc] Hello from A
B: 2011-07-19 10:17:07,963 [1] B DEBUG [LOGPROP = def] Hello from B
C: 2011-07-19 10:17:07,963 [1] C DEBUG [LOGPROP = ghi] Hello from C
Удачи!