Saturday, January 12, 2013

Error handling and logging


We don't think any "enterprise application" can truly be called "enterprise" if it doesn't handle errors well and notify someone to address them. In an ASP.NET site, there are basically two forms of errors—errors that you have caught, and the ones you couldn't. Pretty simple, right? Well, not so fast! Whether you have trapped an error or not, the user of your application is still going to end up with some form of disruption in their surfing experience. So we need a way to not only provide users with a smooth disruption but also to fix the disruption so that it doesn't happen again.



Error handling is the act of doing your best to trap expected or possible errors. It is also the act of not allowing ugly error messages to get in front of your customers. Logging is to capture details of these errors so that we can fix them down the road.

Logging

Logging can either be overly complex, or really easy. As we don't have loads of time on our hands, we usually opt not to reinvent the wheel whenever possible! So in this case, we will be using the log4net framework that provides an extensive set of tools for various forms of logging. You get it from this link http://logging.apache.org/log4net/download_log4net.cgi download log4net-1.2.11-bin-newkey.zip file and copy the log4net.dll and the log4net.xml files into your bin directory in the Components project. Once it is there, add a reference to log4net. Then you will need to create a log4net.config file in the root or bin directory of your Web project.
Now, we can create a class which implements our ILogger interface and helps us to interact with what log4net provides us:
  1. We will continue from last post Creating the .NET Solution Part 5 open the Fishbook solution.
  2. Right click in Interfaces project and select Add/New Item.
    Create ILogger Interface
    Create ILogger Interface
    1. Select Interface Item from C# Template and name it ILoggor.cs and then write the following code:
      using System;
      namespace Fishbook.Interfaces
      {
          public interface ILogger
          {
              void Debug(object source, object message);
              void Debug(object source, object message, Exception exception);
              void Debug(Type source, object message);
              void Debug(Type source, object message, Exception exception);
              void EnsureInitialized();
              void Error(object source, object message);
              void Error(object source, object message, Exception exception);
              void Error(Type source, object message);
              void Error(Type source, object message, Exception exception);
              void Fatal(object source, object message);
              void Fatal(object source, object message, Exception exception);
              void Fatal(Type source, object message);
              void Fatal(Type source, object message, Exception exception);
              void Info(object source, object message);
              void Info(object source, object message, Exception exception);
              void Info(Type source, object message);
              void Info(Type source, object message, Exception exception);
              string SerializeException(Exception e);
              void Warn(object source, object message);
              void Warn(object source, object message, Exception exception);
              void Warn(Type source, object message);
              void Warn(Type source, object message, Exception exception);
          }
      }

    2. Right click in Components project and select Add/New Item.
      Create Log Class
      Create Log Class
      1. Select Class Item from C# Template and name it Log.cs and write the following code:
        using System;
        using System.Collections.Generic;
        using System.IO;
        using log4net;
        using log4net.Appender;
        using log4net.Config;
        using log4net.Layout;
        using Fisharoo.Interfaces;
        using System.ComponentModel.Composition;

        namespace Fisharoo.Components
        {
            [Export(typeof(ILogger))]
            public class Log : ILogger
            {
                private Dictionary<Type, ILog> _loggers = new Dictionary<Type, ILog>();
                private bool _logInitialized = false;
                private object _lock = new object();

                public string SerializeException(Exception e)
                {
                    return SerializeException(e, string.Empty);
                }

                private  string SerializeException(Exception e, string exceptionMessage)
                {
                    if (e == null) return string.Empty;

                    exceptionMessage = string.Format(
                        "{0}{1}{2}\n{3}",
                        exceptionMessage,
                        (exceptionMessage == string.Empty) ? string.Empty : "\n\n",
                        e.Message,
                        e.StackTrace);

                    if (e.InnerException != null)
                        exceptionMessage = SerializeException(e.InnerException, exceptionMessage);

                    return exceptionMessage;
                }

                private  ILog getLogger(Type source)
                {
                    lock (_lock)
                    {
                        if (_loggers.ContainsKey(source))
                        {
                            return _loggers[source];
                        }
                        else
                        {
                            ILog logger = LogManager.GetLogger(source);
                            _loggers.Add(source, logger);
                            return logger;
                        }
                    }
                }

                /* Log a message object */

                public  void Debug(object source, object message)
                {
                    Debug(source.GetType(), message);
                }

                public  void Debug(Type source, object message)
                {
                    getLogger(source).Debug(message);
                }

                public  void Info(object source, object message)
                {
                    Info(source.GetType(), message);
                }

                public  void Info(Type source, object message)
                {
                    getLogger(source).Info(message);
                }

                public  void Warn(object source, object message)
                {
                    Warn(source.GetType(), message);
                }

                public  void Warn(Type source, object message)
                {
                    getLogger(source).Warn(message);
                }

                public  void Error(object source, object message)
                {
                    Error(source.GetType(), message);
                }

                public  void Error(Type source, object message)
                {
                    getLogger(source).Error(message);
                }

                public  void Fatal(object source, object message)
                {
                    Fatal(source.GetType(), message);
                }

                public  void Fatal(Type source, object message)
                {
                    getLogger(source).Fatal(message);
                }

                /* Log a message object and exception */

                public  void Debug(object source, object message, Exception exception)
                {
                    Debug(source.GetType(), message, exception);
                }

                public  void Debug(Type source, object message, Exception exception)
                {
                    getLogger(source).Debug(message, exception);
                }

                public  void Info(object source, object message, Exception exception)
                {
                    Info(source.GetType(), message, exception);
                }

                public  void Info(Type source, object message, Exception exception)
                {
                    getLogger(source).Info(message, exception);
                }

                public  void Warn(object source, object message, Exception exception)
                {
                    Warn(source.GetType(), message, exception);
                }

                public  void Warn(Type source, object message, Exception exception)
                {
                    getLogger(source).Warn(message, exception);
                }

                public  void Error(object source, object message, Exception exception)
                {
                    Error(source.GetType(), message, exception);
                }

                public  void Error(Type source, object message, Exception exception)
                {
                    getLogger(source).Error(message, exception);
                }

                public  void Fatal(object source, object message, Exception exception)
                {
                    Fatal(source.GetType(), message, exception);
                }

                public  void Fatal(Type source, object message, Exception exception)
                {
                    getLogger(source).Fatal(message, exception);
                }

                private  void initialize()
                {
                    string logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Log4Net.config");
                    if (!File.Exists(logFilePath))
                    {
                        logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"bin\Log4Net.config");
                    }

                    XmlConfigurator.ConfigureAndWatch(new FileInfo(logFilePath));
                }

                public  void EnsureInitialized()
                {
                    if (!_logInitialized)
                    {
                        initialize();
                        _logInitialized = true;
                    }
                }
            }
        }



      No comments:

      Post a Comment

      Automatic Traffic Exchange

      YallaTech Facebook page