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.

















May 28th, 2010 at 3:18 pm
[...] Dit blogartikel was vermeld op Twitter door Waldek Mastykarz, Stuart Starrs. Stuart Starrs heeft gezegd: RT @waldekm: New post: 'Logging to ULS in SharePoint 2010' http://tinyurl.com/3x78cdd #SharePoint << Good information! [...]
May 31st, 2010 at 6:30 am
Looks awesome dude! Gonna try it out now…
/Rikard
June 10th, 2010 at 4:32 pm
[...] In this post it is explained how to do and how to create a custom service logger: http://blog.mastykarz.nl/logging-uls-sharepoint-2010/ [...]
August 10th, 2010 at 7:39 am
Nice Waldek, only this isnt thread-safe. Either implement a lock in the Current property or initialize the private service property and then add a private static constructor (also make the _current immutable using the readonly keyword).
August 10th, 2010 at 11:04 am
@Wictor: thanks for the tips, Wictor. Much appreciated :)
October 30th, 2010 at 1:02 pm
[...] http://blog.mastykarz.nl/logging-uls-sharepoint-2010/ [...]
November 16th, 2010 at 3:56 am
Waldek,
Nice post. One comment, in your LogError method and in the call to LoggingService.Current.WriteTrace was your intention to pass category.TraceSeverity instead of TraceSeverity.Unexpected?
November 16th, 2010 at 4:25 pm
@Stiven: because I don't do anything with the trace severity I decided to just set it to TraceSeverity.Unexpected. If you however would like to have a more complete implementation, you would probably do just what you mentioned.
November 16th, 2010 at 11:41 pm
Hi Waldek,
I notice the code for writing your own service contains a reference to SPFarm.Local. Does that mean some or all of the code needs to run elevated / as system?
Cheers, Alex.
November 17th, 2010 at 7:32 am
@Alex Angas: it should run fine under any account. Although it's just a sample code I'm quite sure I've used something similar in production without any problems.
November 24th, 2010 at 3:19 pm
Thanks for the article.
I request you to remove space between WebPart in below line.
LoggingService.LogError("Web Parts", ex.Message);
Code gives an error withouth modifing this.
November 25th, 2010 at 3:44 pm
How did you register this with central administration, so you could set the logging levels, etc..
November 25th, 2010 at 4:58 pm
@Andy Burns: I didn't. I just use fixed values in my code.
November 25th, 2010 at 5:09 pm
@Ravi: Post updated; thanks.
December 6th, 2010 at 12:44 pm
Thanks Waldek. It's realy helpful. Allmost all my SharePoint searches in Google lands me on your blog. :)
December 7th, 2010 at 11:46 am
Hi Waldek, I tried to use this ULS Logging in SharePoint Console Application. I created a class library project with this code in a css(Strong name key file attached). I compiled and copied the dll to my console application project. Now while try to compile the console app it\'s showing Microsoft.SharePoint.dll reference. I copied the dll from SharePoint root folder to this console app project folder and added as reference. But now am getting errors as SharePoint.Search.dll assembly reference missing. I need to build the Console application and it should run in a Server where SharePoint not installed. Please suggest. Thanks.
December 7th, 2010 at 5:44 pm
@venkatx5: Unfortunately it's not enough to just copy the Microsoft.SharePoint.dll. If you want to have an application that depends on the SharePoint API, you need SharePoint to be installed on the same machine for that application to run. If I may ask: what is it exactly that you are trying to achieve?
December 8th, 2010 at 4:57 am
Well, I have a console application that reads XML and stores it in a SharePoint Library. So far we used Microsoft Enterprise Library Logging feature. Now we need to use ULS Logging feature to log Exceptions and errors. I tried as you suggested in our SharePoint 2010 Dev Server and on line "private LoggingService() : base("Merck SharePoint Logging Service", SPFarm.Local)"
getting Null Reference error
"System.NullReferenceException was unhandled Message=Object reference not set to an instance of an object.
…
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:"
Any Suggestions?
December 8th, 2010 at 6:26 am
@venkatx5: You cannot log to ULS if you're not on a SharePoint server. So if you're creating an application that's communicating with SharePoint remotely, you will need to use a custom logging mechanism such as Enterprise Library.
December 8th, 2010 at 8:50 am
Correct. But I don't want to install Enterprise Library in the Server. Since SharePoint has ULS Logging wish to use the same. I suspect on Console Application, Bcoz am not passing any credentials. Does ULS Logging require SharePoint User Context?
December 8th, 2010 at 12:32 pm
@Waldek: OMG. I changed my solution's Platform Target to "x64" and it's started working! :-) Please add this platform target step at last.
December 9th, 2010 at 6:20 am
Hi Waldek, I've written a article based on your code. Basically It explains how to use ULS in Custom Application in Detail(Step by Step Guide).
http://geekswithblogs.net/venkatx5/archive/2010/12/09/how-to-use-uls-in-sharepoint-2010-for-custom-code.aspx
Hope you don't mind am using your Code. :-)
December 9th, 2010 at 12:38 pm
hi good one ..
but it is taking lot of time..
it may hit my page perfomence ..
is there any way to boost logging time..
January 21st, 2011 at 7:51 pm
Great post Waldek. One issue: I replaced the categoryName parameter for the LogError method with an Enum type and now nothing gets logged. It was working with a string parameter. Any idea what's going on? Thanks.
January 23rd, 2011 at 12:06 pm
@Michael: are you getting any erors or it's just not working?
January 31st, 2011 at 12:02 am
[...] to ULS in SharePoint 2010 – Waldek Mastykarz http://blog.mastykarz.nl/logging-uls-sharepoint-2010/ #sp2010 [...]
May 5th, 2011 at 10:17 am
I tried the above solution but I couldn’t get any logging in my ULS log. After some investigation it appeared that my application pool account didn’t have enough rights to write to the ULS log. I added the application pool account to the group “Performance Log Users” and it worked.
May 5th, 2011 at 3:03 pm
@Roel: great tip! Thanks :D
June 17th, 2011 at 4:34 pm
Great article!
Here you find another nice article about logging with SharePoint:
http://www.parago.de/2011/01/how-to-implement-a-custom-sharepoint-2010-logging-service-for-uls-and-windows-event-log/
June 22nd, 2011 at 2:29 pm
Hi Waldek,
Thanks for this post. It helps us a lot. We've already implemented the code with TraceSeverity.Unexpected and it works perfect.
However, I've created a second method that uses the same implementation but with TraceSeverity.Verbose. I've enabled diagnostic logging with verbose logging and all available categories, but the log record won't appear in the ULS.
If I use your first method everyting works fine, except the nasty 'unknown' in the product name column of course.
Have you experienced the same behaviour?
Thanks!
June 23rd, 2011 at 3:19 pm
Given the product name is an internal static string how would you go about making a more common logger to be used from numerous products/solutions? Or would you suggest implementing one of the above each time in each custom product/solution with the relevant name/categories?
June 24th, 2011 at 5:40 am
@Maarten: I haven't experience such issue yet. Any errors in the ULS around the time that you're trying to log your message?
June 24th, 2011 at 5:41 am
@TJ: Depending in how complex it will be you could either implement it as one or separate. It also depends on how you are planning to use the logger: will you be using it for different "products" or not?
June 27th, 2011 at 1:01 pm
[...] Logging to ULS in SharePoint 2010 by Waldek Mastykarz [...]
July 12th, 2011 at 1:07 pm
though its a stupid question, but still.. where can I look at the logs after they are written?
July 13th, 2011 at 7:19 am
@Anshuman: Unless configured differently by default the logs are written to 14\logs.
August 17th, 2011 at 3:12 pm
[...] If you for example want to tag the log entries with your company name, clients name or project name – you can easily change that behavior as well. Take a look at my friend Waldek's post about it here: http://blog.mastykarz.nl/logging-uls-sharepoint-2010/ [...]
August 28th, 2011 at 4:31 pm
What is the difference between the ILogger interface and SPDiagnosticsService.Local.WriteTrace?
Thanks.
August 28th, 2011 at 9:38 pm
@Deepta: What do you mean with the ILogger interface?
September 16th, 2011 at 8:34 am
Hi Waldek
Thanks for this superb article.
I am using existing area and category for logging and when i selected TraceSiverity as Verbose in Central Admin, when i use SPDiagnosticsService.Local.WriteTrace() and when selecting TraceSiverity as Verbose, nothing is logging to ULS. above "Verbose" are logging fine. ie., with Monitor, Medium etc.,
please help me in finding the issue of why verbose messages are not logging to ULS.
regards
Bathula
September 26th, 2011 at 11:51 am
Hi Waldek,
First of all thanks for this article. I used same class for my project. But I am getting error in below line
SPDiagnosticsCategory category = LoggingService.Current.Areas[MaventionDiagnosticAreaName].Categories[categoryName];
While executing above line, it throws error saying that "An item with the same key has already been added". Can you please help me out to resolve this issue.
Advance thanks…
-Sai