Click here to Skip to main content
15,878,959 members
Articles / Web Development / ASP.NET
Article

Error logging techniques using Database

Rate me:
Please Sign up or sign in to vote.
2.70/5 (7 votes)
8 Apr 2008CPOL2 min read 87.2K   1.2K   34   18
Logging the error in the database and sending email to the respective person

Introduction

Nowadays error logging becomes mandatory and there has been lots of techniques/API's to log the errors. We develop a ASP.NET application and it works fine on your development machine, and when we deploy the application to the production we set the <compilation debug="false" ...> element in your web.config , of course it is the best practice, which makes the error not visible to the end users.
Well, now, we got some exception and we wonder what is that error and you don't have any clue about error since we have not logged the exception and we were left at no man’s land and makes the developer job very tough without any clue about the error and hence we expect is to log the error and a notification mail to sent to the development so that we make the developer job much easier which is even best practice.

In following article we are going to cover the topics on how to log the error in a simple way and of course in a efficient manner.

I personally feel logging the errors either in text files or eventviewer would not make sense, since there is a possibility of losing the data.

Storing them in database would be a better way and easily managable and reports can be generated based on the logging date.

This article is focused to make the logging very simple and customisible based on your needs.

How to add error logging technique to any Application?

To add this logging framework to any ASP.NET web application you only need to do the following:
1) Execute the script(DBExceptionHandler\DBErrorLog.sql in any database
2) Add the following or copy paste (DBExceptionHandler\WebConfigKey.txt)to your web.config and modify the conn. string and other key values based on your settings:

<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) Drop the " DBExceptionHandler.dll" into the /bin folder of your app.
4) Jus call the static method YourCompany.ExceptionHandler.dbErrorLogging.LogError(ex) in the catch block.
That's it! Once you have set up the database, please do appropriate changes in the web.config based on the application settings.

How it works?

When there is an exception in the code, it checks for boolean string where the Logging is enabled to our application and calls the method HandleException which takes cares of the logging the exception into the database.

we can also set whether a notification mail of the exception to be sent to the concern person by jus setting EnableLogEmail = True in the web.config.

Below is the code snippet used for logging the error

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;
            }
        }
    }        

Below is the Preview of the Email Message

EmailMessage.JPG

Additional Notes:

I've attached the source with a sample web application which gives you clear idea about how to use them in your application.

If you have any queries or suggestions, please email to kkumar@iotap.com

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralGood Article Pin
Avind Mewara2-Jul-08 19:24
Avind Mewara2-Jul-08 19:24 
very nice article.
thanks for sharing your knowledge with us.

Arvind

Arvind M

GeneralThank you - useful way of logging custom information Pin
Davidjwong13-Apr-08 14:17
Davidjwong13-Apr-08 14:17 
GeneralRe: Thank you - useful way of logging custom information Pin
Kishore Kumar.N14-Apr-08 2:41
Kishore Kumar.N14-Apr-08 2:41 
Questionhow about using gmail smtp server ? Pin
QuachNguyen9-Apr-08 9:46
QuachNguyen9-Apr-08 9:46 
AnswerRe: how about using gmail smtp server ? Pin
Nirosh12-Apr-08 15:22
professionalNirosh12-Apr-08 15:22 
GeneralPossibilities of losing the logs Pin
Eniac09-Apr-08 2:19
Eniac09-Apr-08 2:19 
GeneralRe: Possibilities of losing the logs Pin
Kishore Kumar.N14-Apr-08 2:39
Kishore Kumar.N14-Apr-08 2:39 
GeneralYou do not need this Pin
leppie8-Apr-08 3:38
leppie8-Apr-08 3:38 
GeneralRe: You do not need this Pin
Kishore Kumar.N8-Apr-08 3:51
Kishore Kumar.N8-Apr-08 3:51 
GeneralRe: You do not need this Pin
r_anand_kumar8-Apr-08 4:18
r_anand_kumar8-Apr-08 4:18 
GeneralRe: You do not need this Pin
Madhur Ahuja8-Apr-08 19:59
Madhur Ahuja8-Apr-08 19:59 
GeneralRe: You do not need this Pin
Ashfield9-Apr-08 0:22
Ashfield9-Apr-08 0:22 
GeneralRe: You do not need this Pin
Davidjwong13-Apr-08 14:02
Davidjwong13-Apr-08 14:02 
GeneralRe: You do not need this Pin
leppie13-Apr-08 19:50
leppie13-Apr-08 19:50 
GeneralRe: You do not need this Pin
Davidjwong13-Apr-08 21:00
Davidjwong13-Apr-08 21:00 
GeneralRe: You do not need this Pin
Kishore Kumar.N14-Apr-08 2:31
Kishore Kumar.N14-Apr-08 2:31 
GeneralRe: You do not need this Pin
Richard Deeming14-Apr-08 6:33
mveRichard Deeming14-Apr-08 6:33 
GeneralRe: You do not need this Pin
Davidjwong14-Apr-08 10:50
Davidjwong14-Apr-08 10:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.