使用具有范围属性的log4net

时间:2018-11-28 09:55:37

标签: log4net

我在具有seq目标的现有应用程序log4net上使用。 在代码工作流程中(正在调用不同的方法),我希望将一个id保存为一个属性,以便保留对该id的引用(在查看Seq时更容易理解发生了什么事情)

是否可以使用

using(var log = ........ properties)
{
     normal logging here
}

谢谢

1 个答案:

答案 0 :(得分:0)

可以通过例如

将此类属性存储在ThreadContextLogicalThreadContext
log4net.ThreadContext.Properties["someId"] = "foo";

并通过LayoutPattern包含在%property{someId}

<layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%logger | %level | %property{someId} | %message%newline" />
</layout>

下面的代码

ILog logger = LogManager.GetLogger("SomeLogger");
logger.Info("Message 1");

然后产生以下输出

SomeLogger | INFO | foo | Message 1


此上下文数据可以堆叠,因为Log4net具有context stacks的概念。

  

堆栈存储在上下文属性中,因此堆栈具有名称,并且同一上下文中可以存在多个堆栈。在较窄上下文中设置的属性值将覆盖在较宽范围上下文中设置的具有相同属性名称的堆栈。

     

堆栈支持Push和Pop方法。随着更多上下文数据被推入堆栈,堆栈将不断增长。渲染堆栈时,所有压入堆栈的数据都会与最新数据一起输出到字符串的右端。

     

由于堆栈只是存储在上下文属性中的对象,因此它也使用相同的PatternLayout语法:%property {name}进行呈现。其中name是堆栈的名称。

     

调用堆栈的Push和Pop方法必须匹配,以便每个推送都有相应的pop。 Push方法还返回一个IDisposable对象,该对象将在放置后执行所需的弹出操作。这允许使用C#使用语法来自动执行堆栈管理。


通过Push在堆栈上设置属性值,该属性值返回一个IDisposable对象,该对象会在处置后从堆栈中删除该属性值,例如

using (ThreadContext.Stacks["someId"].Push("bar"))
{
    logger.Info("Message 2");

    using (ThreadContext.Stacks["someId"].Push("baz"))
    {
        logger.Info("Message 3");
    }
}

有输出

SomeLogger | INFO | bar | Message 2
SomeLogger | INFO | baz | Message 3