Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Read&;使用log4net在运行时记录HttpSession数据_C#_Logging_Asp.net Mvc 4_Log4net - Fatal编程技术网

C# Read&;使用log4net在运行时记录HttpSession数据

C# Read&;使用log4net在运行时记录HttpSession数据,c#,logging,asp.net-mvc-4,log4net,C#,Logging,Asp.net Mvc 4,Log4net,这可能是不可能的,但我想知道是否有办法让它发挥作用 我有一个大型ASP.NET MVC43应用程序,它已经安装了日志语句 现在,我们需要在每个日志条目中包含会话对象中的“Company Name”值。是否可以将log4net配置为读取会话数据并将其包含在日志条目中?或者用某种方式强迫它 谢谢你的建议 [编辑] 这个问题帮助很大: 我最终将此作为我的解决方案: 在Global.asax.cs中: // After the session is acquired, push the orga

这可能是不可能的,但我想知道是否有办法让它发挥作用

我有一个大型ASP.NET MVC43应用程序,它已经安装了日志语句

现在,我们需要在每个日志条目中包含会话对象中的“Company Name”值。是否可以将log4net配置为读取会话数据并将其包含在日志条目中?或者用某种方式强迫它

谢谢你的建议

[编辑] 这个问题帮助很大:

我最终将此作为我的解决方案:

在Global.asax.cs中:

    // After the session is acquired, push the organization code into log4net's thread context, in case it has to log anything.
    protected void Application_PostAcquireRequestState(object sender, EventArgs e)
    {
        if (Context.Handler is IRequiresSessionState && Session != null && Session[Constants.EMPLOYEE_DETAILS] != null)
                log4net.ThreadContext.Properties["Company"] = ((EmployeeDetails)Session[Constants.EMPLOYEE_DETAILS]).Company;
    }
在log4net配置中:

  <parameter>
    <parameterName value="@Company"/>
    <dbType value="String"/>
    <size value="10"/>
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%property{Company}" />
    </layout>
  </parameter>


工作得很好-我现在在日志输出中得到了一个公司名称。谢谢大家的帮助。

我认为您可以使用上下文和模式布局来实现这一点:


不过,文档并没有多大帮助。

使用自定义布局转换器

public class CompanyLayoutConverter : PatternLayoutConverter
{
    protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
    {
         var httpContext = HttpContext.Current;
         if (httpContext == null)
             return;

         writer.Write(httpContext.Session["Company Name"]);
    }
}
将此转换器添加到appender布局,公司名称将显示在输出中(只需在conversionPattern值处使用
%company
):


有关如何实现此功能的一些想法,请参见此答案

您应该能够在不实现自己的Appender的情况下完成它

下面是一个自定义
PatternLayoutConverter
的示例,它从
HttpContext.Current.Session
提取参数化值。(我不记得当我把它作为链接答案的一部分发布时是否进行了测试,但应该很接近):

另一个更简单的想法是这样做。。。创建一个对象,该对象将检索所需的会话参数,并将该对象放入MDC中,然后在布局中引用MDC。当log4net从MDC访问对象时,它将调用其ToString方法来获取要写入日志的值

public class HttpContextSessionParametreProvider
{
  private string _name;
  private string _notSet;

  public HttpContextSessionParameterProvider(string name)
  {
    _name = name;
    _notSet = string.Format("{0} not set", _name);
  }

  public override string ToString()
  {
    HttpContext context = HttpContext.Current;  
    if (context != null && context.Session != null)
    {
      object item = context.Session[_name];
      if (item != null)
      {
        return item.ToString();
      }
    }
    return _notSet;
  }
}
在程序入口点附近的某个地方这样使用:

MDC.Set("CompanyName", new HttpContextSessionParametreProvider("Company Name"));
(关于如何配置log4net以从MDC中提取参数,我没有现成的示例,但应该不难找到)

编辑:

您可以像这样配置PatternLayout:

  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="[%thread]|[%property{CompanyName}]|%message%newline"/>
  </layout>


现在,假设
HttpContext.Session[“Company Name”]
设置为某个值,每当您记录消息时,该值都会写入日志。

实现AppenderSkleton(请参阅)非常容易,该实现可以引用静态会话实例并添加信息。谢谢。显然,MDC已被弃用,但您提供的链接提供了一些有用的信息。现在我只想弄明白为什么HttpContext.Current总是空的。可能是因为我正在使用spring.net将log4net实例注入LogManager类。嗯,很乐意帮忙。我不做任何ASP.NET开发,因此我恐怕无法帮助处理空HttpContext.Current。我确实发现了这篇(旧的)外部文章,它描述了HttpContext.Current可以为null的一些情况。也许这会有帮助。这是接近上述答案的第二个答案。我正在让它工作,但无法正确地整理转换模式的值。不过谢谢你。
public class HttpContextSessionParametreProvider
{
  private string _name;
  private string _notSet;

  public HttpContextSessionParameterProvider(string name)
  {
    _name = name;
    _notSet = string.Format("{0} not set", _name);
  }

  public override string ToString()
  {
    HttpContext context = HttpContext.Current;  
    if (context != null && context.Session != null)
    {
      object item = context.Session[_name];
      if (item != null)
      {
        return item.ToString();
      }
    }
    return _notSet;
  }
}
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="[%thread]|[%property{CompanyName}]|%message%newline"/>
  </layout>