是否可以配置在应用程序崩溃时Windows事件日志中存储的信息
本文关键字:日志 事件 存储 信息 Windows 配置 崩溃 应用程序 是否 | 更新日期: 2023-09-27 18:26:10
偶尔,一个错误会触发其中一个不可恢复的异常(例如StackOverflowException
),导致我们的整个ASP.NET MVC应用程序崩溃。发生这种情况时,Windows事件日志通常会包含一些有关错误的信息,尽管这些信息很小。例如,目前,我们认为在反射调用中抛出了一个StackOverflowException
。在这种情况下,事件日志包含一些关于外部TargetInvocationException
的基本信息,而没有任何信息可以让我们确定问题所在。我的问题是,当这种情况发生时,是否可以在.NET/IIS/Windows中配置一些内容来记录更多信息?例如,如果我们能够获得完整异常(包括堆栈跟踪和内部异常)的前N个字符,我们就可以轻松地调试和修复问题。
您无法控制其他类向日志中写入的内容,但您可以在global.asax文件中捕获异常并进行自己的日志记录。我倾向于使用数据库日志记录和电子邮件通知的组合。
--global.asax
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
Exception exSvr = Server.GetLastError();
if (exSvr == null)
return;
if (exSvr.Message == "The client disconnected.")
{
// I don't want to be notified everytime someone closes
// the browser mid-request.
return;
}
if (exSvr is System.Threading.ThreadAbortException || exSvr.InnerException is System.Threading.ThreadAbortException || exSvr.Message.StartsWith("Thread was being aborted") || (exSvr.InnerException != null && exSvr.InnerException.Message.StartsWith("Thread was being aborted")))
{
// So we don't get notified everytime .NET kills a thread.
// NOTE: This error is how .NET kills a thread, and will happen every time we call Response.Redirect("", true)
return;
}
ErrorHandler.SendServerErrMsg("Application Error", exSvr, HttpContext.Current);
}
--错误处理程序
public static void SendServerErrMsg(string codeSection, Exception exSvr, HttpContext context, SeverityLevel lvl = SeverityLevel.Warning)
{
if (_config == null || !_config.EnableEmailAlerts)
return;
if (context != null && context.Request != null && context.Request.Url != null && context.Request.Url.IsLoopback && !_config.SendAlertsInDebugMode)
return;
if (context != null && context.IsDebuggingEnabled && !_config.SendAlertsInDebugMode)
return;
// Attempt to get the currently logged in user.
System.Web.Security.MembershipUser curUsr = null;
try
{ curUsr = System.Web.Security.Membership.GetUser(); }
catch { } // If it fails, don't worry about it.
// Set the message's subject line.
string subject = _config.ApplicationName + " Exception - " + HttpUtility.HtmlEncode(codeSection);
// Build the page body in a StringBuilder object.
System.Text.StringBuilder sb = new System.Text.StringBuilder();
if (context != null && context.Request != null)
sb.AppendLine(string.Format("<h2>{0}</h2>", HttpUtility.HtmlEncode(context.Request.ApplicationPath)));
sb.AppendLine("<p>The following exception has occurred:</p>");
sb.AppendLine("<ul>");
Exception innerEx = exSvr;
while (innerEx != null)
{
sb.AppendLine(string.Format("<li>{0}</li>", HttpUtility.HtmlEncode(innerEx.Message)));
innerEx = innerEx.InnerException;
}
sb.AppendLine("</ul>");
sb.AppendLine("<p/>");
if (exSvr.TargetSite != null)
sb.AppendLine(string.Format("<p>Target Site: {0} {1} (in {2})</p>", exSvr.TargetSite.MemberType, exSvr.TargetSite.Name, exSvr.TargetSite.DeclaringType));
else
sb.AppendLine("<p>Target Site: N/A</p>");
sb.AppendLine("<p/>");
sb.AppendLine("<hr />");
if (context != null && context.Request != null)
{
HttpRequest req = context.Request;
sb.AppendLine("<p>");
sb.AppendLine(string.Format("<div>Request URL: {0}</div>", HttpUtility.HtmlEncode(req.Url.ToString())));
sb.AppendLine(string.Format("<div>Request Path: {0}</div>", HttpUtility.HtmlEncode(req.FilePath)));
sb.AppendLine(string.Format("<div>User: {0}</div>", (curUsr != null) ? HttpUtility.HtmlEncode(curUsr.UserName) : "Unknown"));
sb.AppendLine(string.Format("<div>User Host Address: {0}</div>", HttpUtility.HtmlEncode(req.UserHostAddress)));
// We're going to try a reverse DNS search on the IP address. Failover,
// just uses the UserHostName value from the HttpContext object.
string hostName = null;
try { hostName = System.Net.Dns.GetHostEntry(req.UserHostAddress).HostName; }
catch { hostName = null; }
if (hostName == null) hostName = req.UserHostName;
sb.AppendLine(string.Format("<div>User Host Name: {0}</div>", HttpUtility.HtmlEncode(hostName)));
sb.AppendLine(string.Format("<div>User Agent: {0}</div>", HttpUtility.HtmlEncode(req.UserAgent)));
sb.AppendLine(string.Format("<div>Server Name: {0}</div>", (context.Server != null ? HttpUtility.HtmlEncode(context.Server.MachineName) : "Unknown")));
sb.AppendLine(string.Format("<div>Request Identity: {0}</div>", (req.LogonUserIdentity != null ? HttpUtility.HtmlEncode(req.LogonUserIdentity.Name) : "Unknown")));
sb.AppendLine("</p>");
sb.AppendLine("<hr />");
}
sb.AppendLine("<p>Stack trace follows:</p>");
Exception ex = exSvr;
while (ex != null)
{
sb.AppendLine("<p>");
sb.AppendLine(string.Format("<b>>> {0}:</b> {1} in {2}<br/>", ex.GetType().Name, HttpUtility.HtmlEncode(ex.Message), HttpUtility.HtmlEncode(ex.Source)));
sb.AppendLine(HttpUtility.HtmlEncode(ex.StackTrace));
sb.AppendLine("</p>");
ex = ex.InnerException;
}
if (context!=null && context.Trace.IsEnabled)
{
sb.AppendLine("<hr />");
sb.AppendLine("<p>Web Trace:</p>");
sb.AppendLine(string.Format("<p>{0}</p>", HttpUtility.HtmlEncode(context.Trace.ToString())));
}
EmailHelper.SendEmail(GetAlertContacts(), subject.Trim(), sb.ToString().Trim(), true);
}