Building a Scalable Architecture; SharePoint Records Management

One of the pieces of developing custom components is logging
information. No matter if it’s for diagnostic purposes or when an error
occurs, logging allows you to track the health of your custom component.
When developing custom components for SharePoint 2007 we hadn’t much
choice. Although SharePoint 2007 shipped with the Unified Logging
Service, we couldn’t use it. The SharePoint SDK was pretty clear about
it: although some methods were publicly available, ULS was for internal
use only and was not supposed to be used in custom code. Because of
this, we couldn’t provide a similar logging experience to SharePoint and
had to develop custom logging solutions. SharePoint 2010 changes this
situation: using the new ULS is now supported and may be used for
logging in custom code.
Logging using SharePoint 2010 101
Using the SharePoint 2010 ULS is pretty easy. Using just a few lines
of code you can log information from your custom components:
|
try
{
var i = 0;
var a = 2 / i;
}
catch (Exception ex)
{
SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("My Category", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
}
|
Calling the snippet above will log the following message in the ULS log:

It works…. almost. Did you notice the
Unknown label where
the product name should be mentioned? While it’s not necessary for
simple solutions, it would definitely make it easier to track which
messages originate from which solutions if we actually could provide the
product name.
Logging v2
The SharePoint API doesn’t provide any method which would allow you
to provide the name of the product that logged the message. In order to
write the product name to the ULS you have to create a custom Logging
Service. You can do this by inheriting from the
SPDiagnosticsServiceBase class:
|
public class LoggingService : SPDiagnosticsServiceBase
{
public static string MaventionDiagnosticAreaName = "Mavention";
private static LoggingService _Current;
public static LoggingService Current
{
get
{
if (_Current == null)
{
_Current = new LoggingService();
}
return _Current;
}
}
private LoggingService()
: base("Mavention Logging Service", SPFarm.Local)
{
}
protected override IEnumerable<SPDiagnosticsArea> ProvideAreas()
{
List<SPDiagnosticsArea> areas = new List<SPDiagnosticsArea>
{
new SPDiagnosticsArea(MaventionDiagnosticAreaName, new List<SPDiagnosticsCategory>
{
new SPDiagnosticsCategory("WebParts", TraceSeverity.Unexpected, EventSeverity.Error)
})
};
return areas;
}
public static void LogError(string categoryName, string errorMessage)
{
SPDiagnosticsCategory category = LoggingService.Current.Areas[MaventionDiagnosticAreaName].Categories[categoryName];
LoggingService.Current.WriteTrace(0, category, TraceSeverity.Unexpected, errorMessage);
}
}
|
Instead of using the SPDiagnosticService.Local you would use now our custom LoggingService:
|
try
{
var i = 0;
var a = 2 / i;
}
catch (Exception ex)
{
LoggingService.LogError("WebParts", ex.Message);
}
|
Let’s take a look at the result:

As you can see using a custom Logging Service, you can log the name
of your solution what makes it easier to track your custom messages.
When implementing custom Logging Service you have to provide a list
of categories and logging levels supported by the service. You can do
this by overriding the ProvideAreas method. In my example I implemented
only one category but depending on your solution you could add multiple
categories and severity levels.