Tag Archives: logging

Tailoring SP2010 p&p logging to your application

Back in our last post, we saw an intro to the logging power found in the SP 2010 patterns & practices library. Now, let’s make it our own.

Defining your own areas and categories

The out-of-the-box behaviour is fine, but it’s much nicer for both end user and developer to see the actual application name causing the exception, rather than the generic “Patterns and Practices”. No problem, you can define your own areas and categories! What does this mean? Examine a ULS log file and you’ll see at the top a series of column headers. “Area” is typically used for the a major piece of functionality or application name. “Category” is some component of that functionality. For logging to the Event Viewer, the Source column is used for “Area”, and “Category” is the first line of the log entry.

The many ILogger methods

Before continuing, let’s examine how we use a custom area and category when calling the ILogger. If you have a look at its interface, you’ll find several variations of two methods. LogToOperations writes to both the ULS trace log and the Event Viewer. TraceToDeveloper writes to the trace log only. Some variations allow you to specify a category and others don’t. At this point, you really want to look at the many options and narrow down the list to one or two that are going to be most useful to you. I generally only use the following depending on whether I’m logging exceptions or information:

void LogToOperations(Exception exception, int eventId, EventSeverity severity, string category);
void LogToOperations(string message, string category);

Notice the category parameter which is where we set both the area and category to use. The supplied string here needs to be of the format “Area/Category“. This is fairly distasteful in design and much like a “magic number“, but that’s the way the API has been written. I recommend creating a LoggingHelper class that abstracts this away and reduces the risk of making a mistake.

Registering the areas and categories

There is one last trick to perform before using these custom areas and categories. They must be provisioned as part of a farm level feature. This is primarily because updates are made to the SharePoint configuration database which requires execution by an account with farm level permissions. It’s also because registering new sources for the Event Viewer to use must be done by a user with permissions to write to the Windows registry. Executing this registration as a farm-level event receiver should alleviate these issues (unless you’re deploying to a locked down environment where you may have some problems).

There is sample code on how to register areas and categories in the SharePoint Guidance documentation. (There’s also plenty of other great stuff there about how the logger works and I recommend taking a few minutes to read it.) One extra thing to take note of if you plan on logging to the Event Viewer in a multi-server farm is that this registration needs to take place on each server in the farm. There are instructions on how to do this by lead SharePoint p&p developer Chris Keyser.

Segue – suggestions

As you would have gathered, this library is not perfect. Here’s some thoughts on gotchas and what I feel could be improved:

  • The ILogger interface contains too many method signatures which causes confusion. Most developers will only settle on their chosen one or two. I’d like to see a simple entity-style class used for specifying logging parameters instead of the many options given.
  • Using a ‘magic number’ style string format to select an area and category is error prone. Area and category should be separated, and preferably strongly typed.
  • It’s clear to see the ILogger interface has been designed around logging to the ULS and Event Log. This makes it not as adaptable to other scenarios. Again, using an entity-style class for parameters would help make it more generic.
  • To register your own custom areas and categories, a farm feature is required so that enough permissions are available to write to the Windows registry. In multi-server farms there is added complexity.

On the plus side, a lot of these issues only need to be resolved once.

Conclusion

I really like the logging functionality provided with the patterns & practices library. It’s generally easy to use and certainly powerful. There are some issues, but it’s a great way to get exposure to the benefits of this library and immediately reap rewards!

Intro to SharePoint 2010 patterns & practices – Logging

Microsoft’s patterns & practices library for SharePoint 2010 contains plenty of useful information and tools. One of the simplest things you can start using right now is its logging functionality. Check out these handy features:

  • Log to both the ULS trace logs and the Windows Event Viewer
  • Define your own logging categories so they appear under your application’s name everywhere
  • Support for logging from the sandbox via a provided proxy
  • Configure log event throttling using the out-of-the-box Diagnostic Logging page in Central Administration
  • Contextual information such as current URL and logged in user is automatically added to log entries
  • Don’t worry about logging long messages or correlation IDs, it’s all handled for you
  • Use the provided logging interface to easily write your own logger
  • Service locator provided means almost no code changes when changing to a different logger (for a future blog post)

If you’re a developer that’s never used the library before, this post helps you dip your toes in the water and harness this logging power!

Getting started

The p&p release is a little confusing. There’s the CodePlex project, which links to various components and where you should ask for help or log any bugs you find. However the code is not kept there – download that from MS Downloads. You’ll want to keep an eye on this page for updates as they aren’t announced anywhere that I’ve found.

Once extracted to your development server, you need to build the library. Everything is open source apart from the service locator (for a later blog post). The solution to build can be found at Source\SharePoint 2010\Microsoft.Practices.SharePoint.sln.

Build this project, then copy the output Microsoft.Practices.ServiceLocation.dll and Microsoft.Practices.SharePoint.Common.dll to your project and reference them.

Log away!

Using the logger is pretty easy. First, add these using statements everywhere you wish to log:

using Microsoft.Practices.SharePoint.Common.Logging;
using Microsoft.Practices.SharePoint.Common.ServiceLocation;

Then declare the logger as a field and obtain a reference to it:

ILogger _logger = SharePointServiceLocator.GetCurrent().GetInstance<ILogger>();

Now let’s log an exception…

Exception ex = new ApplicationException("This is my test exception");
_logger.LogToOperations(ex);

…and see what appears in the ULS log…

09/08/2010 20:15:34.66 w3wp.exe (0x15D8) 0x0EF0 Patterns and Practices SharePoint Guidance 0000 Information Category: SharePoint Guidance: An exception has occurred. ExceptionType: ‘ApplicationException’ ExceptionMessage: ‘This is my test exception’ StackTrace: ” Source: ” TargetSite: ” Additional Information: Request TimeStamp: ’2010-09-08T20:15:33.2171690+09:30′ UserName: ‘AA\Administrator’ Request URL: ‘http://aasp2010dev:31000/default.aspx?PageView=Shared&InitialTabId=Ribbon.WebPartPage&VisibilityContext=WSSWebPartPage’ User Agent: ‘Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET4.0C; .NET4.0E; InfoPath.3; .NET CLR 3.5.30729; .NET CLR 3.0.30729)’ Originating IP address: ’127.0.0.1′ 2cc97a55-1c4d-4e22-b145-4de9a3fdf6e1

…and Event Viewer:


Log Name: Application
Source: Patterns and Practices
Date: 8/09/2010 8:15:34 PM
Event ID: 0
Task Category: None
Level: Information
Keywords: Classic
User: N/A
Computer: aasp2010dev.aa.com
Description:
Category: SharePoint Guidance: An exception has occurred.
ExceptionType: 'ApplicationException'
ExceptionMessage: 'This is my test exception'
StackTrace: ''
Source: ''
TargetSite: ''

(many other details removed for brevity)

Here you can see the benefits these simple steps have already given – lots of context relating to exception to help diagnose the problem!

Logging – make it happen!

That’s it for now, but we’ll be exploring a lot more about this library in the next blog post. Remember – you owe it to yourself and your users to log appropriately. Ease the pain of bugs found in production code!

Download and references: