Share via


The Logging Application Block

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

The latest Enterprise Library information can be found at the Enterprise Library site.

patterns & practices Developer Center

On this page:
Supported Scenarios | Design of the Logging Application Block | Differences between Desktop and Silverlight Versions | Remote Service Trace Listener - Parameters, Logging Service Factory, Buffering Messages in Memory, Buffering to Isolated Storage, Configuring the Logging Endpoint on the Server | Isolated Storage Trace Listener - Maximum Size, Reading Log Messages from Isolated Storage | Notification Trace Listener | Runtime Changes API

The Logging Application Block will allow you to write diagnostic information. Using additional metadata, such as the severity or log categories, these log messages can be filtered and routed to various configurable trace listeners and formatters.

Most of the core for the Logging Application Block has been ported to Silverlight. However, the Trace Listeners that are provided with Enterprise Library 5.0 cannot be used in Silverlight due to the Silverlight security sandbox. For example, you cannot use the Flat File Trace Listener or the Event Log Trace Listener, because the Silverlight security sandbox denies you access to these resources. That's why the Enterprise Library 5.0 Silverlight Integration Pack ships with its own set of trace listeners, designed to be used in Silverlight.

In this chapter, we'll give you an overview of the logging application block. Then we'll discuss the Silverlight-specific scenarios that are supported by the Enterprise Library 5.0 Silverlight Integration Pack. If you would like to know more, please read the chapter on the Logging Application Block on MSDN® and in the Developer Guide.

Supported Scenarios

The Silverlight Logging Application Block supports the following scenarios:

  • Writing log messages through a consistent API. The Logging Application Block provides a consistent API for writing log messages. That means that the same the API can be used to write diagnostic trace messages to a diagnostic trace log or important error messages to a remote web service. The LogWriter class has several overloads for writing log messages, with different information, such as the message, category, priority and severity.
  • Filtering and routing log messages to different trace listeners. The logging infrastructure allows you to configure exactly which log messages should be logged and which trace listener they should be logged to.
  • Logging to a Service. The RemoteServiceTraceListener provides a robust mechanism for logging certain messages to a remote server. This allows you to monitor log messages in a centralized location.
  • Logging to isolated storage. The IsolatedStorageTraceListener allows you to write log messages in JSON format to isolated storage. This allows you to write a log file on the client computer. There is also an API for reading log messages from isolated storage, so you can display them in your application.
  • Logging to an event. Using the Notification Trace Listener, you can receive log messages through an event. This can help you to build a developer trace window for your application.
  • Programmatic or XAML-based configuration. The Silverlight Logging Application Block allows you to configure how you'd like to handle log messages. This configuration can be expressed in XAML files or using the programmatic API.
  • Changing log settings at run time. When the application is running, you might want to change the log settings. For example, if a particular user is having trouble, you might want to increase the logging settings so that more information is logged. Or, if you request more space in isolated storage, you might want to increase the size that the application consumes in isolated storage.
Hh852709.note(en-us,PandP.51).gifEd Says:
Ed
                The Logging Application Block for Silverlight works great for various diagnostic logging and tracing tasks. However, you should not use it for auditing purposes. Not only is it possible for log messages to become lost if the buffer becomes full, but it is also possible to tamper with the logged messages. It is nearly impossible to implement a Silverlight auditing mechanism that cannot be circumvented. If you need auditing functionality in your application, you should implement it on the server when certain data is accessed or changed. </td>

Design of the Logging Application Block

This section gives a short introduction to the Logging Application Block Infrastructure. Most the core of the Silverlight Logging Application Block is the same as the Logging Application Block from Enterprise Library 5.0, so please refer to the Logging Application Block documentation on MSDN for more information.

The following diagram shows how the core logging infrastructure works:

Follow link to expand image

The main types of objects are:

  • Log Writer. The log writer is the main entry point for creating log entries and writing them to your chosen logging targets. It creates an instance of a log entry containing the information to be logged, and interacts with the other objects that filter the log entry, assign it to one or more categories, format it, and dispatch it to the appropriate targets.
  • Log Entry. Your application submits information that the Logging Application Block should log either by using the LogWriter class to automatically create a log entry or by directly creating an instance of the LogEntry class and populating it with the information to log.
  • Log Filters. Log filters can block or allow a log entry based on a number of features. Each log entry is assigned to one or more categories (the default is the General category), and the category log filter can use these categories to pass or block a log entry. In addition, two special log filters can block all logging, or block log entries with a priority lower than a specified value. You define the categories, priorities, and the settings for the log filters in the configuration for the block.
  • Trace Sources. Trace sources are effectively a set of buckets into which the block places all log entries that have not been blocked by a log filter. You use these buckets to define where log entries will be dispatched to—you can think of them as being the source of the log entries that will actually be dispatched to the target destinations. There are two basic types of trace sources:
    • There is a trace source for each category you define in the configuration of the block. These are called Category Sources.
    • There are three built-in trace sources: one that receives all log entries, one that receives log entries when an error occurs during processing or dispatching of the log entry, and one that receives all log entries that do not match any configured category. These are called Special Sources.
  • Trace Listeners. Trace listeners represent the targets for your log entries, and you configure one for each type of target (such as a remote logging service or a log file in isolated storage) to which you want to send the log entries. Trace listeners listen for log entries arriving in the trace source buckets, format each log entry as required, and dispatch it to the target configured for that trace source. Your configuration maps each trace source (each category source you define plus the three special sources) to one or more trace listeners. The important point to note here is that this allows you to dispatch each log entry to zero, one, or more targets (such as sending it as an email message as well as writing it to the Windows Event Log). Also, multiple Trace Listeners of the same type can be used.
  • Log Formatters. In Enterprise Library 5.0 there are several trace listeners that require log messages to be represented in text format. Enterprise Library uses Log Formatters to format the log messages into a string. For example, the log messages can be formatted as text or as XML. This feature has not been included in the Enterprise Library 5.0 Silverlight Integration Pack because its trace listeners can use the log message as is, without having it formatted. For example, the Remote Service Trace Listener will serialize and send the entire log message to the server, so it does not need to be formatted as text.

Differences between Desktop and Silverlight Versions

As mentioned before, most of the core of the Enterprise Library 5.0 Logging Application Block has been ported to Silverlight. The following features have not been ported:

  • Log Formatters. The trace listeners in the Silverlight Logging Application Block do not use log formatters. The classes related to the log formatters have not been ported to Silverlight, to reduce the size of the Silverlight Logging Application Block assembly.
  • Instrumentation. Enterprise Library 5.0****implements instrumentation in the logging block, for example, to provide performance counters. This feature has not been ported, since performance counters are not available in Silverlight.
  • Revert impersonation property. Enterprise Library 5.0 uses impersonation when logging to improve logging performance. Impersonation itself is not supported in Silverlight, so the Revert Impersonation property does nothing.
  • Limited supported types for extended properties . The LogEntry class allows you to add objects as extended properties, but the trace listeners from the Enterprise Library 5.0 Silverlight Integration Pack do not support using arbitrary objects. Since the isolated storage trace listener uses the DataContractJsonSerializer, it only supports primitive types. The RemoteServiceTraceListener is using a data contract (LogEntryMessage), which only supports strings as extended properties.
  • Stack Trace. In Enterprise Library 5.0, it’s really easy to write the stack trace when a LogEntry is being written. The stack trace is not part of the LogEntry, but at the time a log message is being formatted, the log formatters can simply grab the stack trace from the context and add that to the formatted log entry. Since the Enterprise Library 5.0 Silverlight Integration Pack doesn’t support log formatters, you will also not automatically get stack trace information for each log entry.
Hh852709.note(en-us,PandP.51).gifSharon Says:
Sharon
                If you need a stack trace for each log entry, then you could create a derived version of the trace listener you’d like to use and add the stack trace to the log message as an extended property.</td>

Remote Service Trace Listener

With the Remote Service Trace Listener, it is possible to log events to a Windows Communication Foundation (WCF) service. The Enterprise Library 5.0 Silverlight Integration Pack provides both the trace listener to be used on the Silverlight client and a configurable logging service implementation to be used on the server. The Remote Service trace listener can send messages immediately or in a batch. It is also robust enough to handle scenarios in which logging to the service fails. In those cases, the log entries can be buffered to memory and isolated storage. This means that log entries that could not be sent can be sent later when the application restarts.

The following diagram shows how the Remote Service trace listener works:

Follow link to expand image

You can configure the Logging Application Block to send certain log entries to the Remote Service trace listener. The Remote Service trace listener can either send the log entries immediately, or as a batch. If the log entries cannot be sent, then they will be buffered in memory and optionally to isolated storage. You will need to configure how the Remote Service trace listener should contact the server, by specifying the address and binding to use. This can be done either programmatically or using a ServiceReferences.ClientConfig file.

On the server, the log messages are received by the log service. This log service needs a service (.svc) file to define the location of the endpoint. The binding for the service also needs to be configured in the web.config file. The log service forwards the log entries to the Enterprise Library 5.0 Logging Application Block.

Parameters

The Remote Service trace listener can be configured with the following parameters:

  • **Logging Service Factory
    **The Remote Service trace listener needs to know how and where to send the log messages. Typically, you'll set this value to the name of the endpoint, which will create and configure a Logging Service Factory for you, but you can also set it to a custom Logging Service Factory.
  • **Send Immediately flag, and Submit Interval
    **You can specify whether the service should send log messages immediately, or if it should send items in a batch. The submit interval determines how often batched messages should be sent, if they are not sent immediately.
  • Buffer size
    Log messages can be buffered in memory by specifying a value for MaxElementsInBuffer
    , and to isolated storage by specifying a value for IsolatedStorageBufferMaxSizeinKilobytes. This buffering is used when messages should be sent in a batch, or when log messages cannot be sent for some reason (for example when the Internet connection is lost). You can specify the maximum number of items to buffer. When you also specify a maximum size for the isolated storage buffer, then this trace listener will also attempt to store the maximum number of items in isolated storage. If the isolated storage buffer becomes full, older messages will be overwritten.
Hh852709.note(en-us,PandP.51).gifEd Says:
Ed
                 The minimum size for <strong>IsolatedStorageBufferMaxSizeinKilobytes</strong> is 5 Kb. Setting it to a value that is lower than this would not make sense, because the buffer would be too small to effectively store items in it, but you would still incur a significant performance hit for serializing. </td>

Logging Service Factory

The Remote Service trace listener uses WCF to send log messages to the server. Like any WCF service, you will need to configure the address and binding of the service. There are two ways in which you can configure these:

  • Configure the binding in a ServiceReference.ClientConfig file. The most common way to configure a WCF service is to add a client config file. This file describes the name of the endpoint and its address and binding. You can configure the Remote Service trace listener by setting the value of the Logging Service Factory property to the name of the binding.
    Hh852709.note(en-us,PandP.51).gifSharon Says:
    Sharon If you are logging sensitive information, then you should really consider using a WCF binding that secures the log messages, for example by requiring HttpsTransport. Also, don’t forget to store the logged information in a secure location on the server.
    - **Supplying a custom Logging Service Factory.** If you wish to have more control over the way the WCF service is created, you can also supply an instance of a Logging Service Factory to the Logging Service Factory property. For example, if you wish to secure your logging service, then you can use a custom Logging Service Factory to supply credentials to the Logging Service. You can only supply a custom Logging Service Factory directly in a XAML configuration file or using the fluent configuration API. It cannot be set using the configuration console or added to an application configuration file.
    Hh852709.note(en-us,PandP.51).gifMark Says:
    Mark You might want to consider securing your LogService endpoint. By only allowing authenticated users to add log messages, you reduce the risk of malicious users performing a denial of service attack by flooding your system with fake log messages. But of course, the downside is that it’s more difficult to detect issues during authentication.

    The section entitled Using the Remote Trace Listener describes how you can use these settings in more detail.

    Buffering Messages in Memory

    If you specify that messages should be buffered, they will always be buffered in memory. You can also specify that the log messages should be buffered to isolated storage, but the messages will still be buffered in memory.

    Hh852709.note(en-us,PandP.51).gifEd Says:
    Ed
                    Be careful with specifying a huge buffer. If the message that is sent to the server contains too many log messages and exceeds the maximum message size specified by WCF, it will not be able to send log messages again and will retry indefinitely. Of course, you can solve this by increasing the maximum message size or decreasing the buffer size. But you can also create a class that derives from the RemoteServiceTraceListener and send the log messages in smaller chunks. In that case, don’t forget to create a custom RemoteServiceTraceListenerData class as well.</td>
    

    Buffering to Isolated Storage

    When you use the option to buffer log messages in isolated storage, the Remote Service trace listener will immediately try to claim the size of the buffer when it starts. If there is not enough space available, then it will claim the amount of space that is actually available. Once claimed, the buffer size will not be automatically changed, even if you change the size in the XAML configuration. However, using the Runtime Changes API, which is described later in this chapter, you can manually change the size of the buffer.

    The****isolated storage buffer will not exceed the maximum buffer size. When the buffer becomes full, it will roll over and start to overwrite the oldest log messages. If you attempt to add an item that by itself exceeds the size of the buffer, then it will not be added to the isolated storage buffer. No logging error will be generated though, because it will still be added to the in-memory buffer.

    When you start multiple instances of your application, only the first instance will be able to use the isolated storage buffer. The other instances will only be able to buffer in memory.

    Configuring the Logging Endpoint on the Server

    On the server side, the logging service can be used as is, customized to fit a particular scenario, or replaced entirely by a custom implementation. The LogService.svc file defines where the endpoint for your logging service resides. In this file, you can specify which implementation you'd like to use. The default logging implementation is the Logging Service in the Microsoft.Practices.EnterpriseLibrary.Logging.Service namespace. You can also use this class as a base class. There are two virtual methods you can use to customize the logging process: Translate, which creates a log entry from the incoming LogEntryMessage, and CollectInformation, which allows you to add additional information to the log message.

    The Logging Service uses the Logging Application Block from Enterprise Library 5.0 to handle log messages on the server. This means you can use all the filter options, trace listeners, and log formatters that are available. For example, you can log all warnings and errors to the Windows Event Log using the Event Log trace listener, and log all informational log messages to a rolling flat file using the Flat File Trace Listener.

    Since the Logging Service is implemented as a WCF service, you'll also need to configure the endpoint in the web.config file.

    Hh852709.note(en-us,PandP.51).gifMark Says:
    Mark
                    I wanted a way to correlate log entries with the user's machine. If a particular user has problems, we can increase his logging levels, but I would like a way to filter log messages for just this user. We implemented this in Stock Trader V2 by querying the <strong>HttpContext.Current.Request.UserHostName</strong> property. This works fine for the purpose of diagnosing problems. However, since this value can be spoofed by a malicious client, you should never use something like this for security-critical actions such as auditing.</td>
    

    Isolated Storage Trace Listener

    The Isolated Storage Trace Listener allows you to write log messages in JavaScript object notation (JSON) format to isolated storage. This allows you to create a log file on the client computer. The following diagram shows how the Isolated Storage trace listener works:

    Follow link to expand image

    The Isolated Log trace listener has the following properties you can set, either programmatically or through configuration:

    • **Name
      **This is the name that will be used to create the log file in isolated storage. Only a single Isolated Storage trace listener instance can write to a file with a particular name at the same time, even across application instances.
    • **Maximum Size in Kilobytes
      **You can specify the maximum size the log will use. If you specify a size that is larger than the actual available size, it will only use the actual available size.

    Maximum Size

    When the Isolated Storage trace listener starts, it will immediately try to claim the specified size. If there is not enough space available, it will claim the amount of space that is actually available. Once claimed, the isolated storage log size will not be automatically changed, even if you change the size in the XAML configuration. However, using the runtime changes API, which is described later in this chapter, you can manually change the size of the buffer.

    When the log becomes full, it will roll over and start to overwrite the oldest log messages. If you attempt to add an item that by itself exceeds the size of the log, then it will not be added to the log file at all and a logging error will be generated.

    Reading Log Messages from Isolated Storage

    If you want your users to be able to view the log file, you should create a custom view for this purpose. You can use the ILogEntryRepository interface to retrieve log messages from the isolated storage log.

    Notification Trace Listener

    The Notification Trace Listener raises an event whenever a new log entry is received. On this event, you can add custom logic. One possible usage would be to store all log messages in memory, and display them in a custom view.

    Runtime Changes API

    The Silverlight Logging Application Block provides an API for making changes to the logging settings at run time. Note that changes made to the logging settings through this API are not persisted. When the application restarts, it will revert back to the settings defined in configuration. This API allows you to do the following:

    • Read current trace listeners and trace sources. You can use the API to find the currently configured trace listeners and trace sources so that you can retrieve their settings.
    • Enable or disable logging altogether. The API allows you to turn logging on or off altogether.
    • Changing existing trace listeners. You can change the settings for an existing trace listener. For example, for the Isolated Storage trace listener you can change the size of the isolated storage cache, or for the Remote Service trace listener, you can change the interval at which log messages are being sent to the server and the buffering settings.
    • Changing existing trace sources. You can also change existing trace sources. For example, you can change the source level of a trace source. You can also add or remove trace listeners that have already been configured.

    It is not possible to add new trace sources or trace listeners. Any trace listener you'd like to add to a trace source using this API should already be used by another trace source.

    Hh852709.note(en-us,PandP.51).gifSharon Says:
    Sharon
                    You can't define a trace listener in configuration that is not being used, because it will be ignored when the Logging Application Block is configured. If you have a trace listener that's normally not used, but you'd like to be able to add it using the change API, then you can do the following: define an unused trace source in configuration and add the trace listener to it. That way, it's available when the Logging Application Block is configured and you can then use the change API to add it to a different trace source.</td>
    

    Next Topic | Previous Topic | Home

    Last built: July 8, 2011