Click here to Skip to main content
Click here to Skip to main content

Error logging techniques using Database

By , 8 Apr 2008
Rate this:
Please Sign up or sign in to vote.

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
{
    /// <span class="code-SummaryComment"><summary></span>
    /// This file Handles the Exception and logging them into the database.
    /// <span class="code-SummaryComment"></summary></span>
    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)

About the Author

Kishore Kumar.N
Architect TATA CONSULTANCY SERVICES
India India
ROLE: SDL Tridion Consultant
 
Background:
Over 8+ Years of Experience working in various Web Content Management System like SDL Tridion,Sharepoint, Interwoven and few other OpenSource CMS.
 
Core WCM product strength is on SDLTridion.
 
Current Profile: Product Specialist
 
Email: kishorekumar.nandagopal@tcs.com

Comments and Discussions

 
GeneralGood Article PinmemberAvind 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 PinmemberDavidjwong13-Apr-08 14:17 
GeneralRe: Thank you - useful way of logging custom information PinmemberKishore Kumar.N14-Apr-08 2:41 
Questionhow about using gmail smtp server ? PinmemberQuachNguyen9-Apr-08 9:46 
AnswerRe: how about using gmail smtp server ? PinmemberNirosh12-Apr-08 15:22 
GeneralPossibilities of losing the logs PinmemberEniac09-Apr-08 2:19 
GeneralRe: Possibilities of losing the logs PinmemberKishore Kumar.N14-Apr-08 2:39 
GeneralYou do not need this Pinmember leppie 8-Apr-08 3:38 
GeneralRe: You do not need this PinmemberKishore Kumar.N8-Apr-08 3:51 
GeneralRe: You do not need this Pinmemberr_anand_kumar8-Apr-08 4:18 
GeneralRe: You do not need this PinmemberMadhur Ahuja8-Apr-08 19:59 
GeneralRe: You do not need this PinmemberAshfield9-Apr-08 0:22 
GeneralRe: You do not need this PinmemberDavidjwong13-Apr-08 14:02 
GeneralRe: You do not need this Pinmember leppie 13-Apr-08 19:50 
GeneralRe: You do not need this PinmemberDavidjwong13-Apr-08 21:00 
GeneralRe: You do not need this PinmemberKishore Kumar.N14-Apr-08 2:31 
GeneralRe: You do not need this PinmemberRichard Deeming14-Apr-08 6:33 
GeneralRe: You do not need this PinmemberDavidjwong14-Apr-08 10:50 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140415.2 | Last Updated 8 Apr 2008
Article Copyright 2008 by Kishore Kumar.N
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid