【问题标题】:Custom log4net property PatternLayoutConverter (with index)自定义 log4net 属性 PatternLayoutConverter(带索引)
【发布时间】:2011-04-27 02:01:04
【问题描述】:

是否可以创建一个允许配置“索引”值的 log4net 自定义 PatternLayoutConverter?我知道允许您编写如下代码的“属性”转换字符串:

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}"/>

在这个例子中,我实际上使用 NLog 的 GDC 对象作为我的“字典”,但我展示了如何编写自己的“可索引”LayoutRenderer(或多或少相当于 log4net 的 PatternLayoutConverter)来访问由索引的值配置文件中的值。

[编辑] 我得到了我想要的答案。我在这里包含了我的示例 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>

【问题讨论】:

    标签: logging log4net nlog


    【解决方案1】:

    我没有尝试过,但这应该可以。在 log4net 中,您可以像这样将选项字符串传递给模式转换器:

    %converterName{converterOptions}
    

    例如,日期模式转换器可以这样使用:

    %date{HH:mm:ss,fff}
    

    这意味着您可以按照建议的方式编写模式转换器。可以在here 中找到此类转换器的简单示例。

    Convert 方法中,您可以使用属性'Option'(在PatternConverter 类中定义)访问属性字符串,并使用线程上下文从字典中获取所需的条目。如果您的选项包含的不仅仅是字典键,您还可以实现 IOptionHandler 接口:这样您就可以在激活 log4net 配置时解析选项。

    【讨论】:

    • 谢谢!这正是我想做的。我会将我的测试 LayoutPatternConverter 添加到我的问题中以供参考,以防其他人感兴趣。
    猜你喜欢
    • 2011-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-08
    • 1970-01-01
    相关资源
    最近更新 更多