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

查看:429
本文介绍了自定义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天全站免登陆