首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将捕获的ASP.NET异常写入EventLog而不丢失详细信息

将捕获的ASP.NET异常写入EventLog而不丢失详细信息
EN

Stack Overflow用户
提问于 2016-08-04 09:26:47
回答 1查看 2.3K关注 0票数 6

这篇文章详细解释了如何将ASP.NET异常记录到EventLog并向最终用户显示自定义错误页。

但是,ASP.NET web应用程序的标准事件日志机制自动包含了本文中未显示的许多有用信息。实现本文中的代码会导致错误事件中的细节/粒度丢失。

例如,在自动异常日志记录中,您可以在标题下看到许多属性:事件信息、应用程序信息、进程信息、请求信息、线程信息、自定义事件详细信息。

如何实现记录在未登录异常中的所有相同信息的日志记录,并将我的自定义信息附加到自定义事件详细信息部分?最好的答案最好是使用System.DiagnosticsSystem.Exception或类似的内置方法,即编写尽可能少的代码来编写上面提到的所有部分的日志条目,并简单地将任何自定义细节附加到字符串中。

如果可能的话,我还想将唯一的哈希事件ID (例如下面的b68b3934cbb0427e9497de40663c5225 )返回给应用程序,以便在ErrorPage.aspx上显示。

所需日志格式示例:

代码语言:javascript
复制
Event code: 3005 
Event message: An unhandled exception has occurred. 
Event time: 15/07/2016 15:44:01 
Event time (UTC): 15/07/2016 14:44:01 
Event ID: b68b3934cbb0427e9497de40663c5225 
Event sequence: 131 
Event occurrence: 2 
Event detail code: 0 

Application information: 
    Application domain: /LM/W3SVC/3/ROOT-1-131130657267252632 
    Trust level: Full 
    Application Virtual Path: / 
    Application Path: C:\WWW\nobulus\nobulusPMM\Application\PMM\ 
    Machine name: L-ADAM 

Process information: 
    Process ID: 47216 
    Process name: iisexpress.exe 
    Account name: L-ADAM\Adam 

Exception information: 
    Exception type: ApplicationException 
    Exception message: Error running stored procedure saveValidation: Procedure or function 'saveValidation' expects parameter '@ValidatedBy', which was not supplied.
   at PMM.Models.PMM_DB.runStoredProcedure(String StoredProcedureName, List`1 SQLParameters) in C:\WWW\nobulus\nobulusPMM\Application\PMM\Models\PMM_DB.cs:line 104
   at PMM.Models.PMM_DB.saveValidation(String PTLUniqueID, String ValidatedBy, DateTime ValidationDateTime, Nullable`1 ValidationCategoryID, String ValidationCategory,     String Comment, Nullable`1 ClockStartDate, Nullable`1 ClockStopDate, String StartRTTStatus, String StopRTTStatus, String LastRTTStatus, Boolean MergedPathway, String     MergedPathwayID, String ExtinctPathwayID, DataTable ChecklistResponses) in C:\WWW\nobulus\nobulusPMM\Application\PMM\Models\PMM_DB.cs:line 265
   at PMM.Validate.lnkSaveButton_Click(Object sender, EventArgs e) in C:\WWW\nobulus\nobulusPMM\Application\PMM\Validate.aspx.cs:line 323
   at System.Web.UI.WebControls.LinkButton.OnClick(EventArgs e)
   at System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)



Request information: 
    Request URL: http://localhost:6901/Validate?PTLUniqueID=RTT10487 
    Request path: /Validate 
    User host address: ::1 
    User: L-ADAM\Adam 
    Is authenticated: True 
    Authentication Type: Negotiate 
    Thread account name: L-ADAM\Adam 

Thread information: 
    Thread ID: 19 
    Thread account name: L-ADAM\Adam 
    Is impersonating: False 
    Stack trace:    at PMM.Models.PMM_DB.runStoredProcedure(String StoredProcedureName, List`1 SQLParameters) in C:\WWW\nobulus\nobulusPMM\Application\PMM\Models\PMM_DB.    cs:line 104
   at PMM.Models.PMM_DB.saveValidation(String PTLUniqueID, String ValidatedBy, DateTime ValidationDateTime, Nullable`1 ValidationCategoryID, String ValidationCategory,     String Comment, Nullable`1 ClockStartDate, Nullable`1 ClockStopDate, String StartRTTStatus, String StopRTTStatus, String LastRTTStatus, Boolean MergedPathway, String     MergedPathwayID, String ExtinctPathwayID, DataTable ChecklistResponses) in C:\WWW\nobulus\nobulusPMM\Application\PMM\Models\PMM_DB.cs:line 265
   at PMM.Validate.lnkSaveButton_Click(Object sender, EventArgs e) in C:\WWW\nobulus\nobulusPMM\Application\PMM\Validate.aspx.cs:line 323
   at System.Web.UI.WebControls.LinkButton.OnClick(EventArgs e)
   at System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)


Custom event details: 
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-02 13:16:35

更新

实际上,我发现使用ILSpy和漫游在ASP.NET内部使用的不同框架类中,这些类具有实现相同行为的受保护方法。

解决方案1:

为此,只需创建继承WebErrorEvent的类,然后重写其构造函数

代码语言:javascript
复制
public class CustomWebErrorEvent : WebErrorEvent
{
    public CustomWebErrorEvent(string message, EventSource source, int eventCode, Exception ex) : base(message, source, eventCode, ex)
    {
    }
}

然后在Global.asax的错误管理方法中使用它:

代码语言:javascript
复制
protected void Application_Error(Object sender, EventArgs e)
{
    // Log error to the Event Log
    Exception myError = null;
    if (HttpContext.Current.Server.GetLastError() != null)
    {
        var r = new CustomWebErrorEvent("error", null, 120, HttpContext.Current.Server.GetLastError());
    }
}

我很肯定它也有可能使ASPNET过载,只需要直接提出一个定制的WebErrorEvent,但我还没有找到它。

我仍然试图弄清楚如何在事件中添加自定义信息,因为重写方法FormatCustomEventDetails没有被调用为Web事件。

解决方案2:

如果暂时不可能添加自定义字段,则可以使用我编写的类似方法来执行相同的输出:

代码语言:javascript
复制
// Log error to the Event Log
Exception myError = null;
if (HttpContext.Current.Server.GetLastError() != null)
{
    var request = HttpContext.Current.Request;
    myError = HttpContext.Current.Server.GetLastError();

    var dateAsBytes = System.Text.Encoding.UTF8.GetBytes(DateTime.Now.ToString("G"));
    var id = Convert.ToBase64String(System.Security.Cryptography.MD5.Create().ComputeHash(dateAsBytes));

    // Event info:
    var eventMessage = myError.Message;
    var currentTime = DateTime.Now.ToString("G");
    var currentTimeUTC = DateTime.UtcNow.ToString("G");

    // Application info:
    var appDomainName = AppDomain.CurrentDomain.FriendlyName;
    var appDomainTrustLevel = (AppDomain.CurrentDomain.IsFullyTrusted) ? "Full" : "Partial";
    var appVirtualPath = VirtualPathUtility.GetDirectory(request.Path);
    var appPath = request.PhysicalApplicationPath;
    var machineName = Environment.MachineName;

    // Process info:
    var process = Process.GetCurrentProcess();
    var processId = process.Id;
    var processName = process.ProcessName;
    var user = System.Security.Principal.WindowsIdentity.GetCurrent().User;
    var accountName = user.Translate(typeof(System.Security.Principal.NTAccount));

    // Exception info:
    var exceptionType = myError.GetType().FullName;
    var exceptionMessage = myError.Message;
    var exceptionStack = myError.StackTrace;

    // Request info:
    var url = request.Url.AbsoluteUri;
    var urlPath = request.Url.PathAndQuery;
    var remoteAddress = request.UserHostAddress;
    var userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
    var isAuthenticated = HttpContext.Current.User.Identity.IsAuthenticated;
    var authenticationType = System.Security.Principal.WindowsIdentity.GetCurrent().AuthenticationType;

    // Thread info:
    var impersonationLevel = System.Security.Principal.WindowsIdentity.GetCurrent().ImpersonationLevel;
    var exceptionStack2 = myError.StackTrace;

    // TODO: aggregate all info as string before writting to EventLog.
}

我发现使用现有的.NET Apis --几乎所有的输出都是必需的字段--只是需要知道,在输出到EventLog中之前,必须将其聚合为字符串。

您可以看到,我使用的一些对象(如AppDomain.CurrentDomainHttpContext.Current.RequestProcess.GetCurrentProcess() )返回了许多其他信息,如果需要的话,这些信息也可以添加到输出中。

当然,这一切都可以用代码简洁的方法来包装。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38763488

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档