代码之家  ›  专栏  ›  技术社区  ›  wageoghe

自定义log4net属性PatternLayoutConverter(带索引)

  •  5
  • wageoghe  · 技术社区  · 14 年前

    是否可以创建允许配置“索引”值的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>
    

    在布局中使用“索引”属性:

      <layout="${longdate} | ${MyGDC:item=name} | ${message}"/>
    

    在这个例子中,我实际上使用nlog的gdc对象作为我的“字典”,但是我演示了如何编写自己的“可索引”布局呈现器(或多或少相当于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>
    
    1 回复  |  直到 14 年前
        1
  •  5
  •   Community taleinat    7 年前

    我没试过,但这应该管用。在log4net中,可以将选项字符串传递给模式转换器,如下所示:

    %converterName{converterOptions}
    

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

    %date{HH:mm:ss,fff}
    

    这意味着您可以按照您建议的方式编写模式转换器。可以找到这样一个转换器的简单示例 here .

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