log4net.GlobalContext.Properties是否每个请求不同?

时间:2014-10-30 03:37:13

标签: c# .net logging asp.net-web-api log4net

在log4net中,我想为特定的http请求的每个日志语句附加一个请求id。请求ID在多个请求中是不同的。在我的global.asax.cs中,我分配了一个requestId。

   protected void Application_BeginRequest(object sender, EventArgs e)
    {

        log4net.GlobalContext.Properties["requestId"] =
    System.Guid.NewGuid().ToString();
      log.Info("Starting request.");  
    }

在我的Log4Net.config中,我将requestId添加到我的模式布局中:

<layout type="log4net.Layout.PatternLayout">
 <param name="ConversionPattern" value="%property{requestId} %d [%t] %-5p %c %m%n"/>
</layout>

使用GlobalContext设置变量线程安全的方法是什么?我是否有并发http请求的风险 不安全地更改requestId以记录另一个请求?

如果这不安全,有什么安全的实施方式?

3 个答案:

答案 0 :(得分:14)

不,这不正确;所有线程和域共享全局上下文。在GlobalContext上设置相同属性的两个线程将覆盖彼此的属性。 log4net.GlobalContext.Properties["requestId"]将始终包含已启动的最新请求的请求ID。

成为threadsafe并不意味着线程无关:它意味着对象可以被多个线程同时操纵。

使用每个线程生成的ThreadContext并允许每个线程拥有一个属性(因此每个请求,假设您的线程在某个时候没有将工作委托给另一个线程): log4net.ThreadContext.Properties["requestId"]

答案 1 :(得分:1)

它对我有用。 我确实有这种情况,一个必须向日志发送不同信息的多线程应用程序取决于线程上下文。

使用ThreadContext而不是GlobalContext就像魅力一样。

答案 2 :(得分:0)

此类型对于多线程操作是安全的。 (log4net.GlobalContext Documentation

编辑:doc链接可能会更新,这适用于v 1.2.15。 GlobalContextProperties

引用:

此类实现一个线程安全的属性集合,并支持存储属性和捕获当前属性的只读副本。此类针对频繁读取属性并且不经常修改的方案进行了优化。