自定义 log4net 属性 PatternLayoutConverter(带索引) [英] Custom log4net property PatternLayoutConverter (with index)

查看:24
本文介绍了自定义 log4net 属性 PatternLayoutConverter(带索引)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it possible to create a log4net custom PatternLayoutConverter that allows an "index" value to be configured? I know about the "property" conversion string that allows you to write code like this:

ThreadContext.Properties["ID"] = yourID;

并指定如下:

%property{ID} 

该值应包含在输出中.

如果我想记录的值在其他字典"中怎么办?我想我可以编写一些逻辑来将这些值从字典复制到 log4net 上下文之一,然后只使用内置的 %property 标记.如果我希望 log4net 根据配置文件中指定的索引值直接从我自己的字典"中记录值怎么办?

What if the values I want to log are in some other "dictionary"? I suppose that I could write some logic to copy those values from the dictionary to one of the log4net contexts and then just use the built in %property token. What if I want log4net to log the values directly from my own "dictionary" based on an index value specified in the config file?

我可以编写自己的 PatternLayoutConverter 来配置如下内容吗:

Can I write my own PatternLayoutConverter that would allow me to configure something like this:

%myproperty{ID}

然后从我自己的字典"中拉取对应的ID"值?

And then pull the corresponding "ID" value from my own "dictionary"?

对于任何有兴趣的人来说,用 NLog 做同样的事情是很容易的:

For anyone that is interested, it is pretty easy to do the same thing with 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 任何带有扩展的程序集:

Tell NLog about any assemblies with extensions:

  <extensions>
    <add assembly="NLog.Extensions"/>
  </extensions>

在布局中使用索引"属性:

Use the "indexed" property in a layout:

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

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

In this example I am actually using NLog's GDC object as my "dictionary", but I am demonstrating how I was able to write my own "indexable" LayoutRenderer (more or less equivalent to log4net's PatternLayoutConverter) to access a value indexed by a value in the config file.

我得到了我想要的答案.我在此处包含了我的示例 PatternLayoutRenderer 的代码.在我的测试中,我的主表单类中有一个静态字典,我可以在其中存储应用程序设置".我创建了一个 PatternLayoutConverter,它可以接受一个键作为参数,以便转换器可以在字典中查找正确的值.我可能能够使用 log4net(或 NLog)上下文对象实现相同的功能,但在我们的应用程序中,我们可能有一些设置或会话信息,应用程序将保留用于其他目的,我们希望能够将其添加到日志输出.由于它已经在查找结构中,因此能够直接引用数据而不是将其显式复制到 log4net(或 NLog 上下文)会很好.

I got the answer that I wanted. I have included the code for my sample PatternLayoutRenderer here. In my test, I have a static dictionary in my main form class where I could store "application settings". I have created a PatternLayoutConverter that can accept a key as a parameter so that the converter can lookup the correct value in the dictionary. I might be able to achieve the same functionality using the log4net (or NLog) context objects, but in our application we might have some settings or session info that the application will hold for other purposes and we want to be able to add that to the logging output. Since it will already be in a lookup structure, it would be nice to be able to reference the data directly rather than having to explicitly copy it to the log4net (or NLog context).

无论如何,这是代码:

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>

推荐答案

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

I did not try it but this should work. In log4net you can pass an option string to a pattern converter like this:

%converterName{converterOptions}

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

The date pattern converter for instance can be used like this:

%date{HH:mm:ss,fff}

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

This means you can write your pattern converter the way you suggested. A simple example for such a converter can be found here.

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

In the Convert method you can access the the property string with the property 'Option' (defined in the PatternConverter class) and use the thread context to get the desired entry from the dictionary. You can also implement the IOptionHandler interface if your options consist of more then just the dictionary key: This way you can parse the options upon activation of the log4net configuration.

这篇关于自定义 log4net 属性 PatternLayoutConverter(带索引)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆