Enterprise Library - Logging and Instrumentation Application Block - Patterns and Practices

Another useful application block that is part of the Enterprise Library is the Logging and Instrumentation Application Block.  It allows you to log events in your applications to various locations, such as a database, the event log, email, a flat file, etc.

As you can see from the snapshot of the configuration tool below, I created a single location to store all my events - a flat file.  It is the MessageLogSink, which stores messages in a file I decided to call message.log.

 

Logging Application Block

 

For testing purposes, I decide to group all my events into 5 categories:

  • Debug
  • Exception
  • General
  • Performance
  • Security

You have to assign one of the categories as default, so I assigned General as default.  Each category can be assigned to one of more sinks.  Thus you could have events of type Exception not only stored to a text file, but also sent to you via email, placed in the event log, etc.  In my case, I just assigned them all to MessageLogSink that saves messages to message.log.

How you organize your categories is fairly important because you not only have the ability to channel categories to one or more different locations, but you also have the ability to filter on categories.  For example, when you first start building the application you will probably want to see all events of type Debug.  However, when the application gets closer to production or into production, you will probably want to turn off a lot of the Debug messages.  You can also filter on Priority as well, so one needs to think out the strategy on how you organize the events and the priority of the events within each category so that you can minimize the logging as the application becomes more mature.

The Logging and Instrumentation Application Block is called within your application using a simple Logger.Write(...) call that has several overloads where you can pass parameters:

 

Logger.Write
public static void Write(object message)
public static void Write(object message, string category)
...
public static void Write(LogEntry log)

 

The parameters are as such:

  • Message
  • Category
  • Priority
  • Title
  • EventID
  • Severity
  • etc...

These values are all neatly placed in a type of LogEntry that gets distributed (after filtering) to each Sink on a category-by-category basis via the Interface ILogSink.

 

ILogSink Interface
public interface ILogSink
{
    /// 
    /// Send message to log sink handler.
    /// 
    /// xmlMessage as string
    void SendMessage(LogEntry log);

    /// 
    /// Sets the formatter to be used by this sink.
    /// 
    ILogFormatter Formatter { get; set; }
}

 

The formatter you see mentioned above is also configurable per sink and category and just specifies what you want the message to look like and what information you want it to contain.

After I finished creating the configuration files, I created a quick test application in Snippet Compiler as shown below.  To stay somewhat consistent on how I use the categories and set priorties, etc., I derived more specific category-based LogEntry classes from LogEntry.  This is totally unnecessary as I was just playing.

Read more.

posted on Thursday, March 17, 2005 5:07 PM

Main

News

Green Tea

.NET Development

Enterprise Library

Patterns & Practices