Custom Auditing in SharePoint 2010–Working with ULS Logs and Event Logs

In a previous article in SharePoint Magazine, I wrote about using custom delegate controls to control access to pages in SharePoint. Although I did mention that this was not an entirely secure approach, there was some controversy about whether the technique was usable at all.

One participant in the ensuing discussion took the time to point out the weaknesses of the solution, and I thought it would be interesting to show how to solve many of the issues mentioned in that response.

The first problem related to auditing, so I though it made sense to start by showing how to add some custom auditing in SharePoint 2010.

I would like to point out that these articles are meant to show individual techniques and should not be used as stand-alone solutions in a production environment.

Only SharePoint 2010?

The logging framework in SharePoint 2007 was less than perfect. Simply put, you were often much better off writing your own logging framework than to use what you got from SharePoint.

Those days are now over, however, with the new logging framework in SharePoint 2010. The upgraded SPDiagnosticsService class provides, compared to SharePoint 2007, a very easy interface for logging events and leave an audit trail.

As such, the examples shown in this article are targeted at SharePoint 2010 only.

ULS and Event Logging

Our goal for this article is to see how we can add events to either the ULS log or the Windows Event log. This is an important skill for SharePoint developers as it allows you to provide feedback to administrators and others about important or informative events in your code.

However, you also need to understand what these two logging destinations are and how best to utilize them.

SharePoint normally provides two types of logging types, the USL log and the Windows event logs. Although you’re certainly free to add additional custom logging functionality, we’re not going to discuss that now.

The ULS log is what you get in the [SPRoot]\LOGS folder, and is often the first place you search for debugging problems with your solutions. These logs normally contain the bulk of the logging information provided by SharePoint.

The benefit of logging to the ULS log is that you can dump much more data there than you would normally want in the Windows event logs. The ULS log is also dedicated to SharePoint so you’ll find only SharePoint information there.

The drawback of the ULS logs is that it is an additional log for administrators to monitor. Even with excellent tools like the ULS Log Viewer, administrators still need to monitor the log in addition to everything else they need to do.

ULS Log Viewer is a free tool that can be downloaded from
http://archive.msdn.microsoft.com/ULSViewer

If you do not have dedicated SharePoint administrators, you’ll likely find that normal system administrators have more than enough to monitor and adding additional burdens to them may not be welcomed.

The other logging destination is the Windows event log, which you’ll find on the server, usually viewable from Administrative tools. This is the monitoring and reporting facility that most administrators use to keep apprised of events on a system.

The benefit of the event logs is that it is an established form of reporting events. Administrators are used to working with the event viewer and there is a range of products designed to help monitor these logs already.

The drawback of the Windows event logs is the lack of detail. Granted, you can add as much as you want to the event logs, but chances are, you’ll be very unpopular if you put hundreds of event log entries every hour, as you could easily do in the ULS logs.

So, which logging destination do you chose? Well, the good news is that you don’t have to chose. You can have your cake and eat IT to.

In fact, you’re probably best off by combining the two logging destinations. For detailed logging with massive amounts of data, use the ULS logs. However, for critical events that require the attention of an administrator, use the Windows event logs.

SharePoint Diagnostics Service

What’s even better is that you don’t need to change the way you log to switch between the two modes of logging. All of the functionality you need to write to the ULS log and the Windows event logs are exposed through the SharePoint diagnostic service.

The diagnostic service is responsible for all aspects of logging and monitoring in SharePoint. By utilizing that service, you don’t need to know any of the internal dealings of working with Windows event logs or anything like that.

Instead, you simply ask the local SharePoint diagnostic service to write the events or traces that you want, and the service will take care of the rest for you. That includes making sure that wonderful new SharePoint 2010 feature, the correlation token, gets added to any event you add to the ULS logs so that it is easier for the administrators to find entries related to your event.

Solution Walkthrough

We’ll start with one of the examples from the Delegate Control article mentioned earlier. To make it easy, let’s just pick the first example, the one that redirect anonymous users to an error page if they try to access an application page. So, we’ll start out with a delegate control with an onload method looking something like this:

protected override void OnLoad(EventArgs e)
{
    if (Context.Request.Url.PathAndQuery.IndexOf("_layouts/", StringComparison.InvariantCultureIgnoreCase)>0)
    {
        if (SPContext.Current.Web.CurrentUser == null)
        {
            // Anonymous user, prevent access
            SPUtility.TransferToErrorPage("Anonymous users have no access to this page");
        }
    }
}

Now, what we want to do is to additionally log what has happened. Let’s first just add the method call, which should be fairly simple, just before transferring to the error page:

LogToULS(string.Format("Anonymous user attempted to access {0}.", Context.Request.Url.ToString()));
// Anonymous user, prevent access
SPUtility.TransferToErrorPage("Anonymous users have no access to this page");

The LogToULS method is deceptively simple, but also holds they keys to the proverbial kingdom. The simplicity shows the elegance of the SPDiagnosticsService.

private void LogToULS(string message)
{
    SPDiagnosticsService diagnosticsService = SPDiagnosticsService.Local;
    SPDiagnosticsCategory category = diagnosticsService.Areas["SharePoint Foundation"].Categories["General"];
    diagnosticsService.WriteTrace(93, category, TraceSeverity.High, message, null);
}

This code really is all you need to write both to the ULS log and to the Windows event logs. Told you it was simple! Let’s examine what goes on here.

SPDiagnosticsService diagnosticsService = SPDiagnosticsService.Local;

The first line gives us access to the local SharePoint diagnostics service. From this object, we have full access to do virtually anything we want, at least from a logging perspective. We can, although not show in this article, configure how the logging should happen, basically anything that you can do through the Diagnostic Logging configuration in Central Administration.

SPDiagnosticsCategory category = diagnosticsService.Areas["SharePoint Foundation"].Categories["General"];

The next line is where we find the category for our log entry, and requires a bit of explaining, most easily done with a screenshot of the Diagnostic Logging configuration in Central Administration.

Custom Auditing in SharePoint 2010 - Figure 1

Categories are organized in areas. Areas are the upper most level shown in the list of in Event Throttling, like Business Connectivity Services and SharePoint Foundation shown in the image. Inside each area are one or more categories, and we need to pick the category where we want our ULS log entry to appear.

You can also create your own areas and categories freely too, to completely customize how your log entries are recorded. That, however, is another show.

The SPDiagnosticsService object conveniently exposes these areas and categories in two collections titled, you guessed it, Areas and Categories, thus explaining our retrieval of the SPDiagnosticsCategory object.

We’ll need this object in the next line, so let’s look at that.

diagnosticsService.WriteTrace(93, category, TraceSeverity.High, message, null);

We’re still utilizing the SPDiagnosticsService object we created earlier. The SPDiagnosticsService class also existed in SharePoint 2007, but what didn’t exist was the two methods WriteTrace and WriteEvent. Now, with SharePoint 2010, we have those two methods, saving us tons of code and hardship.

The signature of the WriteTrace method is simple as well. We provide at least

  • an ID, which is an arbitrary number we can decide ourselves
  • the category we retrieved from the second line
  • the severity of the low entry, defined by the TraceSeverity enumeration
  • the message to be logged

In addition, we can provide additional data to be inserted into the message. This may be useful to enter dynamic data created in the logging method, but in this case, I’ve just sent a null parameter.

So, this really wasn’t too hard, but working with the Windows event logs surely must be more complex, right? Wrong!

Try adding the following line to your method:

diagnosticsService.WriteEvent(93, category, EventSeverity.Information, message, null);

That’s it! The same syntax, granted with an EventSeverity enumeration instead, and with a slightly different method name, and you’re done. Easy as… Well, I never got the hang of pie, but feel free to think of something easy.

Testing

Now that we’ve set up this rather simplistic logging method, we can test it. Deploy your solution, activate it, and log in to your site as an anonymous user before trying to access any application page, such as the All Site Content page.

As shown in the previous article, you’ll get an error message, but our interest is in what appears in the logs. Although you can open these log files to find your entry, I find using the ULS log viewer a much easier approach.

Your result may look something like this:

Custom Auditing in SharePoint 2010 - Figure 2

Note that the WriteEvent method call also adds a ULS log entry.

If you check your Windows event viewer, you may find something like this:

Custom Auditing in SharePoint 2010 - Figure 3

Now that you know how easily you can add logging support to your application, I’m sure your next project will include much better information to those poor administrators who must operate your solutions for years to come.

I also hope that this shows you how you can add auditing trails, and thus answer at least one of the criticisms raise after the previous DelegateControl article. I’ll address others in future articles, so stay tuned :-)

Happy auditing!

.b

Twitter Digg Delicious Stumbleupon Technorati Facebook Email

No comments yet... Be the first to leave a reply!

Leave a Reply

Before you post, please prove you are sentient.

What color is the sky on a sunny day?