Logging to ULS in SharePoint 2010

, ,

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:

Custom message logged in the SharePoint 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:

Custom message logged in the SharePoint ULS log. The message is logged together with the product name.

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.

Technorati Tags:


Possibly related posts

41 Responses to “Logging to ULS in SharePoint 2010”

  1. Tweets die vermelden Logging to ULS in SharePoint 2010 - Waldek Mastykarz -- Topsy.com Says:

    [...] 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! [...]

  2. Rikard Says:

    Looks awesome dude! Gonna try it out now…
    /Rikard

  3. Sharepoint 2010 ULS logging « Sharepointing Says:

    [...] 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/ [...]

  4. Wictor Wilén Says:

    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).

  5. Waldek Mastykarz Says:

    @Wictor: thanks for the tips, Wictor. Much appreciated :)

  6. Uls – Unified Logging Service | Bruce Chao's Sharepoint Learning Blog Says:

    [...] http://blog.mastykarz.nl/logging-uls-sharepoint-2010/ [...]

  7. Stiven Says:

    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?

  8. Waldek Mastykarz Says:

    @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.

  9. Alex Angas Says:

    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.

  10. Waldek Mastykarz Says:

    @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.

  11. Ravi Khambhati Says:

    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.

  12. Andy Burns Says:

    How did you register this with central administration, so you could set the logging levels, etc..

  13. Waldek Mastykarz Says:

    @Andy Burns: I didn't. I just use fixed values in my code.

  14. Waldek Mastykarz Says:

    @Ravi: Post updated; thanks.

  15. venkatx5 Says:

    Thanks Waldek. It's realy helpful. Allmost all my SharePoint searches in Google lands me on your blog. :)

  16. venkatx5 Says:

    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.

  17. Waldek Mastykarz Says:

    @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?

  18. venkatx5 Says:

    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?

  19. Waldek Mastykarz Says:

    @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.

  20. venkatx5 Says:

    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?

  21. venkatx5 Says:

    @Waldek: OMG. I changed my solution's Platform Target to "x64" and it's started working! :-) Please add this platform target step at last.

  22. venkatx5 Says:

    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. :-)

  23. vikram Says:

    hi good one ..
    but it is taking lot of time..

    it may hit my page perfomence ..

    is there any way to boost logging time..

  24. Michael Says:

    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.

  25. Waldek Mastykarz Says:

    @Michael: are you getting any erors or it's just not working?

  26. Twitter settimana del 2011-01-30 — .mark.net il blog di Marco Trova Says:

    [...] to ULS in SharePoint 2010 – Waldek Mastykarz http://blog.mastykarz.nl/logging-uls-sharepoint-2010/ #sp2010 [...]

  27. Roel Says:

    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.

  28. Waldek Mastykarz Says:

    @Roel: great tip! Thanks :D

  29. JB Says:

    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/

  30. Maarten Says:

    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!

  31. TJ Says:

    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?

  32. Waldek Mastykarz Says:

    @Maarten: I haven't experience such issue yet. Any errors in the ULS around the time that you're trying to log your message?

  33. Waldek Mastykarz Says:

    @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?

  34. My Logging Diagnostics Service for SharePoint 2010 » Andy Burns’ SharePoint Blog Says:

    [...] Logging to ULS in SharePoint 2010 by Waldek Mastykarz [...]

  35. Anshuman Says:

    though its a stupid question, but still.. where can I look at the logs after they are written?

  36. Waldek Mastykarz Says:

    @Anshuman: Unless configured differently by default the logs are written to 14\logs.

  37. SP 2010: Developing for performance Part 4 – Logging | Tobias Zimmergren Says:

    [...] 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/ [...]

  38. Deepta Says:

    What is the difference between the ILogger interface and SPDiagnosticsService.Local.WriteTrace?

    Thanks.

  39. Waldek Mastykarz Says:

    @Deepta: What do you mean with the ILogger interface?

  40. Bathula Says:

    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

  41. Sai Says:

    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

Leave a Reply

Security Code:

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS
Copyright © 2007 - 2012 Waldek Mastykarz

Creative Commons License