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