Click here to Skip to main content
15,891,951 members
Articles / Programming Languages / C#

An Extension to the Enterprise Library Logging Application Block

Rate me:
Please Sign up or sign in to vote.
4.76/5 (18 votes)
28 Oct 200612 min read 73.1K   1.5K   51  
Provide more control over logging by extending the Enterprise Library Logging Application Block.
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Diagnostics;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.EnterpriseLibrary.Logging.Filters;

namespace EntLibLoggingExtended
{
    //
    // By wrapping the EntLib Logger class we are able to strongly type the operation string values 
    // and priroty int values and limit them to the Category and Priority enum values.
    //
    // We also add some default Write methods for the common loggoing message types we will be using.
    //

    /// <summary>
    /// Facade for writing a log entry to one or more <see cref="Microsoft.Practices.EnterpriseLibrary.LoggingTraceListener"/>s.
    /// This class is sealed.  This class wraps the <see cref="Microsoft.Practices.EnterpriseLibrary.Logger"/> class.
    /// </summary>
    public static class Logger
    {
        #region Enterprise Library Logger interface
        //-----------------------------------------------------------------------------------------------------

        private const Priority DefaultPriority = Priority.None;
        private const TraceEventType DefaultSeverity = TraceEventType.Information;
        private const int DefaultEventId = 1;
        private const string DefaultTitle = "";

		private static readonly CategoriesCollection emptyCategoriesList = new CategoriesCollection();

		/// <summary>
		/// Add a key/value pair to the <see cref="System.Runtime.Remoting.Messaging.CallContext"/> dictionary.  
		/// Context items will be recorded with every log entry.
		/// </summary>
		/// <param name="key">Hashtable key</param>
		/// <param name="value">Value.  Objects will be serialized.</param>
		/// <example>The following example demonstrates use of the AddContextItem method.
		/// <code>Logger.SetContextItem("SessionID", myComponent.SessionId);</code></example>
		public static void SetContextItem(object key, object value)
		{
            Microsoft.Practices.EnterpriseLibrary.Logging.Logger.SetContextItem(key, value);
		}

		/// <summary>
		/// Empty the context items dictionary.
		/// </summary>
		public static void FlushContextItems()
		{
			Microsoft.Practices.EnterpriseLibrary.Logging.Logger.FlushContextItems();
		}

		/// <overloads>
		/// Write a new log entry to the default category.
		/// </overloads>
		/// <summary>
		/// Write a new log entry to the default category.
		/// </summary>
		/// <example>The following example demonstrates use of the Write method with
		/// one required parameter, message.
		/// <code>Logger.Write("My message body");</code></example>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		public static void Write(object message)
		{
            Write(message, emptyCategoriesList, DefaultPriority,
				  DefaultEventId, DefaultSeverity, DefaultTitle, null);
		}

		/// <summary>
		/// Write a new log entry to a specific category.
		/// </summary>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="category">Category name used to route the log entry to a one or more trace listeners.</param>
		public static void Write(object message, Category category)
		{
			Write(message, category, DefaultPriority, DefaultEventId, DefaultSeverity, DefaultTitle, null);
		}

		/// <summary>
		/// Write a new log entry with a specific category and priority.
		/// </summary>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="category">Category name used to route the log entry to a one or more trace listeners.</param>
		/// <param name="priority">Only messages must be above the minimum priority are processed.</param>
        public static void Write(object message, Category category, Priority priority)
		{
			Write(message, category, priority, DefaultEventId, DefaultSeverity, DefaultTitle, null);
		}

		/// <summary>
		/// Write a new log entry with a specific category, priority and event id.
		/// </summary>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="category">Category name used to route the log entry to a one or more trace listeners.</param>
		/// <param name="priority">Only messages must be above the minimum priority are processed.</param>
		/// <param name="eventId">Event number or identifier.</param>
        public static void Write(object message, Category category, Priority priority, int eventId)
		{
			Write(message, category, priority, eventId, DefaultSeverity, DefaultTitle, null);
		}

		/// <summary>
		/// Write a new log entry with a specific category, priority, event id and severity.
		/// </summary>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="category">Category name used to route the log entry to a one or more trace listeners.</param>
		/// <param name="priority">Only messages must be above the minimum priority are processed.</param>
		/// <param name="eventId">Event number or identifier.</param>
		/// <param name="severity">Log entry severity as a <see cref="TraceEventType"/> enumeration. (Unspecified, Information, Warning or Error).</param>
        public static void Write(object message, Category category, Priority priority, int eventId, TraceEventType severity)
		{
			Write(message, category, priority, eventId, severity, DefaultTitle, null);
		}

		/// <summary>
		/// Write a new log entry with a specific category, priority, event id, severity
		/// and title.
		/// </summary>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="category">Category name used to route the log entry to a one or more trace listeners.</param>
		/// <param name="priority">Only messages must be above the minimum priority are processed.</param>
		/// <param name="eventId">Event number or identifier.</param>
		/// <param name="severity">Log message severity as a <see cref="TraceEventType"/> enumeration. (Unspecified, Information, Warning or Error).</param>
		/// <param name="title">Additional description of the log entry message</param>
        public static void Write(object message, Category category, Priority priority, int eventId,
								 TraceEventType severity, string title)
		{
			Write(message, category, priority, eventId, severity, title, null);
		}

		/// <summary>
		/// Write a new log entry and a dictionary of extended properties.
		/// </summary>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="properties">Dictionary of key/value pairs to log.</param>
		public static void Write(object message, IDictionary<string, object> properties)
		{
			Write(message, emptyCategoriesList, DefaultPriority,
				  DefaultEventId, DefaultSeverity, DefaultTitle, properties);
		}

		/// <summary>
		/// Write a new log entry to a specific category with a dictionary 
		/// of extended properties.
		/// </summary>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="category">Category name used to route the log entry to a one or more trace listeners.</param>
		/// <param name="properties">Dictionary of key/value pairs to log.</param>
        public static void Write(object message, Category category, IDictionary<string, object> properties)
		{
			Write(message, category, DefaultPriority, DefaultEventId, DefaultSeverity,
				  DefaultTitle, properties);
		}

		/// <summary>
		/// Write a new log entry to with a specific category, priority and a dictionary 
		/// of extended properties.
		/// </summary>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="category">Category name used to route the log entry to a one or more trace listeners.</param>
		/// <param name="priority">Only messages must be above the minimum priority are processed.</param>
		/// <param name="properties">Dictionary of key/value pairs to log.</param>
        public static void Write(object message, Category category, Priority priority, IDictionary<string, object> properties)
		{
			Write(message, category, priority, DefaultEventId, DefaultSeverity, DefaultTitle, properties);
		}

		/// <summary>
		/// Write a new log entry with a specific category, priority, event Id, severity
		/// title and dictionary of extended properties.
		/// </summary>
		/// <example>The following example demonstrates use of the Write method with
		/// a full set of parameters.
		/// <code></code></example>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="category">Category name used to route the log entry to a one or more trace listeners.</param>
		/// <param name="priority">Only messages must be above the minimum priority are processed.</param>
		/// <param name="eventId">Event number or identifier.</param>
		/// <param name="severity">Log message severity as a <see cref="TraceEventType"/> enumeration. (Unspecified, Information, Warning or Error).</param>
		/// <param name="title">Additional description of the log entry message.</param>
		/// <param name="properties">Dictionary of key/value pairs to log.</param>
        public static void Write(object message, Category category, Priority priority, int eventId,
								 TraceEventType severity, string title, IDictionary<string, object> properties)
		{
            CategoriesCollection categories = new CategoriesCollection();
            categories.Add(category);

            Write(message, categories, priority, eventId, severity, title, properties);
		}

		/// <summary>
		/// Write a new log entry to a specific collection of categories.
		/// </summary>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="categories">Category names used to route the log entry to a one or more trace listeners.</param>
        public static void Write(object message, CategoriesCollection categories)
		{
			Write(message, categories, DefaultPriority, DefaultEventId, DefaultSeverity, DefaultTitle, null);
		}

		/// <summary>
		/// Write a new log entry with a specific collection of categories and priority.
		/// </summary>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="categories">Category names used to route the log entry to a one or more trace listeners.</param>
		/// <param name="priority">Only messages must be above the minimum priority are processed.</param>
        public static void Write(object message, CategoriesCollection categories, Priority priority)
		{
			Write(message, categories, priority, DefaultEventId, DefaultSeverity, DefaultTitle, null);
		}

		/// <summary>
		/// Write a new log entry with a specific collection of categories, priority and event id.
		/// </summary>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="categories">Category names used to route the log entry to a one or more trace listeners.</param>
		/// <param name="priority">Only messages must be above the minimum priority are processed.</param>
		/// <param name="eventId">Event number or identifier.</param>
        public static void Write(object message, CategoriesCollection categories, Priority priority, int eventId)
		{
			Write(message, categories, priority, eventId, DefaultSeverity, DefaultTitle, null);
		}

		/// <summary>
		/// Write a new log entry with a specific collection of categories, priority, event id and severity.
		/// </summary>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="categories">Category names used to route the log entry to a one or more trace listeners.</param>
		/// <param name="priority">Only messages must be above the minimum priority are processed.</param>
		/// <param name="eventId">Event number or identifier.</param>
		/// <param name="severity">Log entry severity as a <see cref="TraceEventType"/> enumeration. (Unspecified, Information, Warning or Error).</param>
        public static void Write(object message, CategoriesCollection categories, Priority priority, int eventId, TraceEventType severity)
		{
			Write(message, categories, priority, eventId, severity, DefaultTitle, null);
		}

		/// <summary>
		/// Write a new log entry with a specific collection of categories, priority, event id, severity
		/// and title.
		/// </summary>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="categories">Category names used to route the log entry to a one or more trace listeners.</param>
		/// <param name="priority">Only messages must be above the minimum priority are processed.</param>
		/// <param name="eventId">Event number or identifier.</param>
		/// <param name="severity">Log message severity as a <see cref="TraceEventType"/> enumeration. (Unspecified, Information, Warning or Error).</param>
		/// <param name="title">Additional description of the log entry message</param>
        public static void Write(object message, CategoriesCollection categories, Priority priority, int eventId,
								 TraceEventType severity, string title)
		{
			Write(message, categories, priority, eventId, severity, title, null);
		}

		/// <summary>
		/// Write a new log entry to a specific collection of categories with a dictionary of extended properties.
		/// </summary>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="categories">Category names used to route the log entry to a one or more trace listeners.</param>
		/// <param name="properties">Dictionary of key/value pairs to log.</param>
        public static void Write(object message, CategoriesCollection categories, IDictionary<string, object> properties)
		{
			Write(message, categories, DefaultPriority, DefaultEventId, DefaultSeverity,
				  DefaultTitle, properties);
		}

		/// <summary>
		/// Write a new log entry to with a specific collection of categories, priority and a dictionary 
		/// of extended properties.
		/// </summary>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="categories">Category names used to route the log entry to a one or more trace listeners.</param>
		/// <param name="priority">Only messages must be above the minimum priority are processed.</param>
		/// <param name="properties">Dictionary of key/value pairs to log.</param>
        public static void Write(object message, CategoriesCollection categories, Priority priority, IDictionary<string, object> properties)
		{
			Write(message, categories, priority, DefaultEventId, DefaultSeverity, DefaultTitle, properties);
		}

		/// <summary>
		/// Write a new log entry with a specific category, priority, event Id, severity
		/// title and dictionary of extended properties.
		/// </summary>
		/// <example>The following example demonstrates use of the Write method with
		/// a full set of parameters.
		/// <code></code></example>
		/// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
		/// <param name="categories">Category names used to route the log entry to a one or more trace listeners.</param>
		/// <param name="priority">Only messages must be above the minimum priority are processed.</param>
		/// <param name="eventId">Event number or identifier.</param>
		/// <param name="severity">Log message severity as a <see cref="TraceEventType"/> enumeration. (Unspecified, Information, Warning or Error).</param>
		/// <param name="title">Additional description of the log entry message.</param>
		/// <param name="properties">Dictionary of key/value pairs to log.</param>
        public static void Write(object message, CategoriesCollection categories, Priority priority, int eventId,
								 TraceEventType severity, string title, IDictionary<string, object> properties)
		{
            LogEntry log = new LogEntry();
            log.Message = message.ToString();
            log.Categories = categories;
            log.Priority = priority;
            log.EventId = eventId;
            log.Severity = severity;
            log.Title = title;
            log.ExtendedProperties = properties;

			Write(log);
		}

		/// <summary>
		/// Write a new log entry as defined in the <see cref="LogEntry"/> parameter.
		/// </summary>
		/// <example>The following examples demonstrates use of the Write method using
		/// a <see cref="LogEntry"/> type.
		/// <code>
		/// LogEntry log = new LogEntry();
		/// log.Category = "MyCategory1";
		/// log.Message = "My message body";
		/// log.Severity = TraceEventType.Error;
		/// log.Priority = 100;
		/// Logger.Write(log);</code></example>
		/// <param name="log">Log entry object to write.</param>
		public static void Write(LogEntry log)
		{
            Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Writer.Write(log);
		}

		/// <summary>
		/// Returns the filter of type <typeparamref name="T"/>.
		/// </summary>
		/// <typeparam name="T">The type of filter requiered.</typeparam>
		/// <returns>The instance of <typeparamref name="T"/> in the filters collection, or <see langword="null"/> 
		/// if there is no such instance.</returns>
		public static T GetFilter<T>()
			where T : class, ILogFilter
		{
            return Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Writer.GetFilter<T>();
		}

		/// <summary>
		/// Returns the filter of type <typeparamref name="T"/> named <paramref name="name"/>.
		/// </summary>
		/// <typeparam name="T">The type of filter required.</typeparam>
		/// <param name="name">The name of the filter required.</param>
		/// <returns>The instance of <typeparamref name="T"/> named <paramref name="name"/> in 
		/// the filters collection, or <see langword="null"/> if there is no such instance.</returns>
		public static T GetFilter<T>(string name)
			where T : class, ILogFilter
		{
            return Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Writer.GetFilter<T>(name);
		}

		/// <summary>
		/// Returns the filter named <paramref name="name"/>.
		/// </summary>
		/// <param name="name">The name of the filter required.</param>
		/// <returns>The filter named <paramref name="name"/> in 
		/// the filters collection, or <see langword="null"/> if there is no such filter.</returns>
		public static ILogFilter GetFilter(string name)
		{
            return Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Writer.GetFilter(name);
		}

		/// <summary>
		/// Query whether logging is enabled.
		/// </summary>
		/// <returns><code>true</code> if logging is enabled.</returns>
		public static bool IsLoggingEnabled()
		{
            return Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Writer.IsLoggingEnabled();
		}

		/// <summary>
		/// Query whether a <see cref="LogEntry"/> shold be logged.
		/// </summary>
		/// <param name="log">The log entry to check</param>
		/// <returns>Returns <code>true</code> if the entry should be logged.</returns>
		public static bool ShouldLog(LogEntry log)
		{
            return Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Writer.ShouldLog(log);
		}

		/// <summary>
		/// Gets the instance of <see cref="LogWriter"/> used by the facade.
		/// </summary>
		/// <remarks>
		/// The lifetime of this instance is managed by the facade.
		/// </remarks>
		public static LogWriter Writer
		{ get { return Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Writer; } }

        //-----------------------------------------------------------------------------------------------------
        #endregion

        #region Custom Write methods
        //-----------------------------------------------------------------------------------------------------
        /// <summary>
        /// Write a new log entry with Category of Assert and Priority of Low
        /// </summary>
        /// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
        public static void WriteAssert(object message)
        {
            Write(message, Category.Assert, Priority.Low);
        }

        /// <summary>
        /// Write a new log entry with Category of Debug and Priority of Debug
        /// </summary>
        /// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
        public static void WriteDebug(object message)
        {
            Write(message, Category.Debug, Priority.Debug);
        }

        /// <summary>
        /// Write a new log entry with Category of Debug and Priority of Debug
        /// </summary>
        /// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
        /// <param name="properties">Dictionary of key/value pairs to log.</param>
        public static void WriteDebug(object message, IDictionary<string, object> properties)
        {
            Write(message, Category.Debug, Priority.Debug, properties);
        }

        /// <summary>
        /// Write a new log entry with Category of Debug and Priority of Debug. Use this overload if a LogEntry
        /// needed to be created for seeing whether the message would be logged.  The Category of the LogEntry 
        /// will be set to Debug (should already be set to this though) and the Priority will be set to Debug
        /// </summary>
        /// <param name="log">Log entry object to write.</param>
        public static void WriteDebug(LogEntry log)
        {
            if (!log.Categories.Contains(Category.Debug))
                log.Categories.Add(Category.Debug);
            log.Priority = Priority.Debug;

            Write(log);
        }

        /// <summary>
        /// Write a new log entry with Category of Trace and Priority of Trace. Only gets
        /// written in DEBUG build.
        /// </summary>
        /// <param name="step">A label for the step in the code being taced.</param>
        public static void WriteTrace(string step)
        {
#if DEBUG
            string message = "Trace: Step = '" + step + "' in method '" + GetExecutingMethodName() +
                ". Current activity = '" + Trace.CorrelationManager.ActivityId + "'.";
            Write(message, Category.Trace, Priority.Trace);
#endif
        }

        /// <summary>
        /// Write a new Information log entry.  This method is intended for writting to the Application
        /// Event Log so use a Category that will be written to the Application Event Log for the 
        /// appropriate Source.
        /// </summary>
        /// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
        /// <param name="category">Category name used to route the log entry to a one or more trace listeners.</param>
        /// <param name="eventId">Event number or identifier.</param>
        public static void WriteInformation(object message, Category category, int eventId)
        {
            Write(message, category, Priority.Low, eventId, TraceEventType.Information, "Information");
        }

        /// <summary>
        /// Write a new Information log entry.  This method is intended for writting to the Application
        /// Event Log so use a Category that will be written to the Application Event Log for the 
        /// appropriate Source.
        /// </summary>
        /// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
        /// <param name="category">Category name used to route the log entry to a one or more trace listeners.</param>
        /// <param name="eventId">Event number or identifier.</param>
        /// <param name="properties">Dictionary of key/value pairs to log.</param>
        public static void WriteInformation(object message, Category category, int eventId, IDictionary<string, object> properties)
        {
            Write(message, category, Priority.Low, eventId, TraceEventType.Information, "Information", properties);
        }

        /// <summary>
        /// Write a new Warning log entry.  This method is intended for writting to the Application
        /// Event Log so use a Category that will be written to the Application Event Log for the 
        /// appropriate Source.
        /// </summary>
        /// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
        /// <param name="category">Category name used to route the log entry to a one or more trace listeners.</param>
        /// <param name="eventId">Event number or identifier.</param>
        public static void WriteWarning(object message, Category category, int eventId)
        {
            Write(message, category, Priority.Medium, eventId, TraceEventType.Warning, "Warning");
        }

        /// <summary>
        /// Write a new Warning log entry.  This method is intended for writting to the Application
        /// Event Log so use a Category that will be written to the Application Event Log for the 
        /// appropriate Source.
        /// </summary>
        /// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
        /// <param name="category">Category name used to route the log entry to a one or more trace listeners.</param>
        /// <param name="eventId">Event number or identifier.</param>
        /// <param name="properties">Dictionary of key/value pairs to log.</param>
        public static void WriteWarning(object message, Category category, int eventId, IDictionary<string, object> properties)
        {
            Write(message, category, Priority.Medium, eventId, TraceEventType.Warning, "Warning", properties);
        }

        /// <summary>
        /// Write a new Error log entry.  This method is intended for writting to the Application
        /// Event Log so use a Category that will be written to the Application Event Log for the 
        /// appropriate Source.
        /// </summary>
        /// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
        /// <param name="category">Category name used to route the log entry to a one or more trace listeners.</param>
        /// <param name="eventId">Event number or identifier.</param>
        public static void WriteError(object message, Category category, int eventId)
        {
            Write(message, category, Priority.High, eventId, TraceEventType.Error, "Error");
        }

        /// <summary>
        /// Write a new Error log entry.  This method is intended for writting to the Application
        /// Event Log so use a Category that will be written to the Application Event Log for the 
        /// appropriate Source.
        /// </summary>
        /// <param name="message">Message body to log.  Value from ToString() method from message object.</param>
        /// <param name="category">Category name used to route the log entry to a one or more trace listeners.</param>
        /// <param name="eventId">Event number or identifier.</param>
        /// <param name="properties">Dictionary of key/value pairs to log.</param>
        public static void WriteError(object message, Category category, int eventId, IDictionary<string, object> properties)
        {
            Write(message, category, Priority.High, eventId, TraceEventType.Error, "Error", properties);
        }
        //-----------------------------------------------------------------------------------------------------
        #endregion

        #region Private methods
        //-----------------------------------------------------------------------------------------------------
        /// <summary>
        /// Finds the first method back in the stack trace that is not a method in this class
        /// </summary>
        /// <returns>The first method back in the stack trace that is not a method in this class</returns>
        private static string GetExecutingMethodName()
        {
            string result = "Unknown";
            StackTrace trace = new StackTrace(1, false);

            for (int index = 0; index < trace.FrameCount; ++index)
            {
                StackFrame frame = trace.GetFrame(index);
                MethodBase method = frame.GetMethod();
                if (method.DeclaringType != typeof(Logger))
                {
                    result = method.DeclaringType + "." + method.Name;
                    break;
                }

            }

            return result;
        }
        //-----------------------------------------------------------------------------------------------------
        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


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

Comments and Discussions