Exploring design elements

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
  • Trace Source Categories
  • Trace Listeners
  • Log Message Formatters
  • Logging Filters
  • TraceManager and Tracer

We will now explore the technical details of each one of these design elements.

LogEntry

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.

LogEntry

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

Title

String

Gets or sets the title of the log message; by default this property is set to String.Empty.

Message

String

Gets or sets the message body to log; by default this property returns String.Empty.

Categories

ICollection<String>

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.

CategoriesStrings

String[]

This read-only property returns categories as a string array; this property is available to support WMI queries.

Priority

int

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.

Severity

TraceEventType

Gets or sets the severity of type System.Diagnostics.TraceEventType; the default value is TraceEventType.Information.

LoggedSeverity

String

This read-only property returns the string representation of Severity, which is of type System.Diagnostics.TraceEventType.

EventId

int

Gets or sets the event number or identifier.

ActivityId

Guid

Holds tracing activity id; a Guid is generated and assigned automatically if tracing is enabled. Returns empty Guid if tracing is not enabled.

ActivityIdString

String

This read-only property returns a string representation of the tracing activity id to support WMI queries.

RelatedActivityId

Guid?

Gets or sets the related activity id; by default this property is null.

AppDomainName

String

Gets or sets the AppDomain name; if this property is not set then the name of the AppDomain in which the program is running will be used.

MachineName

String

Gets or sets the machine name; if this property is not set then the current name of the machine (Environment.MachineName) in which the program is running will be used.

ManagedThreadName

String

Gets or sets the name of the .NET thread; if this property is not set then the current thread name (Thread.CurrentThread.Name) will be used.

ProcessId

String

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.

ProcessName

String

Gets or sets the process name; if this property is not set then the process name of the current running process will be used.

Win32ThreadId

String

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.

TimeStamp

DateTime

Gets or sets the date and time of the log entry message; if this property is not initialized then it will automatically return DateTime.UtcNow.

TimeStampString

String

This read-only property returns the string representation of the TimeStamp property formatted using the current culture.

ErrorMessages

String

This read-only property returns as String the error message that was added using the AddErrorMessage method.

ExtendedProperties

IDictionary<String, object>

Gets or sets additional properties through a dictionary of key-value pairs.

Logger

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.

Logger

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

Write

The Logger class provides a total of nineteen Write methods with variable parameter signatures. These overloaded methods go a long way in logging a meaningful log entry. At the bare minimum it requires only the message to be logged, allowing it to write the log entry to the default category.

ShouldLog

This method is useful to query whether a LogEntry object should be logged; it accepts a LogEntry instance and returns true if the entry should be logged.

IsLoggingEnabled

This method queries whether logging is enabled and returns true/false based on the outcome of the query.

GetFilter

There are three GetFilter methods, these methods return the matching ILogFilter instance from the filters collection. If no match is found then they return null.

SetContextItem

This method accepts two parameters: key and value of type Object. The added context items will be written with every log entry.

FlushContextItems

Calling this method will empty the context items dictionary.

Reset

The Reset method as per the documentation is marked public for testing purposes; it basically resets the writer used by the façade. Please note threads still holding references to the old LogWriter will fail when the LogWriter gets disposed.

Using Logger

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.

LogWriter

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.

LogWriter

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

Write

The LogWriter class provides a total of nineteen Write methods with variable parameter signatures. These overloaded methods go a long way in logging a meaningful log entry. At the bare minimum it requires only the message to be logged, allowing it to write the log entry to the default category.

ShouldLog

This method is useful to query whether a LogEntry object should be logged; it accepts a LogEntry instance and returns true if the entry should be logged.

IsLoggingEnabled

This method queries whether logging is enabled and returns true/false based on the outcome of the query.

IsTracingEnabled

This method queries whether tracing is enabled and returns true/false based on the outcome of the query.

GetFilter

There are a total of three GetFilter methods; these methods return the matching ILogFilter instance from the filters collection. If no match is found then they return null.

SetContextItem

This method accepts two parameters, key and value of type Object. The added context items will be written with every log entry.

FlushContextItems

Calling this method will empty the context items dictionary.

GetMatchingTraceSources

This method returns IEnumerable<LogSource> for the matching trace category sources specified in the given LogEntry instance.

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);

Adding trace source categories

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:

  • Special categories
  • Log categories

The following class diagram depicts the exposed properties and methods of the LogSource class:

Adding trace source categories

Configuring special categories

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 LogEntry instance is not defined in the configuration then the log entry will be logged to this special category.

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.

Configuring log categories

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.

Configuring log categories

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:

Configuring log categories

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.

Configuring trace listeners

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.

Configuring trace listeners

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.

  • All
  • Off
  • Critical
  • Error
  • Warning
  • Information
  • Verbose
  • ActivityTracing

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.

  • LogicalOperationStack
  • DateTime
  • Timestamp
  • CallStack
  • ProcessId
  • ThreadId

Configuring Event Log Trace Listener

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.

Note

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.

Configuring Event Log Trace Listener

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.

Configuring Flat File Trace Listener

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:

Configuring Flat File Trace Listener

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 %TEMP%, %WINDIR%, etc.

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.

Tip

While running the application in debug mode, the log file will be generated in %Program Files%Microsoft Visual Studio 9.0Common7IDE folder, the "File Name" can be changed to ". race.log" to generate the log file in the executing assembly folder.

Configuring Rolling Flat File Trace Listener

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.

Configuring Rolling Flat File Trace Listener

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 %TEMP%, %WINDIR%, etc.

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:

  • Minute
  • Hour
  • Day
  • Week
  • Month
  • Year
  • Midnight

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.

Configuring XML Trace Listener

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:

Configuring 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 %TEMP%, %WINDIR%, etc.

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.

Configuring Database Trace Listener

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:

Configuring 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.

Configuring to send log messages to an e-mail address

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:

Configuring to send log messages to an e-mail address

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:

  • None
  • WindowsCredentials
  • UserNameAndPassword

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).

Configuring System Diagnostics Trace Listener

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.

Configuring System Diagnostics 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:

Configuring System Diagnostics Trace Listener

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.

Configuring Message Queuing Trace Listener

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.

Configuring 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:

  • Lowest
  • VeryLow
  • Low
  • Normal
  • AboveNormal
  • High
  • VeryHigh
  • Highest

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:

  • True
  • False

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:

  • None
  • Automatic
  • Single

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.

Configuring WMI Trace Listener

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:

Configuring 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.

Configuring custom trace listeners

The Logging block provides an abstract class called CustomTraceListener as an extension point for implementing custom trace listeners. Also, we may extend one of the existing trace listener implementations to satisfy our unique requirements.

Configuring log message formatters

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.

Configuring log message formatters
  • 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.

Configuring log message formatters

The action performed in the above screenshot will add a Binary Log Message Formatter to the configuration editor as shown in the following screenshot.

Configuring log message formatters

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.

Configuring log message formatters

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.

Configuring log message formatters

Configuring logging filters

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.

Configuring logging filters
  • 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.

Adding a category filter

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:

Adding a category filter

The following screenshot shows the default settings of the newly added category filter:

Adding a 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:

  • AllowAllExceptDenied
  • DenyAllExceptAllowed

Adding a logging enabled filter

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:

Adding a logging enabled filter

The following screenshot shows the default settings of the newly added Logging Enabled Filter:

Adding a 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.

Adding a priority filter

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:

Adding a priority filter

The following screenshot shows the default settings of the newly added Priority Filter:

Adding a 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.

TraceManager and Tracer

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:

TraceManager and Tracer

Tracing activities

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:

Tracing activities

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.

Customizing Logging block elements

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

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.

Configuring the custom trace listener

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:

Configuring the custom trace listener

After clicking on Add Custom Trace Listener, a dialog box is displayed with the available types that derive from CustomTraceListener.

Configuring the custom trace listener

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:

Configuring the custom trace listener

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.

Implementing a custom log formatter

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.

Configuring the custom log formatter

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:

Configuring the custom log formatter

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:

Configuring the 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:

Configuring the custom 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.

Implementing a custom log filter

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.

Configuring the custom log filter

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:

Configuring the custom log filter

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:

Configuring the custom log filter

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.

Configuring the custom log filter

The configuration specified in the above screenshot will block all log entries with machine name as "machine1".

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.75.165