如何设置特定于ASP.NET请求的log4net上下文属性?

Tom*_*son 10 asp.net log4net properties httpcontext

我一直在使用log4net来记录我们的ASP.NET网站的日志消息,最近我想添加有关错误发生的页面/处理程序的信息.因此我决定将以下行添加到Global.asax:

void Application_BeginRequest(object sender, EventArgs e)
{
    log4net.ThreadContext.Properties["page"] = HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath;
}
Run Code Online (Sandbox Code Playgroud)

我明智地加入%property{page}了我的转换模式:

<conversionPattern value="%newline%date %-5level %property{page} - %message%newline%newline%newline" />
Run Code Online (Sandbox Code Playgroud)

这适用于单个请求.但后来我在日志中注意到,在ASP.NET请求期间,页面属性可能会发生变化.我已经登录了一个ASHX处理程序,并且在其处理过程中,页面属性将更改为指向ASPX页面的不同值.我得出结论,有另一个请求进入ASP.NET并且它BeginRequest被执行并且静态页面属性log4net.ThreadContext被更改为另一个值.

现在,我想维护每个请求的页面属性,以便我可以将执行页面的路径一致地记录到日志中.我试图找到答案,但我一无所获.解决此问题的推荐方法是什么?我确信这是Web服务器事件记录的非常基本的功能.

Tim*_*wis 22

由于ASP.NET 不保证整个页面请求将在同一个线程上处理,我更喜欢从HttpContext.Current获得答案,因为log4net处理 日志记录事件.

以下GetCurrentPage类通过重写其方法来实现log4net手动调用"活动属性值"的内容ToString:

public class GetCurrentPage
{
  public override string ToString()
  {
      if (null != HttpContext.Current)
      {
          return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath;
      }
      return string.Empty; // or "[No Page]" if you prefer
  }
}
Run Code Online (Sandbox Code Playgroud)

Application_Start在log4net的GlobalContext 中的Global.asax中注册此类.

protected void Application_Start(object sender, EventArgs e)
{
    XmlConfigurator.Configure();
    GlobalContext.Properties["page"] = new GetCurrentPage();
}
Run Code Online (Sandbox Code Playgroud)

当log4net写入该%property{page}行的一部分时,它将调用ToString我们GetCurrentPage类的方法,该方法将查找当前请求中的值.

  • 这是天才. (3认同)