tri*_*bus 5 vb.net asp.net error-handling logging log4net
我正在开发一个Log4Net配置,它将记录所有未处理的异常.我需要基于用户的某些属性添加到每个日志条目中.我在Application_Error事件中以下列方式成功设置了它.这是我完整的global.asax
Imports log4net
Imports log4net.Config
Public Class Global_asax
Inherits System.Web.HttpApplication
'Define a static logger variable
Private Shared log As ILog = LogManager.GetLogger(GetType(Global_asax))
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
' Fires when the application is started
ConfigureLogging()
End Sub
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
' Code that runs when an unhandled error occurs
Dim ex As Exception = Server.GetLastError()
ThreadContext.Properties("user") = User.Identity.Name
ThreadContext.Properties("appbrowser") = String.Concat(Request.Browser.Browser, " ", Request.Browser.Version)
If TypeOf ex Is HttpUnhandledException AndAlso ex.InnerException IsNot Nothing Then
ex = ex.InnerException
End If
log.Error(ex)
ThreadContext.Properties.Clear()
End Sub
Private Sub ConfigureLogging()
Dim logFile As String = Server.MapPath("~/Log4Net.config")
log4net.Config.XmlConfigurator.ConfigureAndWatch(New System.IO.FileInfo(logFile))
log4net.GlobalContext.Properties("appname") = System.Reflection.Assembly.GetExecutingAssembly.GetName.Name
End Sub
End Class
Run Code Online (Sandbox Code Playgroud)
这似乎工作正常.但是,我有一些问题我无法回答.
我通过threadcontext添加用户特定属性的方式是正确的吗?即使在负载下,这总是会记录正确的信息吗?你什么时候使用threadlogicalcontext?有一个更好的方法吗?
谢谢
Ben*_*man 11
加载特定于请求的值是不安全的ThreadContext.原因是ASP.NET共享线程来处理请求.事实上,它经常这样做.
您可以改为使用LogicalThreadContext,但这只是将值存储在Call Context中,用于Remoting.
AFAIK没有特定于HttpContext的上下文存储,所以你可以做的是将一个"值提供者"实例作为你的线程上下文,并在运行时它将在这个类上调用.ToString()来获取值.
public class HttpContextUserProvider
{
public override string ToString()
{
return HttpContext.Current.User.Identity.Name;
}
}
Run Code Online (Sandbox Code Playgroud)
它不太理想,但它有效.
Ben的回答是正确的.
但是,和其他一些用户一样,我仍然有点迷失方向.这个log4net上下文问题与ASP.Net线程敏捷性帖子,特别是这个MarekStój的博客--log4net上下文属性和ASP.NET一个为一些优秀的代码示例提供了更多的问题上下文.
我强烈推荐MarekStój的实施,尽管在我的情况下ThreadContext.Properties["UserName"]需要更换ThreadContext.Properties["User"].
我在我的Logger类中添加了一个BeginRequest方法,我从Application_AuthenticateRequest调用它来加载所有相关的log4net属性.
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
Logger.BeginRequest(Request);
}
Run Code Online (Sandbox Code Playgroud)
方法代码:
public static void BeginRequest(System.Web.HttpRequest request)
{
if (request == null) return;
ThreadContext.Properties["ip_address"] = AdaptivePropertyProvider.Create("ip_address", IPNetworking.GetMachineNameAndIP4Address());
ThreadContext.Properties["rawUrl"] = AdaptivePropertyProvider.Create("rawUrl", request.RawUrl);
if (request.Browser != null && request.Browser.Capabilities != null)
ThreadContext.Properties["browser"] = AdaptivePropertyProvider.Create("browser", request.Browser.Capabilities[""].ToString());
if (request.IsAuthenticated && HttpContext.Current.User != null)
ThreadContext.Properties["User"] = AdaptivePropertyProvider.Create("user", HttpContext.Current.User.Identity.Name);
}
Run Code Online (Sandbox Code Playgroud)
我发现我必须传入Request对象而不是HttpContext.Current.Request在方法中使用.否则我会丢失用户和身份验证信息.请注意,IPNetworking该类是我自己的,因此您需要提供自己的获取客户端IP的方法.该AdaptivePropertyProvider课程直接来自MarekStój.
| 归档时间: |
|
| 查看次数: |
6861 次 |
| 最近记录: |