Goal of this post
I've been working on the past few days on a way to improve the logging infrastructure of our data visualization tool
Charting for SharePoint.
I thought adding a new category to SharePoint Central Admin diagnostic logging screen would be straightforward. Damned! I'm still wondering why this part of the framework is so skeletal. I found so few documentation on IDiagnosticsManager and IDiagnosticsLevel - and the way to implement this stuff correctly - that I've decided to create a proxy class to make this finally easy.
Only very few lines of code are required to achieve that:
Play with the sample attached
The file attached to this post contains a sample implentation of my base class (see Samples folder from the Visual Studio solution)
You can try it by deploying Prexens.SharePoint.Diagnostics.wsp (see bin\Solution folder from the Visual Studio solution). This solution basically registers the DLL, provisions a farm level feature containing a receiver which registers the diagnostics manager when activated. The diagnostics manager is deleted when the feature is deactivated.
Implement your own diagnostics manager
Here are the steps to implement your own diagnostics manager based on my abstract class.
- Create a class library assembly and sign it. Add a new class and make it inherit from Prexens.SharePoint.Diagnostics.Samples.BaseDiagnosticsManager (see files attached to this post to get this class).
- Implement a parameterless constructor which passes a literal identifier for your diagnostics manager as a parameter of the base class contructor. Call RegisterCategory for any new entry you want to make visible from the list of SharePoint logging categories.
public SandboxDiagnosticsManager()
: base("My diagnostics manager")
{
RegisterCategory("My first custom logging category");
RegisterCategory("My second custom logging category");
}
- Override the method GetCurrentOnFarm(SPFarm farm) and paste the code below. Simply replace SandboxDiagnosticsManager with the name of your own class.
protected override BaseDiagnosticsManager GetCurrentOnFarm(SPFarm farm)
{
return farm.Services.GetValue<SandboxDiagnosticsManager>("My diagnostics manager");
}
That's it, you diagnostics manager is ready to go. Event and trace severity levels will be automatically persisted to SharePoint config DB when farm admins tweak the event throttling of your custom categories. The SharePoint OO will give you a hook to a cached copy of these settings anywhere, anytime.
Next step is to register your diagnostics manager as a SharePoint service.
Register your custom diagnostics manager
Run the following code in a console app. Again, replace SandboxDiagnosticsManager with the name of your own class
SandboxDiagnosticsManager manager = new SandboxDiagnosticsManager();
SPFarm.Local.Services.Add(manager);
A cleaner way would be to create a farm feature registering your diagnostics manager on activation, and deleting it on deactivation (see attached file for a running sample of this approach).
Use your custom diagnostics manager
Event and trace severity levels associated with your custom categories can be retrevied this way:
SandboxDiagnosticsManager manager =
SPFarm.Local.Services.GetValue<SandboxDiagnosticsManager>("My diagnostics manager");
IDiagnosticsLevel customLoggingCategory = manager.GetItem("My first custom logging category");
EventSeverity eventSeverity = customLoggingCategory.EventSeverity;
TraceSeverity traceSeverity = customLoggingCategory.TraceSeverity;
In my case, my custom categories are used in relevant part of the code of Charting for SharePoint to determine if a trace has to be outputted to ULS files according to trace and event severity levels configured through central admin.
Updates from my last post on March 6
I've updated my source code to make it Web farm compliant. Update method is indeed different when running code on several WFE.