ost applications need to write log messages at different layers of the application for instrumentation, debugging, or monitoring purposes. Generally, developers write code to log these messages to an external store such as an event log, a database, an external flat file, or an XML file. Logging typically requires a lot of reusable boilerplate code to construct an effective application logging functionality. Fortunately, you no longer have to create logging code manually. The patterns and practices team at Microsoft, realizing the need for a reusable logging capability, created the logging block and made it an integral component of Enterprise Library 3.0. This article introduces the logging block by providing and explaining examples that use it to write robust and fault-tolerant .NET applications.
The logging block provides a flexible and extensible logging mechanism that you can use in any type of .NET application?including Windows Forms applications, ASP.NET applications, console applications, and so on. By default, it ships with a number of reusable logging classes (also known as trace listeners) that can store log information to a wide range of external sources, including databases, XML files or flat files, MSMQ, a specified event log, and so on.
As a developer enabling basic logging functionalities, you just need to choose a trace listener and declaratively specify your choice in the application’s configuration file; then you can make logging calls from the application?the rest is all handled for you.
After installing Enterprise Library 3.1 May 2007 edition, you’ll find the exception handling block assemblies in the
![]() | ? |
Figure 1. Logging Block Dependencies: The trace listeners register the log entries to the appropriate log destinations. In addition to the core assemblies, the logging block also references the data access block for logging data in a database. |
To be able to use the basic features of logging block, you need to reference the Microsoft.Practices.EnterpriseLibrary.Common.dll, and Microsoft.Practices.EnterpriseLibrary.Logging.dll assemblies. If you intend to log information to a database, you also need to reference the Microsoft.Practices.EnterpriseLibrary.Data.dll assembly. Figure 1 shows the dependencies of the logging block.
Build a Simple Example
Here’s a simple example that explores the steps involved in configuring the logging block to log messages to the event log. To begin, create a new Visual C# Windows Application named LoggingBlockExample. After creating the project, add references to the Microsoft.Practices.EnterpriseLibrary.Common.dll and Microsoft.Practices.EnterpriseLibrary.Logging.dll assemblies by navigating to the
After that, import the following core logging namespace:
using Microsoft.Practices.EnterpriseLibrary.Logging;
Next, add the configuration settings to the application configuration (app.config) file to specify the event log as the logging destination (see Listing 1). All the required logging entries reside within the
- listeners?Lets you specify the trace listeners to which log entries are routed.
- formatters?This optional element allows you to specify the format of the log entry produced by the format-aware trace listeners.
- categorySources?Allows you to specify the sources that are responsible for mapping specific categories to their corresponding trace listeners. Note that one of the categories in the
element is referenced in the defaultCategory attribute in the element. - specialSources?Lets you specify special trace sources that can process specific types of log entries.
With the app.config file settings in place, the next step is to write code against the logging block. First, import the core logging namespace as shown below:
using Microsoft.Practices.EnterpriseLibrary.Logging;
Next, open the Windows form, add a command button named btnLogMessage, and modify its Click event handler so it matches the following code:
private void btnLogMessage_Click(object sender, EventArgs e) { //Create an LogEntry object and set its properties LogEntry entry = new LogEntry(); entry.EventId = 1; entry.Priority = 1; entry.Message = "This is a test message"; entry.Categories.Clear();![](http://assets.devx.com/articlefigs/21443.jpg)
? Figure 2. Event Log Message: Output such as this is typical for logged messages viewed through the Application category of the Windows Event Viewer.
//Note that the default category is General entry.Categories.Add("General"); Logger.Write(entry); MessageBox.Show("Log is written"); }
The preceding code uses two important logging classes: LogEntry and Logger. LogEntry represents a single log entry, so the class exposes properties such as the priority of the log message, event id, log message, and so on. Logger exposes methods for writing the log message to one or more trace listeners as identified in the configuration file.
To write a log message, you create a LogEntry instance and populate its properties appropriately. A LogEntry lets you specify one or many categories under which the message may be logged through the appropriate trace listeners.
Figure 2 shows the log entry in the event log when you click on the “Log Message” button in the sample application.
Using the Enterprise Library Configuration Tool
Although you can manually configure the logging entries in the app.config file as discussed in the preceding section, you’ll be glad to know that it’s far easier if you use the Configuration Tool that ships with Enterprise Library.
To do that, open the Enterprise Library Configuration tool, create a new application, and then right-click on Application Configuration and select New ? Logging Application Block (see Figure 3).
![]() | ? |
Figure 3. Enterprise Library Configuration Tool: This tool lets you specify the logging configuration settings using a wizard. |
The logging block configuration schema consists of four key elements named Category Sources, Special Sources, Trace Listeners, and Formatters. By default, the logging application block creates a Formatted EventLog TraceListener entry and configures it as the category source with the Text Formatter as the default formatter.
Here’s how to set up a new XML log through the Configuration Tool. Right-click the Trace Listeners node and select New ? XML Trace Listener from the context menu. After creating the new listener, change the file name property on the right-hand pane to C:TempTrace.xml.
The next step is to reference the new listener from the event sources. Right-click the All Events node and select New ? Trace Listener Reference from the context menu. After creating the trace listener reference, set the ReferencedTraceListener property on the right pane to XML Trace Listener. When you’ve finished the changes, the wizard should show output similar to Figure 4.
|
|
Save the configuration settings from the Configuration Tool as app.config. If you now include the generated app.config file in your existing C# project example, you’ll see XML generated in the log file (see Figure 5).
That’s all you have to do to enable simple logging scenarios using the Configuration Tool.
Using a Database as the Log Store
You’ve explored the steps involved in writing log information to an event log and an XML file. Although this approach works for most simple scenarios, for more complex applications, you might want to write the log information to a persistent data store such as a SQL Server database. Logging to a database makes it easy to write queries against the logged messages for troubleshooting purposes. The logging block comes bundled with an out-of-the-box database trace listener that is capable of writing to a data store.
To use the database-driven logging, you first need to execute a SQL script (supplied with Enterprise Library) to create the logging database. Run the LoggingDatabase.sql file that you’ll find in the
Now, you need to modify your app.config file to use the “Database Trace Listener.” You will also need to specify the database connection string. Listing 2 shows a complete example configuration file.
Author’s Note: Make sure to edit the connection string in the |
Next, open the Windows Forms application created in the previous section and simply switch the existing app.config file with the app.config you just created. Run the sample application again. This time, after clicking the button to execute the logging code, if you open the Log table in the Logging database, you will see the created log entry.
Implementing Custom Trace Listeners
If the built-in trace listeners prove insufficient to meet your needs, the logging block lets you implement custom trace listeners by deriving from the CustomTraceListener class. That customization is beyond the scope of this article, but you can find more information in this MSDN article.
You’ve seen how adding the logging block lets you create flexible and easy-to-maintain logging code in .NET applications, using configuration and straightforward code to log messages to files, event logs, and SQL Server. Sure, the configuration’s a little verbose, but that sure beats writing repetitive code, or worse, changing your code just to switch log stores. And because the Enterprise Library Configuration Tool makes the configuration a wizard-driven instead of a memorize-and-pray procedure, you should now have little trouble adding robust logging to all your applications.