5

我使用以下类使用 log4net 打印出消息:

public class Message
{
    public String Text { get; set; }
    public int Id { get; set; }
    public override string ToString()
    {
        return Text;
    }
}

我使用Logger.Info(MessageInstance),所以 log4net 只是调用该ToString方法并打印出消息。我还想记录Id消息对象的属性,但我不知道如何实现这一点。

我的转换模式看起来与此类似:

<conversionPattern value="%date %-5level %message%newline" />

我尝试添加%message{Id},但这只会打印整个消息两次。

有什么建议么?

4

2 回答 2

3

我刚刚编写了一个自定义模式,它允许读取消息对象的属性。

public class ReflectionReader : PatternLayoutConverter
{
    public ReflectionReader()
    {
        _getValue = GetValueFirstTime;
    }

    protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
    {
        writer.Write(_getValue(loggingEvent.MessageObject));
    }

    private Func<object, String> _getValue;
    private string GetValueFirstTime(object source)
    {
        _targetProperty = source.GetType().GetProperty(Option);
        if (_targetProperty == null)
        {
            _getValue = x => "<NULL>";
        }
        else
        {
            _getValue = x => String.Format("{0}", _targetProperty.GetValue(x, null));
        }
        return _getValue(source);
    }

    private PropertyInfo _targetProperty;
}

结合这个:

public class ReflectionLayoutPattern : PatternLayout
{
    public ReflectionLayoutPattern()
    {
        this.AddConverter("item", typeof(ReflectionReader));
    }
}

配置如下所示:

<layout type="MyAssembly.MyNamespace.ReflectionLayoutPattern, MyAssembly">
  <conversionPattern value="[%item{Id}]&#9;%message%newline" />
</layout>
于 2013-04-04T11:47:08.923 回答
2

您可以使用派生自XmlLayoutBase的 CustomXmlLayout 类并覆盖 FormatXml 方法。此方法将 LoggingEvent 对象作为参数,该对象将包含传递给 log 方法的 MessageObject。

public class SpecialXmlLayout : XmlLayoutBase
{
    protected override void FormatXml(XmlWriter writer, LoggingEvent loggingEvent)
    {
        Message message = loggingEvent.MessageObject as Message;
        writer.WriteStartElement("LoggingEvent");
        writer.WriteElementString("Message", GetMessage(message));
        // ... write other things
        writer.WriteEndElement();
    }
}

在 GetMessaage 方法中,根据您的需要从消息中创建字符串。

然后在 log4net 配置中使用这个布局类:

<log4net>
    <appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">
      <applicationName value="My Application" />
      <layout type="Namespace.SpecialXmlLayout">
      </layout>
      <filter type="log4net.Filter.LevelRangeFilter">
        <param name="LevelMin" value="ERROR" />
        <param name="LevelMax" value="FATAL" />
      </filter>
    </appender>
</log4net>

这就是想法。有关更具体的详细信息,您必须查阅 log4Net SDK 文档。

于 2013-04-04T10:54:52.273 回答