使用数据库进行错误日志记录技术






2.70/5 (7投票s)
将错误记录到数据库并发送电子邮件给相关人员。
引言
如今,错误日志记录变得至关重要,并且已经存在许多用于记录错误的技巧/API。我们开发了一个 ASP.NET 应用程序,它在您的开发机器上运行良好,当我们部署应用程序到生产环境时,我们在 web.config 中设置 <compilation debug="false" ...> 元素,当然这是最佳实践,这使得错误对最终用户不可见。
现在,我们遇到了一些异常,并且我们想知道这个错误是什么,由于我们没有记录异常,您对错误一无所知,我们被困在了无人区,这使得开发人员的工作变得非常艰难,没有任何关于错误的线索,因此我们希望记录错误并将通知邮件发送给开发人员,以便我们让开发人员的工作变得更容易,这甚至是最佳实践。
在以下文章中,我们将介绍如何以一种简单的方式,当然也是以一种有效的方式记录错误。
我个人认为将错误记录在文本文件或事件查看器中没有意义,因为存在数据丢失的可能性。
将它们存储在数据库中将是一个更好的方法,易于管理,并且可以根据日志记录日期生成报告。
本文重点在于使日志记录非常简单并可根据您的需求进行定制。
如何将错误日志记录技术添加到任何应用程序?
要将此日志记录框架添加到任何 ASP.NET Web 应用程序,您只需要执行以下操作
1) 在任何数据库中执行脚本 (DBExceptionHandler\DBErrorLog.sql)
2) 添加以下内容或复制粘贴 (DBExceptionHandler\WebConfigKey.txt) 到您的 web.config 中,并根据您的设置修改连接字符串和其他关键值
<appSettings>
<add key="EnableLog" value="true"></add>
<add key="EnableLogEmail" value="true"></add>
<add key="LogToEmail" value="yourname1@domain.com|yourname2@domain.com"/>
<add key="smtpServer" value="smtpserverAddress"/>
<add key="LogFromEmail" value="demoadmin@iotap.com"/>
<add key="dbErrorLog" value="Data Source=.\SQLExpress;Integrated Security=True;User Instance=True;AttachDBFilename=|DataDirectory|DemoDatabase.mdf;"/>
</appSettings>
3) 将 " DBExceptionHandler.dll" 放入您应用程序的 /bin 文件夹中。
4) 在 catch 块中调用静态方法 YourCompany.ExceptionHandler.dbErrorLogging.LogError(ex)。
就这样!设置好数据库后,请根据应用程序设置在 web.config 中进行适当的更改。
它是如何工作的?
当代码中发生异常时,它会检查应用程序是否启用了日志记录的布尔字符串,并调用 HandleException 方法,该方法负责将异常记录到数据库中。
我们还可以通过在 web.config 中设置 EnableLogEmail = True 来设置是否将异常通知邮件发送给相关人员。
以下是用于记录错误的示例代码段
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Diagnostics; using System.Data.SqlClient; using System.Web.Mail; using System.Text; namespace YourCompany.ExceptionHandler { /// <summary> /// This file Handles the Exception and logging them into the database. /// </summary> public class dbErrorLogging { public dbErrorLogging() { // // TODO: Add constructor logic here // } public static void LogError(Exception oEx) { bool blLogCheck = Convert.ToBoolean(System.Configuration.ConfigurationSettings.AppSettings["EnableLog"]); bool blLogEmailCheck = Convert.ToBoolean(System.Configuration.ConfigurationSettings.AppSettings["EnableLogEmail"]); if (blLogCheck) { HandleException(oEx); } if (blLogEmailCheck) { SendExceptionMail(oEx); } } public static void HandleException(Exception ex) { HttpContext ctxObject = HttpContext.Current; string strLogConnString = System.Configuration.ConfigurationSettings.AppSettings["dbErrorLog"].ToString(); string logDateTime = DateTime.Now.ToString("g"); string strReqURL = (ctxObject.Request.Url != null) ? ctxObject.Request.Url.ToString() : String.Empty; string strReqQS = (ctxObject.Request.QueryString != null) ? ctxObject.Request.QueryString.ToString() : String.Empty; string strServerName = String.Empty; if (ctxObject.Request.ServerVariables["HTTP_REFERER"] != null) { strServerName = ctxObject.Request.ServerVariables["HTTP_REFERER"].ToString(); } string strUserAgent = (ctxObject.Request.UserAgent != null) ? ctxObject.Request.UserAgent : String.Empty; string strUserIP = (ctxObject.Request.UserHostAddress != null) ? ctxObject.Request.UserHostAddress : String.Empty; string strUserAuthen = (ctxObject.User.Identity.IsAuthenticated.ToString() != null) ? ctxObject.User.Identity.IsAuthenticated.ToString() : String.Empty; string strUserName = (ctxObject.User.Identity.Name != null) ? ctxObject.User.Identity.Name : String.Empty; string strMessage = string.Empty, strSource = string.Empty, strTargetSite = string.Empty, strStackTrace = string.Empty; while (ex != null) { strMessage = ex.Message; strSource = ex.Source; strTargetSite = ex.TargetSite.ToString(); strStackTrace = ex.StackTrace; ex = ex.InnerException; } if (strLogConnString.Length > 0) { SqlCommand strSqlCmd = new SqlCommand(); strSqlCmd.CommandType = CommandType.StoredProcedure; strSqlCmd.CommandText = "sp_LogExceptionToDB"; SqlConnection sqlConn = new SqlConnection(strLogConnString); strSqlCmd.Connection = sqlConn; sqlConn.Open(); try { strSqlCmd.Parameters.Add(new SqlParameter("@Source", strSource)); strSqlCmd.Parameters.Add(new SqlParameter("@LogDateTime", logDateTime)); strSqlCmd.Parameters.Add(new SqlParameter("@Message", strMessage)); strSqlCmd.Parameters.Add(new SqlParameter("@QueryString", strReqQS)); strSqlCmd.Parameters.Add(new SqlParameter("@TargetSite", strTargetSite)); strSqlCmd.Parameters.Add(new SqlParameter("@StackTrace", strStackTrace)); strSqlCmd.Parameters.Add(new SqlParameter("@ServerName", strServerName)); strSqlCmd.Parameters.Add(new SqlParameter("@RequestURL", strReqURL)); strSqlCmd.Parameters.Add(new SqlParameter("@UserAgent", strUserAgent)); strSqlCmd.Parameters.Add(new SqlParameter("@UserIP", strUserIP)); strSqlCmd.Parameters.Add(new SqlParameter("@UserAuthentication", strUserAuthen)); strSqlCmd.Parameters.Add(new SqlParameter("@UserName", strUserName)); SqlParameter outParm = new SqlParameter("@EventId", SqlDbType.Int); outParm.Direction = ParameterDirection.Output; strSqlCmd.Parameters.Add(outParm); strSqlCmd.ExecuteNonQuery(); strSqlCmd.Dispose(); sqlConn.Close(); } catch (Exception exc) { EventLog.WriteEntry(exc.Source, "Database Error From Exception Log!", EventLogEntryType.Error, 65535); } finally { strSqlCmd.Dispose(); sqlConn.Close(); } } } protected static string FormatExceptionDescription(Exception e) { StringBuilder sb = new StringBuilder(); HttpContext context = HttpContext.Current; sb.Append("<b>Time of Error: </b>" + DateTime.Now.ToString("g") + "<br />"); sb.Append("<b>URL:</b> " + context.Request.Url + "<br />"); sb.Append("<b>QueryString: </b> " + context.Request.QueryString.ToString() + "<br />"); sb.Append("<b>Server Name: </b> " + context.Request.ServerVariables["SERVER_NAME"]+ "<br />"); sb.Append("<b>User Agent: </b>" + context.Request.UserAgent + "<br />"); sb.Append("<b>User IP: </b>" + context.Request.UserHostAddress + "<br />"); sb.Append("<b>User Host Name: </b>" + context.Request.UserHostName + "<br />"); sb.Append("<b>User is Authenticated: </b>" + context.User.Identity.IsAuthenticated.ToString() + "<br />"); sb.Append("<b>User Name: </b>" + context.User.Identity.Name + "<br />"); while (e != null) { sb.Append("<b>Message: </b>" + e.Message + "<br />"); sb.Append("<b> Source: </b>" + e.Source + "<br />"); sb.Append("<b>TargetSite: </b>" + e.TargetSite + "<br />"); sb.Append("<b>StackTrace: </b>" + e.StackTrace + "<br />"); sb.Append(Environment.NewLine + "<br />"); e = e.InnerException; } sb.Append("--------------------------------------------------------" + "<br />"); sb.Append("Regards," + "<br />"); sb.Append("Admin"); return sb.ToString(); } public static void SendExceptionMail(Exception e) { string strEmails = ConfigurationSettings.AppSettings["LogToEmail"].ToString(); if (strEmails.Length > 0) { string[] arEmails = strEmails.Split(Convert.ToChar("|")); MailMessage strMessage = new MailMessage(); strMessage.BodyFormat = MailFormat.Html; strMessage.To = arEmails[0]; for (int i = 1; i < arEmails.Length; i++) strMessage.Cc = arEmails[i]; string strFromEmail = ConfigurationSettings.AppSettings["LogFromEmail"].ToString(); strMessage.From = strFromEmail; strMessage.Subject = "AMR Research: Exception dated "+DateTime.Now+ " !"; string sExceptionDescription = FormatExceptionDescription(e); strMessage.Body = sExceptionDescription; SmtpMail.SmtpServer = System.Configuration.ConfigurationSettings.AppSettings["smtpServer"].ToString(); try { SmtpMail.Send(strMessage); } catch (Exception excm) { Debug.WriteLine(excm.Message); throw; } } else { return; } } }
以下是电子邮件消息的预览

其他说明
我附带了源代码和一个示例 Web 应用程序,它让您清楚地了解如何在您的应用程序中使用它们。
如果您有任何疑问或建议,请发送电子邮件至 kkumar@iotap.com