Saturday, July 30, 2011

SharePoint 2010 TroubleShooting Tips

The saying goes 'to Err is human', with this in mind Microsoft had made commendable improvements on the instrumentation side with SharePoint 2010, by shipping a slew of features and tools for developers and admins as well. Now the task of uncovering those mysterious bugs and performance bottlenecks, inadvertently got in during the development phase, is a breeze. Let me show you how these new features\tools is going to save you from the intricacies of debugging hard to find bugs in SharePoint 2010. Here I will be discussing on the following tools\features.


1. Developer Dashboard
2. Using SPMonitoredScope with Developer Dashboard
3. Demystifying Correlation ID
4. Using ULSLogViewer and SPDiag.exe
5. WSS_Logging
6. Setting Debug Flag
7. Attaching Debugger during run-time
8. Using SPDisposeCheck

Developer Dashboard
If you are a SharePoint developer moving from MOSS (2007) to SharePoint 2010, you are definitely going to appreciate this new feature called 'Developer Dashboard' introduced with SharePoint 2010. This enables you to have a run down of all the operations in a particular page request, including page execution time, execution time of each HttpHandlers, Web parts, database queries and stored proc names. Here is a screen shot of how the developer dashboard will look like in your browser. In short this feature, allows you to trace down the code\component which is behaving unusual. You can click the image to view in its original size. 

Fig -1

Now let me show you how to get the 'Developer Dashboard' visible on your page. First of all this feature is disabled by default, you have to enable this either through Server Object Model or by using commands from 'stsadm' and 'PowerShell'. 

For those new to PowerShell, let me have a word on this. With SharePoint 2010, Microsoft has associated PowerShell which is a versatile, powerful and extensible command line shell, which goes beyond the boundaries of vanilla command line tools. Moreover the existing 'stsadm' will be replaced by Powershell sometime in future. I would recommend learning PowerShell which will be worth the time and effort, looking at the rich set of features it offers

So coming back to the point, enabling 'Developer Dashboard' in your SharePoint site. First I am going to show you how to get this done with 'stsadm'. Before this, make sure that you are running the Command line window as farm admin.


Stsadm –o setproperty –pn developer-dashboard –pv ondemand 


After executing this command you need to login to a SharePoint site as site collection owner. In the site you should see a new icon on to the top right hand side of the page like the one below. 

Fig -2

Clicking on that should toggle the 'Developer Dashboard' on your current page as shown in Fig-1. You can turn it off with the following 'stsadm' command.


Stsadm –o setproperty –pn developer-dashboard –pv ondemand 


Enable Developer Dashboard using PowerShell:
The following command is a single line command, so make sure to take out the line breaks if you are copying from here.

[Microsoft.SharePoint.Administration.SPWebService]::ContentService.DeveloperDashboardSettings.DisplayLevel =
 ([Enum]::Parse([Microsoft.SharePoint.Administration.SPDeveloperDashboardLevel],“OnDemand”));

Disable Developer Dashboard using PowerShell:
The following command is a single line command, so make sure to take out the line breaks if you are copying from here.


[Microsoft.SharePoint.Administration.SPWebService]::ContentService.DeveloperDashboardSettings.DisplayLevel =
([Enum]::Parse([Microsoft.SharePoint.Administration.SPDeveloperDashboardLevel],“Off”));

Enabling Developer Dashboard using Server Object Model from .NET Code:


public void EnableDD()
{
  SPDeveloperDashboardSettings DDSettings = new SPWebService.ContentServuce.SPDeveloperDashboardSettings;

  DDSettings.DisplayLevel = SPDeveloperDashboardLevel.OnDemand;
  DDSettings.TraceEnabled = true;
  DDSettings.Update();
}


Disabling Developer Dashboard using Server Object Model from .NET Code:


public void DisableDD()
{
  SPDeveloperDashboardSettings DDSettings = new SPWebService.ContentServuce.SPDeveloperDashboardSettings;

  DDSettings.DisplayLevel = SPDeveloperDashboardLevel.Off;
  DDSettings.TraceEnabled = false;
  DDSettings.Update();
}

SPMonitoredScope 
You could unleash the true potential of 'Developer Dashboard' when used with 
SPMonitoredScope class. This class helps you to monitor performance and resource usage for a specific code block. Say you notice a degradation in performance  in a page containing a webpart developed by your team. After going through the code, you suspect a specific method block which seems like the culprit behind this. In such scenarios you could warp the suspected code block\method inside the SPMonitoredScope class, which will provide you with details on resource usage, performance bottlenecks and on how the component interacts with other components. When you wrap a code block inside the SPMonitoredScope, the statistics are written to the Developer Dashboard and to ULS (Unified Logging Service) logs. So here's how to get that done.

using (new SPMonitoredScope(“CodeMonitor_001”))
{
   SuspectedCodeBlock(); 
}


if you wish to collect the code statistics only when the number of requests exceed than the required number of requests or the time taken to process the requests exceeds the a specified number of seconds; in such scenarios you could use the following overloaded form of the SPMonitoredScope class.


using (new SPMonitoredScope("CodeMonitor_001",
                             TraceSeverity.Verbose,
                             2000,
                             new SPRequestUsageCounter(5),
                             new SPSqlQueryCounter()))
{
    SuspectedCodeBlock();
}


The above code block will flag a critical event, if the request takes more than 2 seconds to complete or the number of requests goes beyond 5.


Correlation ID
Truth to be told, when I started with SharePoint development seeing the screen shot as the one shown below was a nightmare, as I couldn't infer any clues from those error message and even couldn't comprehend what this Correlation ID was? Can you infer anything thing from this screen shot? certainly not! 


So what is this Correlation ID? Well Correlation ID is a GUID token generated for each and every request received by the SharePoint Web Front End (WFE) servers. This ID is passed across to all subsequent operations in response to the request, i.e. if the web request inturn makes a database call, you could trace this Correlation ID in the SQL Profiler too. In short all operations linked to a web request request will have this Correlation ID attached.

So next question is, how to figure out the root cause of an error from the Correlation ID? For this you need to search for the CorrelationID inside the ULS Logs, which is located in the "{SharePoint root}\Logs". Finding the CorrelationID among the huge set of log files may seem like searching for a needle in a hay stack. For this Microsoft is providing a set of tools to help you analyze the ULS logs in a better way. Lets explore those tools to surface the root cause from the Correlation ID.


SharePoint Diagnostic Studio (SPDiag) - This is powerful diagnostic tool to troubleshoot SharePoint 2010 issues. SPDiag diagnosis issues by collecting instrumentation data from ULS logs, Windows Event logs, IIS, performance counters  sharepoint logs, SQL databases and presenting those using preconfigured reports. To find the Correlation ID, first of all you need to download and install the tool from here on to your SharePoint 2010 box. 


1. After this, open the SPDiag application window and create a new project by passing the host name of the sharepoint server. 
2. Provide the farm admin credentials.
3. Take a Full snapshot of the farm.
4. In the search box key in the Correlation ID, which will bring up the message corresponding to the provided correlation id.


The documentation on SPDiag is available here.


ULSViewer - Unlike SPDiag, this utility parses and displays only the ULS log data in a friendly interface which is available as freeware. For your information, this tool is not supported by Microsoft even though its available for download from the Microsoft domain.  In the ULSViewer, open the log file with date when the error occurred, here you will see a column titled 'Correlation' this is where you could spot the CorrelationID. Next to the Correlation column you will find a message column containing the detailed error info.


WSS_Logging - With SharePoint 2010, Microsoft had gone one step further by introducing a logging database, which stores a wealth of instrumentation data on the SharePoint servers and farm. The database reads logs from all front end servers through a timer job. You could also search for the Correlation ID using the following SQL query.


SELECT
          [RowCreatedTime],  
                [ProcessName],  
                [Area],  
                [Category],  
                [EventID],
                [Message] 
FROM
            [WSS_UsageApplication].[dbo].[ULSTraceLog] 
WHERE
            CorrelationId='21AC2020-3AEB-1069-C2DD-08112B30309A'

I hope by now, you should be confident enough to tackle the errors with those cryptic 'Correlation ID'.


If you wish to see the logging improvements shipped as part of SharePoint 2010, here's two articles from the SharePoint escalation team worth reading. Part 1, Part 2.

Debug Flag
Lets look at something simple, which lets you view the error information in the SharePoint page itself, instead of going through the CorrelationID lookup. A word of caution, this should not be done on a production server. Lets see how to set the Debug Flag.


1. Open the directory where you web application is located, which should be "C:\inetpub\wwwroot\wss\VirtualDirectories\". 
2. Open the web.config file.
3. Locate the entry "CallStack", set the value to "true"
4. Locate the entry "CustomErrors", set the 'mode' attribute to 'off'


Now going to the page, where the Correlation ID showed up should display the classical ASP.NET YSOD (Yellow Screen Of Death) with detailed error info.


Attach Debugger:
With VS.NET 2010 you could easily debug the SharePoint features by putting a break point in your code and pressing F5 as you do for a normal asp.net application. But there are scenarios where the code you want to debug might not get executed straightaway like Event receivers, timer jobs etc, in such cases the best approach is to add the following line of code where you wish the set the break point.


Debugger.Launch()


Executing the above piece of code will cause the 'Attach Debugger' window to show up, to which you could attach VS.NET and debug as you do normally.




SPDisposeCheck
During development chances are that you might miss out server objects like SPSite, SPWeb from properly disposing, which could end up hogging the server memory in the log run. Did you know that, each instance of SPSite and SPWeb contains a reference to an SPRequest object that, in turn, contains a reference to an unmanaged COM object that handles communications with the database server. So as to prevent the leftover COM instances from accumulating in the memory, Microsoft had come up with an excellent command line utility for verifying your code against a set of best practices like, whether the code had disposed all  objects implementing IDisposable interface. It also verifies the code for 'Do No Dispose' patterns like certain objects which are internal to SharePoint should not be disposed, like the ones coming under SPContext.Current context. After executing the SPDisposeCheck.exe against your assembly\executable, a report will be generated listing out the issues identified. Chances are that you might find false positives too in the report. 


You can download this utility from here. A Best Practices documentation is available on MSDN, on how to Dispose SP2010 Server Objects.


Its recommended to integrate SPDisposeCheck.exe with VS.NET so as to analyze your assemblies without switching to an external console window. Here's an article that details on how to get this done.



Conclusion
SharePoint being a vast product, brings in challenges for the developer and administrators on effectively extending and maintaining the product in respect to the business requirements. Here's a resourceful document which I came across while browsing, detailing things like how to get most out of SharePoint features and services and how to fix problems that might arise when using SharePoint 2010. Here's the link to the document.

No comments: