The design of the Logging Application Block involves several elements such as log message, category, logging destination/target and the format in which the information has to be logged. Additionally, we may have filters to enable/disable logging based on certain criteria.
The design elements of the Logging Application Block are as follows:
LogEntry
Logger
LogWriter
We will now explore the technical details of each one of these design elements.
The very basic information for a log entry is the log message; additionally it may have other information such as Title, Priority, Categories, EventId, Severity, ActivityId, TimeStamp
, and so on. The LogEntry
class part of the Microsoft.Practices.EnterpriseLibrary.Logging
namespace holds all this information, which can be passed on to the Write
method of a Logger
or LogWriter
instance. We have not used the LogEntry
while writing our first log message; the Write
method provides several overloads, which can be used to pass as little information as we want and simplify the task of logging. However LogWriter
internally creates a LogEntry
object with the details provided in the respective overloaded Write
method.
The following screenshot shows the class diagram of LogEntry, XmlLogEntry
, and TraceLogEntry.
The LogEntry
class inherits from the ICloneable
interface and so it supports cloning; the Clone
method can be called to create a new LogEntry
object that is a copy of the current instance. The XmlLogEntry
class inherits from the LogEntry
class; it provides support to log messages in XML format, and the XmlTraceListener
class leverages XmlLogEntry
to deliver the trace data as XML. A LogEntry
object can be constructed using several different constructors that accept several parameters, apart from which it exposes several public properties that can be assigned. Many of these properties such as MachineName, ProcessId, ProcessName
, and so on are initialized internally if the value is not assigned explicitly. A special mention to ExtendedProperties
, this property allows us to add additional information to the log entry and is quite handy to log custom information.
The following is a list of the properties of the LogEntry
class for your quick reference. Values of these properties will be part of the generated log entry in the configured destination (file, database, e-mail address, and so on).
Property |
Type |
Description |
---|---|---|
|
|
Gets or sets the title of the log message; by default this property is set to |
|
|
Gets or sets the message body to log; by default this property returns |
|
|
Gets or sets the category name as a collection of strings; this information will be used to route the log entry to one or more trace listeners. |
|
|
This read-only property returns categories as a string array; this property is available to support WMI queries. |
|
|
Gets or sets the priority or importance of the log message; by default it is -1. It is to be noted that only messages satisfying the priority filter configuration of minimum and maximum priorities (inclusive) will be processed. |
|
|
Gets or sets the severity of type |
|
|
This read-only property returns the string representation of Severity, which is of type |
|
|
Gets or sets the event number or identifier. |
|
|
Holds tracing activity id; a |
|
|
This read-only property returns a string representation of the tracing activity id to support WMI queries. |
|
|
Gets or sets the related activity id; by default this property is |
|
|
Gets or sets the |
|
|
Gets or sets the machine name; if this property is not set then the current name of the machine ( |
|
|
Gets or sets the name of the .NET thread; if this property is not set then the current thread name ( |
|
|
Gets or sets the Win32 process ID; if this property is not set then the Win32 process ID for the current running process will be used. |
|
|
Gets or sets the process name; if this property is not set then the process name of the current running process will be used. |
|
|
Gets or sets the Win32 thread id; if this property is not initialized then it will automatically return the Win32 thread id of the current thread provided unmanaged code permission is available. |
|
|
Gets or sets the date and time of the log entry message; if this property is not initialized then it will automatically return |
|
|
This read-only property returns the string representation of the |
|
|
This read-only property returns as |
|
|
Gets or sets additional properties through a dictionary of key-value pairs. |
While writing our first log message we leveraged the LogWriter
. Alternatively we can also use the Logger
class. The Logger
class is a static façade to write log enties to one or more logging destinations (trace listeners). This class is part of the Microsoft.Practices.EnterpriseLibrary.Logging
namespace and was used in the previous versions to perform logging using the exposed methods, primarily the Write
method.
The following class diagram screenshot depicts the exposed properties and methods of the Logger
class.
The Logger
class exposes several methods not only to write log messages but also to perform supporting actions. The following is a list of the methods and brief summary of each method:
Method Name |
Description |
---|---|
|
The |
|
This method is useful to query whether a |
|
This method queries whether logging is enabled and returns |
|
There are three |
|
This method accepts two parameters: key and value of type |
|
Calling this method will empty the context items dictionary. |
|
The |
Since Logger
is a static façade class, we can start calling the methods mentioned in the previous table without creating an instance. Internally, it creates a local instance of LogWriter
using EnterpriseLibraryContainer.Current.GetInstance<LogWriter>()
and forwards all the actions to the LogWriter
instance.
The following code snippets demonstrate the usage of different overloads of the Write
method of the Logger
class.
Logging using the default category:
Logger.Write("Log Message");
Logging using a specific category:
Logger.Write("Log Message", "LOG CATEGORY");
Passing a little more information:
//Message | Category | Priority | EventId | Severity | Title Logger.Write("Log Message", "LOG CATEGORY", 1, 1234, TraceEventType.Critical, "Log Title");
There are in total nineteen overloaded Write
methods, each accepting a different set of parameters and helping us construct the LogEntry
object internally using the information provided by us.
We have already explored the usage of LogWriter
while writing our first log message. Basically, LogWriter
is an abstract class and is the primary interface in this release for creating log entries; this abstract class belongs to the Microsoft.Practices.EnterpriseLibrary.Logging
namespace. EnterpriseLibraryContainer
has the mapping information that resolves the type (LogWriter) and creates an instance of LogWriterImpl
. The LogWriter
instance can be created using the dependency injection approach or if required, the concrete implementation LogWriterImpl
can be used directly as well. The LogWriter
instance writes log messages based on the configuration and the messages are routed to the respective logging destinations (trace listeners) based on category.
The following screenshot shows the methods exposed by LogWriter
, and inheritance details of LogWriterImpl
and the LogWriterFactory
class.
The LogWriter
class also exposes several methods and some of them perform the same actions as with the Logger
class. There are few additional methods that are not available in the Logger
class. The following is a list of the methods and a brief summary of each method.
Method Name |
Description |
---|---|
|
The |
|
This method is useful to query whether a |
|
This method queries whether logging is enabled and returns |
|
This method queries whether tracing is enabled and returns |
|
There are a total of three |
|
This method accepts two parameters, key and value of type |
|
Calling this method will empty the context items dictionary. |
|
This method returns |
We used the simplest overload of the Write
method while logging our first log message. To demonstrate the power of the other overloads, we will explore two more overloaded options. One of the overloads allows us to pass message, title, category, priority, event id, and severity. This overload allows writing a log entry with the value specified for several key elements.
The following code snippet calls the Write
method that accepts Message, Category, Priority, EventId, Severity
, and Title
.
//Writes a new log entry with the specified category, priority, event id, severity and title logWriter.Write("Log Message", "Log Category", 1, 1234, TraceEventType.Information, "Log Title");
So far we haven't explored the usage of the LogEntry
class; we can construct a LogEntry
instance with the values for one or more key elements and pass it to the overloaded Write
method of the LogWriter
instance.
The following is a code snippet that constructs a LogEntry
instance and calls the Write
method.
//Create new LogEntry object LogEntry logEntry = new LogEntry(); //Assign the category logEntry.Categories = new string[] { "UI Events" }; //Assign title logEntry.Title = "Log Title"; //Assign message logEntry.Message = "Log Message"; //Assign priority logEntry.Priority = 1; //Assign severity logEntry.Severity = TraceEventType.Information; //Writes a new log entry using the LogEntry instance logWriter.Write(logEntry);
So far we have been using the default category (General) to log messages, which was added automatically while setting up the Logging block settings. Now, let us understand the concept behind Trace Source Categories and learn to add and configure new categories. While logging in our application code, we provide one or more category under which the log entry will be logged. Categories allow us to group together a set of log messages. This helps us in controlling the logging behavior such as log destination, log format, and enabling/disabling logging through log filters. These categories can be associated with one or more logging target listeners (log destinations).
We can configure two types of categories:
The following class diagram depicts the exposed properties and methods of the LogSource
class:
Special categories are nothing but out-of-the-box category sources provided by the Logging Application Block. We cannot add additional categories or remove these sources but we can provide one or more log destination (trace listener) to the special category source.
The following table lists the three special categories and their descriptions.
Special Category |
Description |
---|---|
All Events |
If this special category is configured then regardless of other matching categories, the log entry will be traced through the log source. |
Unprocessed Category |
If All Events special category is not configured and this category is configured and the category specified in the |
Logging Errors & Warnings |
If both All Event and Unprocessed Category are not configured and the property Warn If No Category Match in Logging Settings is set to true then the log entry will be logged to this special category. |
Logging a message with defined categories not only gives more context to the message but also allows finer control over it while deciding whether to turn on/off logging for a particular category. It is a good practice to decide the logging categories (for example, Debug, Trace, UI Events, Data Access Events, and so on) beforehand instead of logging into the default category (General). Category sources are defined in the configuration settings as part of the Logging Application Block configuration; a default category is also set while adding the configuration using the Enterprise Library configuration tool.
Let us add a new category in the categories section of the Logging Settings. Click on the plus symbol provided in the Categories section. Next, click on the Add Category menu item, a new category with default values will be loaded in the configuration tool as seen in the following screenshot.
We will add a category named UI Events; for the purposes of the demonstration the category name has been updated to UI Events. The following screenshot displays the newly added category:
Note that the default Event Log Trace Listener is mapped by clicking on the plus symbol against the Listeners and selecting the Event Log Trace Listener from the drop-down list.
The following is the list of configurable properties and their description:
Property |
Description |
---|---|
Name |
Category name, used to identify this category. By default this property is set to "Category" or if the name already exists then the configuration tool appends the number 2, 3, 4 and so on. |
Auto Flush |
Indicates whether Logging Target Listeners will automatically flush messages and write the log entries as soon as they are received. Setting it to False will buffer the log entries and they will be written in batches or when a significant event occurs such as machine shutting down. By default this property is set to True. |
Listeners |
Allows adding one or more Logging Target Listeners for this category; log entries will be sent to the configured listeners provided they meet the minimum severity. We have to explicitly configure the listeners. |
Minimum Severity |
Indicates the minimum severity level required to log the message. By default it is set to All. |
Trace listeners determine where exactly the log entry will be sent for storage, each trace source category may be associated with one or more trace listeners. Several trace listeners are available out of the box to meet varied requirements; these inherit from the abstract class called TraceListener
, part of the System.Diagnostics
namespace. Apart from the trace listeners provided by the Logging Application Block, .NET Framework also provides several trace listeners. The Logging block provides additional formatting functionality, which is not available with the .NET Framework trace listeners as they only send strings not a LogEntry
object. The following class diagram shows the base classes through which several trace listeners are derived and additional functionality is implemented.
Trace listeners such as FormattedEventLogTraceListener
, the FlatFileTraceListener
, and the WMITraceListener
use the same configuration information as System.Diagnostics
trace listeners. This means we can leverage these three trace listeners provided as part of the<system.diagnostics>
configuration section. Several trace listeners have common properties that can be configured; these properties are explained next:
Property Name |
Description |
---|---|
Name |
Used to identify an item. |
Severity Filter |
This setting determines the minimum severity of message that will be sent to the logging target. Below are the options for this setting; the default setting is All.
|
Trace Output Options |
Trace listeners that do not output to a Text Formatter use this setting to determine the elements/options to be included in the trace output. Below are the possible values; by default none of the values is included.
|
Although we have already seen this trace listener in action as it is part of the default configuration, which was used while writing our first log message, we haven't yet explored the design elements and the available configuration options. Logging formatted messages to the Windows Event Log is provided by the FormattedEventLogTraceListener
class and is part of the Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners
namespace. This class inherits from the abstract class FormattedTraceListenerWrapperBase
. The FormattedEventLogTraceListener
class internally creates an instance of System.Diagnostics.EventLogTraceListener
and passes on to its base class.
The Logging block creates the event log source if it does not exist; since creation of event log source requires appropriate privileges (access rights to the registry key HKLMSystemCurrentControlSetServicesEventLog)
the application/component must run with those privileges. Alternatively, the event log source can be created while installing the application/component under an account with the required privileges.
The following screenshot depicts the default settings without any association to the log formatter.
The following table provides a listing of all the configurable properties and their description. It will help in modifying the default behavior of the Formatted Event Log Trace Listener.
Property |
Description |
---|---|
Name |
Logging target listener name used to identify this item. |
Formatter Name |
Name of the log message formatter; the drop-down list allows selecting the currently added log message formatters. |
Log Name |
Indicates the name of the Windows Event Log such as Application or System to which the log messages will be written. |
Machine Name |
Name of the machine to which the log messages should be written; the default value is "." denoting the local machine. |
Severity Filter |
Indicates the minimum severity of messages that should be processed and sent to the logging target. |
Source Name |
Source name to be used while writing to the Windows Event Log; the default value is Enterprise Library Logging. |
Trace Output Options |
Determines the elements included in the trace output for listeners that do not output to a Text Formatter. The default value is None and this property is optional. |
This trace listener writes log entries to a flat file using the configured log formatter. The FlatFileTraceListener
class is part of the Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners
namespace and inherits from the FormattedTextWriterTraceListener
class.
Flat File Trace Listener allows to output log messages to a disk file. The following is a screenshot of the default configuration setting:
The following table lists the configuration properties and their description:
Property |
Description |
---|---|
Name |
Logging target listener name used to identify this item. |
File Name |
Path and file name for the log file, using environment variables such as |
Formatter Name |
Name of the log message formatter, the drop-down list allows selecting the currently added log message formatters. |
Message Footer |
Footer text to be added to the log message. |
Message Header |
Header text to be added to the log message. |
Severity Filter |
Indicates the minimum severity of messages that should be processed and sent to the logging target. |
Trace Output Options |
Determines the elements included in the trace output for listeners that do not output to a Text Formatter. The default value is None and this property is optional. |
While logging to a flat file is a good option, sometimes we might want to log to new file based on the size or age of the file. The Rolling Flat File Trace Listener provides this functionality by allowing us to configure the size and time thresholds. The RollingFlatFileTraceListener
class is part of the Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners
namespace and it inherits from the FlatFileTraceListener
class. The Rolling Flat File Trace Listener provides several properties to tweak the behavior of the listener through configuration.
The following screenshot displays the default configuration settings.
The list of properties and their description is given next. These properties can be configured to tweak the behavior of the Rolling Flat File Trace Listener.
Property |
Description |
---|---|
Name |
Logging target listener name used to identify this item. |
File Exists Behavior |
Determines whether to overwrite the file or create a new file using a name created using the timestamp when it rolls over. |
File Name |
Path and file name for the log file, using environment variables such as |
Formatter Name |
Name of the log message formatter; the drop-down list allows selecting the currently added log message formatters. |
Max Archived Files |
This property specifies the maximum number of log files to be retained; when the number of log files exceeds the specified number the listener will purge the old files based on the file creation date. |
Message Footer |
Footer text to be added to the log message. |
Message Header |
Header text to be added to the log message. |
Roll Interval |
Determines the log file roll-over interval; the default value is None. Options include:
|
Roll Size KB |
Determines the maximum log file size (in kilobytes) before rolling over. |
Severity Filter |
Indicates the minimum severity of messages that should be processed and sent to the logging target. |
Timestamp Pattern |
Specifies the date/time format to be used to suffix the file name. |
Trace Output Options |
Determines the elements included in the trace output for listeners that do not output to a Text Formatter. The default value is None and this property is optional. |
This trace listener as the name suggests writes the log message to a file in XML form. The XmlTraceListener
class is part of the Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners
namespace and it inherits from the XmlWriterTraceListener
class available in the System.Diagnostics
namespace. It does not require a log formatter as it internally formats LogEntry
or any class derived from LogEntry
into an XML string using the XmlLogFormatter
class.
XML Trace Listener configuration consists of three key properties: File Name, Severity Filter
, and Trace Output Options
, which might be modified to change the respective behavior.
The following screenshot shows the default settings of the XML Trace Listener:
The following table listing shows the configurable properties and their descriptions.
Property |
Description |
---|---|
Name |
Logging target listener name used to identify this item. |
File Name |
Path and file name for the log file, using environment variables such as |
Severity Filter |
Indicates the minimum severity of messages that should be processed and sent to the logging target. |
Trace Output Options |
Determines the elements included in the trace output for listeners that do not output to a Text Formatter. The default value is None and this property is optional. |
As the name suggests, this trace listener writes log messages to a database formatting the output using the configured log formatter. The FormattedDatabaseTraceListener
class is part of the Microsoft.Practices.EnterpriseLibrary.Logging.Database
namespace and it inherits from an abstract class named FormattedTraceListenerBase
. The Logging block provides the database table schema and stored procedures to log messages in the database; the database script LoggingDatabase.sql
and Windows command script CreateLoggingDb.cmd
are available in the default source folder (EntLib50SrcBlocksLoggingSrcDatabaseTraceListenerScripts
). Although the sql script generates a database named Logging, the script can be modified to create tables and stored procedures in our custom database as well. By default the command file generates the database, tables, and stored procedures in local instance of SQL Server Express; this can be customized in the command script file.
Database Trace Listener configuration involves setting of Database Instance and Formatter at the bare minimum; other properties might be modified to change their respective behavior.
The next screenshot shows the default settings of the Database Trace Listener:
The following table listing shows the configurable properties and their description:
Property |
Description |
---|---|
Name |
Logging target listener name used to identify this item. |
Add Category Procedure |
Name of the stored procedure that creates a new category in the tables; the default value is AddCategory, which is generated by the script provided in the source folder of database logging. |
Database Instance |
Name of the database instance to be used for logging messages. |
Formatter Name |
Name of the log message formatter; the drop-down list allows selecting the currently added log message formatters. |
Severity Filter |
Indicates the minimum severity of messages that should be processed and sent to the logging target. |
Trace Output Options |
Determines the elements included in the trace output for listeners that do not output to a Text Formatter. The default value is None and this property is optional. |
Write To Log Procedure |
Name of the stored procedure that inserts log messages into the tables; the default value is WriteLog, which is generated by the script provided in the source folder of database logging. |
The e-mail trace listener provides the ability to send log entries as e-mail messages to the specified e-mail address. This trace listener is feature-packed; it allows setting the authentication mode, from address, SMTP port and server, SSL mode, and so on. The EmailTraceListener
class provides the implementation for this functionality; it inherits from the FormattedTraceListenerBase
abstract class and both are part of the Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners
namespace. Email Trace Listener configuration involves setting of several properties that are mandatory for the functioning of this trace listener.
The following screenshot shows the default setting of the Email Trace Listener:
The following table listing shows the configurable properties and their description:
Property |
Description |
---|---|
Name |
Logging target listener name used to identify this item. |
Authentication Mode |
Determines how the listener will authenticate the user. The default value is None. Options include:
|
Authentication User Name |
User name to use for authentication while sending e-mail messages. |
Authentication Password |
Password to use for authentication for the specified user name. |
Formatter Name |
Name of the log message formatter; the drop-down list allows selecting the currently added log message formatters. |
From Address |
E-mail address to be used to send the e-mail messages from. |
Severity Filter |
Indicates the minimum severity of messages that should be processed and sent to the logging target. |
Smtp Port |
Specifies the Smtp port to be used to send the e-mail message; the default value is 25. |
Smtp Server |
Specifies the Smtp server name or IP address to be used to send the e-mail message; the default IP address is 127.0.0.1 (local host). |
Subject Line Prefix |
Prefix to add at the start of the e-mail subject. |
Subject Line Suffix |
Suffix to add to the end of the e-mail subject. |
To Address |
The address to send the log entry e-mail to. |
Trace Output Options |
Determines the elements included in the trace output for listeners that do not output to a Text Formatter. The default value is None and this property is optional. |
Use SSL |
Determines whether to use Secure Socket Layer (SSL). |
The System Diagnostics Trace Listener is an interesting trace listener; it provides the Type Name property to configure the trace listener to be used from the list of available trace listeners. The following screenshot displays the default settings of this trace listener.
Apart from the common properties, the previous screenshot has two interesting properties. The Type Name property allows us to assign the fully qualified type name of the trace listener to be used while writing log messages. The InitData property allows us to pass initialization data to the configured trace listener.
The following table listing shows the configurable properties and their description:
Property |
Description |
---|---|
Name |
Logging target listener name used to identify this item. |
InitData |
The value provided in this property will be passed on to the configured trace listener as initialization data. |
Severity Filter |
Indicates the minimum severity of messages that should be processed and sent to the logging target. |
Trace Output Options |
Determines the elements included in the trace output for listeners that do not output to a Text Formatter. The default value is None and this property is optional. |
Type Name |
Fully qualified type name of the trace listener to be used to write log messages. |
The following screenshot shows the type selection dialog box with the list of available trace listeners derived from TraceListener:
We can select any trace listener from the list as shown in the above screenshot, for example selecting ConsoleTraceListener
will write all messages to Console.Out
or Console.Error
.
The Message Queuing Trace Listener sends the log entries to the configured Msmq instance; the MsmqTraceListener
class inheriting the FormattedTraceListenerBase
abstract class, both part of the Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners
namespace, provides the implementation for this functionality.
The following screenshot displays the default settings of Message Queuing Trace Listener.
The following table provides the list of configurable properties and their description.
Property |
Description |
---|---|
Name |
Logging target listener name used to identify this item. |
Formatter Name |
Name of the log message formatter; the drop-down list allows selecting the currently added log message formatters. |
Message Priority |
This property sets the priority of a log entry; while in transit the message priority determines where the log entry is inserted into its destination queue. The default value is Normal. Available options are:
|
Queue Path |
Message queuing path to be used by the Msmq Trace Listener instance. The default value is .Private$myQueue. |
Recoverable |
This property determines whether the log entry is delivered even following computer failure or network problem. The default value is False. Available options:
|
Severity Filter |
Indicates the minimum severity of messages that should be processed and sent to the logging target. |
Time To Be Received |
This property allows setting the total time to receive the log entry by the destination queue. The default value is 49710.06:28:15. |
Time To Reach Queue |
This property allows setting the maximum time to reach the queue for a log entry. The default value is 49710.06:28:15. |
Trace Output Options |
Determines the elements included in the trace output for listeners that do not output to a Text Formatter. The default value is None and this property is optional. |
Transaction Type |
This property determines the Message Queuing transaction type. The default value is None. Available options:
|
Use Authentication |
This property determines whether to use authentication before the message is sent. The default value is False. |
Use Dead Letter Queue |
This property determines whether a copy of any undelivered message should be sent to dead letter queue. The default value is False. |
Use Encryption |
This property determines whether to use encryption. The default value is False. |
The WMI Trace Listener raises a WMI event passing the LogEntry
instance; this functionality is implemented by the WmiTraceListener
class inheriting directly from the System.Diagnostics.TraceListener
abstract class.
The following screenshot displays the default settings of WMI Trace Listener:
The following table provides a list of the configurable properties and their description:
Property |
Description |
---|---|
Name |
Logging target listener name used to identify this item. |
Severity Filter |
Indicates the minimum severity of messages that should be processed and sent to the logging target. |
Trace Output Options |
Determines the elements included in the trace output for listeners that do not output to a Text Formatter. The default value is None and this property is optional. |
While logging information to a log destination, the log entry must often be formatted. The Logging block provides two log message formatters (TextFormatter
and BinaryLogFormatter)
to format the information in the LogEntry
instance. Both these formatters inherit from an abstract class named LogFormatter
, which in turn implements the ILogFormatter
interface. All the mentioned formatter elements are part of the Microsoft.Practices.EnterpriseLibrary.Logging.Formatters
namespace. ILogFormatter
exposes a method called Format
that accepts a LogEntry
instance and returns the formatted string; derived classes are expected to provide implementation for the Format
method.
TextFormatter:
This is a template-based formatter that formats LogEntry
information using the default template tokens.BinaryLogFormatter:
This serializes a LogEntry
object using BinaryFormatter
and returns it as a base-64 encoded string. This formatter should be used with Message Queuing.XmlLogFormatter:
As the name suggests, this formatter formats a LogEntry
object to an XML string representation. This formatter is not available as part of configuration but is internally used by XmlTraceListener
to convert the LogEntry
object to an XML string.Let's see how to configure a trace listener to use Binary Log Message Formatter; the process is same for Text Formatter as well. Click on the plus symbol in the Log Message Formatters section and navigate to Add Log Message Formatters | Add Binary Log Message Formatter as shown in the following screenshot.
The action performed in the above screenshot will add a Binary Log Message Formatter to the configuration editor as shown in the following screenshot.
Once the log message formatter is added to the configuration, the next step is to configure the formatter in the trace listener. Most trace listeners have a property named Formatter Name, which lists the available log message formatters in a drop-down list. The following screenshot shows the Formatter Name configured to use the Binary Log Message Formatter.
While writing log messages using the preceding configuration, the log messages will be formatted using the binary format. The following screenshot shows output from the trace.log
file with the log message formatted using the Binary Log Message Formatter.
Logging is very helpful but it also comes with a cost; too much logging might impact performance. Also there are scenarios where we might want to disable logging based on certain conditions. Logging filters provide the mechanism to switch on/off logging. We can provide filter conditions and prevent the Logging block from sending the LogEntry
object to the trace listeners. The Logging block provides three types of logging filters: CategoryFilter, PriorityFilter
, and LogEnabledFilter
. These filters inherit from an abstract class named LogFilter
which in turn implements the ILogFilter
interface. All these logging filter elements are part of the Microsoft.Practices.EnterpriseLibrary.Logging.Filters
namespace. The ILogFilter
interface exposes two members; derived classes are expected to provide implementation for both the members. The Name
property returns the name of the log filter and the Filter
method accepts a LogEntry
object and returns a Boolean
value indicating whether or not to send the message to the trace listeners.
CategoryFilter:
Filters LogEntry
objects based on categories, this allows us to turn on/off logging for specific categories.PriorityFilter:
Filters LogEntry
objects based on the priority, we can specify the minimum and maximum priority condition for logging.LogEnabledFilter:
This filter gives us control to completely turn on/off logging.Category filter configuration allows us to add one or more categories and set the filter mode to either "allow all except denied" or "deny all except allowed". The following screenshot shows how to add a category filter:
The following screenshot shows the default settings of the newly added category filter:
The following table shows the list of configurable properties and their description:
Property |
Description |
---|---|
Name |
Logging filter name used to identify this item. |
Categories |
List of all the categories defined for this filter. |
Filter Mode |
Filter mode determines whether the configured categories will be allowed or denied logging. The default value is AllowAllExceptDenied. Options are:
|
Logging enabled filter configuration is pretty straight forward, it just allows us to specify whether all logging activities are enabled or disabled by setting the All Logging Enabled property. The following screenshot shows how to add the logging enabled filter:
The following screenshot shows the default settings of the newly added Logging Enabled Filter:
The following table listing shows the available configurable properties and their description:
Property |
Description |
---|---|
Name |
Logging filter name used to identify this item. |
All Logging Enabled |
Determines whether all logging is enabled or disabled. The default value is False. |
Priority filter configuration allows us to configure the maximum and minimum priority values based on which the log messages will be filtered. The following screenshot shows how to add a priority logging filter:
The following screenshot shows the default settings of the newly added Priority Filter:
The table below shows the list of configurable properties and their description:
Property |
Description |
---|---|
Name |
Logging filter name used to identify this item. |
Maximum Priority |
Maximum priority filter value; any log message priority greater than this value will not be logged. The default value is 2147483647. |
Minimum Priority |
Minimum priority filter value; any log message priority less than this value will not be logged. The default value is 0. |
The TraceManager
class provides application activity tracing functionality to log method entry/exit and duration; it is part of the Microsoft.Practices.EnterpriseLibrary.Logging
namespace. This class exposes a method named StartTrace
; this method internally creates and returns a new Tracer
object. The Tracer
class provides the actual implementation of the tracing functionality. Tracing starts with the creation of the Tracer
object and ends when the object is disposed.
The following screenshot displays the class diagram of the Tracer
and TraceManager
classes:
We can trace application activities using the TraceManager
class. This class exposes a method called StartTrace
, which starts with the invocation of the StartTrace
method and stops the tracing activity when the Tracer
instance gets disposed.
The following code snippet shows how to initiate tracing and end the tracing activity:
//Create a TraceManager instance using the EnterpriseLibraryContainer TraceManager traceManager = EnterpriseLibraryContainer.Current.GetInstance<TraceManager>(); using (traceManager.StartTrace("Tracing")) { //Perform application actions here }
The previous code snippet first creates an instance of TraceManager
using the EnterpriseLibraryContainer
class. Next, we use the TraceManager
instance and call the StartTrace
method inside a using
statement. This makes sure that the Tracer
instance created internally gets disposed and the tracing activity ends with the disposal of the Tracer
instance.
The following screenshot shows the typical log entry of a tracing activity:
The above given screenshot shows two log entries representing the start and end of the tracing activity with the timestamp, activity ID, ticks, and other details.
The Logging block provides extension points to implement custom Trace Listeners, Log Formatters, and Log Filters. Although the Logging block provides commonly used logging functionality every project has its own set of requirements and on some occasions we would like to extend an existing element or write a custom implementation using the extension points.
Implementing a custom trace listener is simple; we just need to inherit from the abstract class called CustomTraceListener
. The CustomTraceListener
class inherits from System.Diagnostics.TraceListener
, also an abstract class exposing several virtual methods that can be overridden to provide the custom implementation. We have to add reference to the System.Configuration.dll
assembly in the project while implementing custom trace listener.
The following code snippet shows the list of required namespaces for the custom implementation:
using System.Diagnostics; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration; using Microsoft.Practices.EnterpriseLibrary.Logging; using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration; using Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners;
The folowing code block shows the implementation details such as ConfigurationElementType
attribute, inheritance, methods to be overridden, and so on.
[ConfigurationElementType(typeof(CustomTraceListenerData))] public class MyCustomTraceListener : CustomTraceListener { public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data) { if (data is LogEntry && this.Formatter != null) { this.WriteLine(this.Formatter.Format(data as LogEntry)); } else { this.WriteLine(data.ToString()); } } public override void Write(string message) { this.WriteLine(message); } public override void WriteLine(string message) { //Write to custom destination } }
The MyCustomTraceListener
class inherits from CustomTraceListener
and has overridden three methods: TraceData, WriteLine
, and Write
. We have to provide our custom logic to write the messages to the destination in the Write
and WriteLine
methods. It is to be noted that in the TraceData
method we verify whether the parameter data is of type LogEntry
; this check is carried out to ensure that the custom trace listener executes correctly outside of the Logging block. We also verify whether we have the formatter to format the log message; based on the outcome of the condition we write the message by passing the message to the WriteLine
method. Also to be noticed is that the MyCustomTraceListener
class is decorated with the ConfigurationElementType
attribute with the input as CustomTraceListenerData
; this attribute indicates the configuration object type to be used.
We have to configure the custom trace listener to leverage the trace listener; configuration is similar to what we have seen with other trace listeners. The following screenshot shows how to add a custom trace listener:
After clicking on Add Custom Trace Listener, a dialog box is displayed with the available types that derive from CustomTraceListener
.
After selecting the required type and clicking on the OK button, the configuration editor will add the details to the configuration file. The following screenshot displays the added MyCustomTraceListener:
We are already aware of the common properties such as Name, Formatter, Severity Filter, and Trace Output Options. The property named Attributes comes in quite handy to pass additional configuration information to our custom trace listener.
A custom log formatter can be implemented by implementing the ILogFormatter
interface. We need to implement the Format
method that accepts a LogEntry
instance and provides custom formatting logic to return the formatted string.
The following code snippet shows the required namespaces:
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration; using Microsoft.Practices.EnterpriseLibrary.Logging; using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration; using Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;
The following code snippet shows the implementation structure of a custom log formatter.
[ConfigurationElementType(typeof(CustomFormatterData))] public class CustomFormatter: ILogFormatter { public string Format(LogEntry log) { //Provide custom formatting logic here } }
We have to provide the custom formatting logic in the Format
method of the CustomFormatter
class.
Configuration of the custom log message formatter is similar to that for Text Formatter and Binary Formatter; the configuration editor provides an option Add Custom Log Message Formatter. The following screenshot highlights the option:
Once we click on the Add Custom Log Message Formatter option, a dialog box to browse types that derive from ILogFormatter
interface opens up. The following screenshot displays the dialog box with the selected custom log formatter:
After clicking the OK button, the configuration editor adds a new log formatter in the Log Formatters section. The following screenshot displays the newly added log formatter:
Attributes can be passed on to the custom formatter by providing the key and value details. Trace listeners will be able to select this custom formatter from the formatter drop-down list.
We will implement a simple custom log filter to understand the creation of custom log filters; this log filter implements the ILogFilter
interface and uses the configuration element type CustomLogFilterData
. The CustomLogFilterData
class provides the infrastructure (configuration data) for custom log filters. This custom filter allows us to pass the required information as custom attributes. We will use this to pass the name of a machine that should not be allowed to write log entries.
The following code snippet shows the list of required namespaces for the custom implementation:
using System.Collections.Specialized; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration; using Microsoft.Practices.EnterpriseLibrary.Logging; using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration; using Microsoft.Practices.EnterpriseLibrary.Logging.Filters;
The following code snippet shows the custom log filter implementation that filters log entries based on machine name:
[ConfigurationElementType(typeof(CustomLogFilterData))] public class MachineNameLogFilter : ILogFilter { string filterMachineName = string.Empty; public MachineNameLogFilter(NameValueCollection attributes) { filterMachineName = attributes["MachineName"]; } public bool Filter(LogEntry log) { return string.Compare(log.MachineName, filterMachineName, true) != 0; } public string Name { get { return "Machine name Log Filter"; } } }
The MachineNameLogFilter
class is annotated with a ConfigurationElementType
attribute of CustomLogFilterData
; we have implemented a constructor that accepts NameValueCollection
, which contains the attributes added in the configuration. The Filter
method is at the heart of the action that determines whether the machine name matches with the log entry's machine name; if there is a match then the method returns false
to stop the log entry from being written.
Configuration of a custom log filter is pretty straightforward: click on the plus symbol provided in the Logging Filters section, navigate, and click on the menu item Add Logging Filters | Add Custom Logging Filter.
The following screenshot displays the configuration option to add custom log filters:
After clicking on the menu item Add Custom Logging Filter a type-browser dialog box will be displayed with the list of available custom log filters. The following screenshot displays the type MachineNameLogFilter:
Select the custom log filter and click OK button; this will add the custom log filter to the configuration editor. The following screenshot displays the newly added custom log filter; an attribute MachineName with the value has been manually added for your reference.
The configuration specified in the above screenshot will block all log entries with machine name as "machine1".
3.145.14.132