Design of the SharePoint Logger

The SharePoint Logger provides a reusable set of classes that developers can use to log diagnostic information from SharePoint applications. It is designed to do the following:

  • It provides a consistent mechanism that developers can use to write messages to the Windows event log and the ULS trace log.
  • It enables developers to create and manage custom diagnostic areas and categories.
  • It supports substitution of mock logger implementations for unit testing.
  • It provides an extensible architecture that developers can customize to their own requirements, if required.

Design Highlights

The ILogger interface and the SharePointLogger class are at the heart of the SharePoint Logger.

The ILogger interface is designed to accommodate most logging scenarios and to help developers target their messages to either system administrators or developers. It does this by defining two key methods: LogToOperations and TraceToDeveloper. Consumers use the SharePoint Service Locator to request an implementation of the ILogger interface. The default implementation is the SharePointLogger class, although developers can register alternative implementations if required.

The SharePointLogger class is a straightforward implementation of the ILogger interface. The class is comprised of two replaceable components that implement the IEventLogLogger interface and the ITraceLogger interface. These interfaces define the following functionality:

  • IEventLogLogger. Classes that implement this interface record events that are meant for system administrators. The default implementation of this interface is the EventLogLogger class, which uses the DiagnosticsService class to write messages to the Windows event log.
  • ITraceLogger. Classes that implement this interface record trace information for application developers. The default implementation of this interface is the TraceLogger class, which uses the DiagnosticsService class to write messages to the ULS trace log.

The following class diagram illustrates the relationship between the key classes in the SharePoint Logger.

The SharePoint Logger

Ff798512.2631d4cc-e5b2-499b-a7a9-3df3ed9d23f4(en-us,PandP.10).png

Design Details

This section describes the design and functionality of the SharePoint Logger in more detail, including the roles and responsibilities of the key classes and the points at which the SharePoint Logger can be customized.

The SharePointLogger Class

The SharePointLogger class has the following responsibilities:

  • Forward the log messages to the appropriate logger. Messages targeted at operations are sent to both the class that implements the IEventLogLogger interface and the class that implements the ITraceLogger interface. Messages targeted solely at developers are only sent to the class that implements the ITraceLogger.
  • Enrich the log message with contextual information. Relevant information, such as the current URL and the name of the currently logged-on user, is added to each log message.
  • Format exceptions into a human readable message. Exception messages are sent to the log files in a format that is readable by humans.
  • Provide a high level of robustness in case the logging fails. If a message cannot be written to the event logger implementation, a LoggingException is thrown that contains both the original log message and the reason for the logging failure.

Note

An exception is not thrown if a message cannot be written to the trace logger implementation. Instead, the SharePointLogger class attempts to write a message to the event logger implementation to indicate that the trace has failed.

The SharePointLogger class is not responsible for actually writing messages to the logs. This functionality is the responsibility of the classes that implement the ITraceLogger interface and the IEventLogLogger interface. This provides a more flexible design. For example, you could develop an alternative implementation of IEventLogLogger that writes messages to a database instead of the Windows event log. The SharePointLogger class would remain unaffected by this change and would simply send the same logging information to the new IEventLogLogger implementation.

The TraceLogger and EventLogLogger Classes

The TraceLogger class is the default implementation of the ITraceLogger interface. This implementation simply receives trace messages from the SharePointLogger class and passes them to the DiagnosticsService class for logging to the ULS trace log.

Similarly, the EventLogLogger class is the default implementation of the IEventLogLogger interface. This class receives event messages from the SharePointLogger class and passes them to the DiagnosticsService class for logging to the Windows event log.

The DiagnosticsService Class

The SharePoint 2010 API includes an abstract class named SPDiagnosticsServiceBase that defines the core functionality required to manage diagnostic areas and categories in a SharePoint environment. In the SharePoint Logger, the DiagnosticsService class inherits from SPDiagnosticsServiceBase to provide several key features:

  • It manages the collection of custom diagnostic areas and categories.
  • It registers new diagnostic areas as event sources in the Windows registry.
  • It writes received messages to the Windows event log and the ULS trace log.

The DiagnosticsService class uses the SharePoint The Application Setting Manager to persist custom areas and categories to the farm-scoped property bag.

For more information about the SPDiagnosticsServiceBase class, see SPDiagnosticsServiceBase Class on MSDN.

Registering the SharePoint Logger

Because the SharePoint Logger enables users to make changes to the built-in diagnostic areas and categories, it must be registered with the SharePoint farm before you can use it. SharePoint automatically registers the logger when you first use a class that requires the logger.

When the logger requires an instance of DiagnosticsService, it retrieves the instance from the static DiagnosticsService.Local property. In turn, the property getter calls the SPDiagnosticsServiceBase.GetLocal<DiagnosticsService> method in the SharePoint API to create the instance. The GetLocal first checks to see whether DiagnosticsService is registered; if it is not already registered, it registers it. Because of this, no action is actually required to register the logger. The SharePoint Logger provides a Register method for symmetry, but generally you should not have to use it.

If you want to remove the SharePoint Logger from your environment, you should use the DiagnosticsService.Unregister method. This calls a SharePoint API to delete the logger from the configuration database. The best way to manage this is to use include a farm-scoped feature in the solution package that you use to deploy the SharePoint Logger. In the feature receiver class, override the FeatureDeactivating method and call the DiagnosticsService.Unregister method. This ensures that the SharePoint Logger is unregistered when you retract the solution.

Customizing the SharePoint Logger

The SharePoint Logger is designed to work with the SharePoint Service Locator. With service location, you can replace the default logging and tracing components if you need more flexibility or if you want to reuse an existing logging or tracing component. For example, during unit testing, you can customize logging so that the logging information becomes part of the unit test's output, as shown in Customizing the Logger for Unit Testing.

For more information about the SharePoint service locator, see The SharePoint Service Locator.

Service location occurs at three points of the logger's design:

  • IEventLogLogger. By default, this interface is mapped to the EventLogLogger class.
  • ITraceLogger. By default, this interface is mapped to the TraceLogger class.
  • ILogger. By default, this interface is mapped to the SharePointLogger class.

You can customize logging and tracing by reconfiguring any of these type mappings:

  • If you want to change the way event logging is handled, replace the EventLogLogger class with a new class that implements the IEventLogLogger interface. For example, you could log events to a central database instead of to the Windows event log.
  • If you want to change the way trace logging is handled, replace the TraceLogger class with a new class that implements the ITraceLogger interface. For example, you can log trace messages to the ASP.NET trace log.
  • If you want to make minor changes to the way the SharePointLogger class handles logging, you can create a class that derives from it. The SharePointLogger class uses virtual methods for most operations, so you can override much of its behavior.
  • If you want full control over how logging and tracing are handled, replace the SharePointLogger class with a new class that derives from the BaseLogger class or that directly implements the ILogger interface.
  • If you want to create your own logging infrastructure, you must derive from the SPDiagnosticsServiceBase class in the SharePoint API. You can review the DiagnosticsService class in the SharePoint Logger for an example of how to approach this.

Use the IServiceLocatorConfig interface to configure your application to use your new custom logger. For an example of how to use the SharePoint Service Locator to replace a service, see Using a Feature Receiver to Register a Type Mapping.

Extending Logging Functionality to the Sandbox Environment

The SharePoint Logger includes a full-trust proxy that you can use to enable logging from sandboxed solutions. However, if you are unable to deploy the logging proxy, you can extend the SharePoint Logger to support logging to an alternative location within the sandbox environment, such as a SharePoint list.

The SharePointLogger class includes two virtual methods named WriteToOperationsLogSandbox and WriteSandboxTrace. When the logger detects that it is running in the sandbox, it calls these methods to write log messages and trace messages, respectively. By default, these methods first check whether the logging proxy is installed. If the logging proxy is available, the methods use it to write to the event logs or the trace files. If the proxy is unavailable, the methods simply drop any log messages.

By overriding these methods, you can customize the logger to take alternative actions when it is running in the sandbox environment. To do this, you should use the following high-level steps:

  1. Create a class that derives from the SharePointLogger class.
  2. Override the WriteToOperationsLogSandbox method and the WriteSandboxTrace method to implement your custom handling of logging and tracing messages within the sandbox environment.
  3. Use the SharePoint Service Locator to register your logger class as the default implementation of the ILogger interface. For more information about how to do this, see Using Custom Logger Classes and Adding Type Mappings. You should use a feature receiver class to register your type mapping at the site collection level when your application is installed.