When developing an application it’s possible to use debug mode to figure out why something is wrong, but when it’s time to deploy the application something else has to be integrated. To solution to this is logging. Implementing good logging functionality will make the Operations people who have to deploy your application happy as well, because they can integrate it into existing monitoring systems.
Enterprise Library was used to implement a flexible logging solution. Thanks to the
Logging and Instrumentation Application Block it’s possible to integrate logging into your code, but decide where to output the log externally from the application. This way it’s possible to log to a flat file, a database, an email address, the event log, a message queue, WMI and custom implementations, without having to change code.
A
Logging project was added to start, to provide some helper constants:
using System;
namespace MediaService.Logging {
public struct Priority {
public const Int32 Lowest = 0;
public const Int32 Low = 1;
public const Int32 Normal = 2;
public const Int32 High = 3;
public const Int32 Highest = 4;
} /* Priority */
public struct Category {
public const String Player = "Player";
public const String Remoting = "Remoting";
public const String Data = "Data";
public const String SqlServer = "SqlServerData";
} /* Category */
} /* MediaService.Logging */
After this, a reference to the
Logging project was added together with a reference to
Microsoft.Practices.EnterpriseLibrary.Logging. A reference to the
Enterprise Library Configuration Application Block was needed as well.
At this point it was possible to log messages by using the following construct:
if (randomSong == null) {
Logger.Write("Unable to select a random song.", Category.Player,
Priority.High, 1, Severity.Error);
} else {
Logger.Write(String.Format("Fetched song: {0} (Random).", randomSong.Path),
Category.Player, Priority.Low, 1, Severity.Information);
}
Similar code had been added throughout the code to provide meaningful feedback. The only thing left was configuring where the log output had to go.
Using the
Enterprise Library Configuration tool, an existing
App.config was loaded and the
Logging and Instrumentation Application Block was added. Under
Client Settings,
LoggingEnabled was to
True.
A new category had to be added, called
Player, by right clicking on
Categories and selecting
New – Category. This is the name that was used in the code to specify which log the output belongs to. It was possible to define multiple categories.
To define where the output had to go to, a new sink was added, called
Player Flat File Sink, by right clicking on
Sinks and selecting
New – Flat File Sink.
Player.log was chosen as a filename, without a header.
Formatters are used to define how a single log entry had to look. By default a
Text Formatter was provided, which included extensive information. To have an overview log file, a new formatter was added by right clicking
Formatters and selecting
New – Text Formatter. The template for this
Simple Text Formatter was the following:
{severity}
[{timestamp}]: {message}
Finally a new destination was added by right clicking the
Player category and selecting
New – Destination. This destination was configured to use the
Simple Text Formatter together with the
Player Flat File Sink.
After this, the
loggingconfiguration.config and
loggingdistributorconfiguration.config files had to be copied in the
Post-build event as well. At this point, the application had implemented a flexible logging strategy, where an administrator could easily decide to turn logging on or off and where the log output had to go to and which template had to be used.