【问题标题】:log4net AppenderSkeleton ignores PatternLayoutlog4net AppenderSkeleton 忽略 PatternLayout
【发布时间】:2015-03-23 11:39:07
【问题描述】:

我用 log4net 创建了自己的 Appender,

 public class TextBoxAppender : AppenderSkeleton
{
      ...(constructor and other stuff omitted)...

        protected override void Append(log4net.Core.LoggingEvent loggingEvent)
        {
              var msg = string.Concat(loggingEvent.RenderedMessage, "\r\n");

              _textBox.AppendText(s);

        }

}

我的 App.config 有一个我想使用的 PatternLayout,

 <appender name="TextBoxAppender" type="log4netAppender.TextBoxAppender">
      <root>
        <level value="DEBUG">
          <appender-ref ref="TextBoxAppender">
          </appender-ref>
        </level>
      </root>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date{dd MMM yyyy HH:mm:ss} %level - %message%newline%exception%newline" />
      </layout>
    </appender>

loggingEvent.RenderedMessage 没有给我用 PatternLayout 格式化的字符串。

我看到 AppendSkeleton 有这个签名

public virtual ILayout Layout { get; set; }

但我不想编写自己的布局,我想使用其他 Appender 使用的“标准”布局...

有人知道吗?非常感谢

提示:也许这样我们可以访问其他现有记录器的渲染器?

var hierarchy = (Hierarchy)LogManager.GetRepository();
hierarchy.RendererMap .....

解决方案

在Append()中,在RenderLoggingEvent之前,设置Layout,否则为null。

this.Layout = new log4net.Layout.PatternLayout("%date{dd MMM yyyy HH:mm:ss} %level - %message");
string msg = base.RenderLoggingEvent(loggingEvent);

【问题讨论】:

    标签: c# log4net log4net-appender


    【解决方案1】:

    调用基本方法 RenderLoggingEvent 以根据您的游览布局编写您的事件。例如这里是TraceAppender中的Append方法

    // log4net.Appender.TraceAppender
    protected override void Append(LoggingEvent loggingEvent)
    {
        Trace.Write(base.RenderLoggingEvent(loggingEvent), this.m_category.Format(loggingEvent));
        if (this.m_immediateFlush)
        {
            Trace.Flush();
        }
    }
    

    所以在你的情况下:

    public class TextBoxAppender : AppenderSkeleton
    {
        ...(constructor and other stuff omitted)...
        protected override void Append(log4net.Core.LoggingEvent loggingEvent)
        {
            // format your message in the layout, not here
            // var msg = string.Concat(loggingEvent.RenderedMessage, "\r\n");
            _textBox.AppendText(base.RenderLoggingEvent(loggingEvent));
        }
    }
    

    【讨论】:

    • 好吧,虽然这对我有所帮助,但 RenderLoggingEvent() 会抛出异常“必须设置布局”,这又回到了我遇到的问题。我是否需要编码 %newline 是 write("\n") 等等...?
    • 这是 RenderLoggingEvent 方法中的第一个检查。你在构造函数中初始化你的布局吗?
    • 不,我没有初始化任何布局。我想重用另一个附加程序的布局。因为我不想做一些特别的事情,只是典型的带有 %date %level %exception 的 PatternLayout ...
    • 您可以尝试在构造函数中将布局分配给新布局吗?显然,这是推荐给其他 appender 的
    【解决方案2】:

    您应该使用 textBox.BeginInvoke 而不是 textBox.Invoke 或 textBox.AppendText 以实现线程安全。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多