Using a Timer Job to ensure diagnostic areas of SPGuidance

In one of my previous posts, I described a PowerShell script that could be run on each front-end to ensure that for each diagnostic area defined in the logging framework, a corresponding event source was created. That script should be run with sufficient privileges on the target box, but does the job.

I then promised to post a method to do that from a timer job next, but work and private life has kept me busy lately ūüėČ My apologies. However, here it is.

In this post, I would like to expand on that a little, but instead of using the PowerShell route, I use a SharePoint Timer Job to accomplish the same thing.

You can download the example Visual Studio 2010 project from this location. What we will do in this post:

  1. Create a timer job that should be run on each front-end that ensures that for each diagnostic area, an event source is registered.
  2. Create two features:
    1. Diagnostics areas and categories
    2. Timer Job

In a real-world situation, I would publish the SPGuidance assemblies in a separate WSP, however, for simplicity; they are packaged with this solution.

I will create one diagnostic area called Boom.CustomLogging and two categories, called Connections and Events. From within the web part, I will log to both categories. In my next post, I will also show how to create a custom logging component. For this post, we use the default one (which logs to the event log and ULS logs).

First, open Visual Studio and create an empty SharePoint project. We will create three features:

  1. DiagnosticAreas à Sets up the diagnostic areas and categories
  2. JobInstaller à Will install our job to ensure the event sources
  3. WebParts à Will contain our test web part

Also create a Web Part element called LoggingTester and add it to the solution. Add Event receivers to the DiagnosticAreas and JobInstaller features. Finally, add a class to your project called EnsureEventSourcesJob.cs that will hold your timer job to ensure event sources. Your solution explorer should look something like this:

Configure Custom Diagnostic Areas

We will start with the event receiver for the Diagnostic areas. This feature receiver will set up our areas and categories that we will use in our sample. I want to configure one custom diagnostic area that is specific to my application and two categories beneath it.

  • Diagnostic Area: Boom.CustomLogging
    • Category: Connections (default event severity Error, default trace severity Medium)
    • Category: Events (default event severity Information, default trace severity Medium)

On the side, it is also possible to add categories to the default SharePoint 2010 diagnostic areas, such as Access Services, Excel Services Application and SharePoint Foundation Search, however, this is considered bad practice. In short, do not do it. Whenever you wish to introduce custom categories, do so in your own diagnostic area.

The following piece of code was taken from the SPGuidance chm. It defines a property in our event receiver class that returns a DiagnosticsAreaCollection with my custom areas and categories.

// This helper property builds a collection of areas and categories.
DiagnosticsAreaCollection _myAreas = null;
DiagnosticsAreaCollection MyAreas
   get {
      if (_myAreas == null)
         _myAreas = new DiagnosticsAreaCollection();
DiagnosticsArea boomArea = new DiagnosticsArea(“Boom.CustomLogging”);
¬†¬†¬†¬†¬†¬†¬†¬† boomArea.DiagnosticsCategories.Add(new DiagnosticsCategory(“Events”, EventSeverity.Information, TraceSeverity.Medium));
¬†¬†¬†¬†¬†¬†¬†¬† boomArea.DiagnosticsCategories.Add(new DiagnosticsCategory(“Connections”, EventSeverity.Error, TraceSeverity.Medium));


In this code snippet, we define a property that creates a new Microsoft.Practices.SharePoint.Common.Logging.DiagnosticsAreaCollection, creates a new Microsoft.Practices.SharePoint.Common.Logging.DiagnosticsArea called Boom.CustomLogging and finally adds two Microsoft.Practices.SharePoint.Common.Logging.DiagnosticsCategory objects that defines my two categories and adds it to the custom area. Finally, I add the area to the collection and return it.

No real magic here. We will use this property in both the feature activated and feature deactivating events. So, let us go in the feature activated event.

public override void FeatureActivated(SPFeatureReceiverProperties properties) {

configMgr = SharePointServiceLocator.GetCurrent().GetInstance<IConfigManager>();
   DiagnosticsAreaCollection configuredAreas = new DiagnosticsAreaCollection(configMgr);

(DiagnosticsArea newArea in MyAreas)
     var existingArea = configuredAreas[newArea.Name];
     if (existingArea == null) {
else {
¬†¬†¬†¬†¬†¬†¬† throw new SPException(“Diagnostic area already exists”);


In this method, we use the SharePointServiceLocator, which is also part of the Guidance framework, to return an instance of IConfigManager. The IConfigManager can be used to store configuration data on any level in SharePoint, so at Web, Site, WebApp and Farm level. Again, this is part of the Guidance framework and provides a single consistent framework to store configuration data that is not to be located in the web.config. Using the config manager, we request the current custom configured diagnostic areas. Then, for each area from our property (our new set), we check whether or not it already exists. If not, we add it. Finally, save the configuration again.

The feature deactivating method basically does the reverse, shown below.

public override void FeatureDeactivating(SPFeatureReceiverProperties properties) {
   // Then remove the areas
   IConfigManager configMgr = SharePointServiceLocator.GetCurrent().GetInstance<IConfigManager>();
   DiagnosticsAreaCollection configuredAreas = new DiagnosticsAreaCollection(configMgr);
foreach (DiagnosticsArea area in MyAreas) {
      DiagnosticsArea areaToRemove = configuredAreas[area.Name];
      if (areaToRemove != null) {
         foreach (DiagnosticsCategory c in area.DiagnosticsCategories) {
            var existingCat = areaToRemove.DiagnosticsCategories[c.Name];
            if (existingCat != null) {
if (areaToRemove.DiagnosticsCategories.Count == 0) {


The only difference here is that we take a safe approach as suggested in the guidance, because other applications (depending on company guidelines) could have added categories to the diagnostic area. The safe way therefore is to remove the own configured categories and if none remain, remove the area.

Create the timer job to ensure event sources

In this section we will create a simple timer job that needs to be executed on every server in the farm. The job will call a method from the Guidance framework that will ensure that for each custom diagnostic area, a corresponding event source is created. This will have the same function as my PowerShell script in my previous post, just implemented through a timer job. The advantage here however, is that I can configure the timer job to run on specific intervals on all servers within the farm. The PowerShell script can also be scheduled and run remotely, but needs more management.

We define the timer job in the EnsureEventSourcesJob class.

public class EnsureSourcesJob : SPJobDefinition {
   public EnsureSourcesJob() : base() {}
EnsureSourcesJob(string name, SPWebApplication webApplication) : base(name, webApplication, null, SPJobLockType.None) {
      this.Title = name;

   public o
verride void Execute(Guid targetInstanceId)
      ILogger logger = SharePointServiceLocator.GetCurrent().GetInstance<ILogger>();
¬†¬†¬†¬†¬† logger.TraceToDeveloper(“Ensure Configured Diagnostic Areas registered timer job executing.”, 103, Microsoft.SharePoint.Administration.TraceSeverity.Monitorable, “Events”);
      // Important! The JobLockType should be set to None to run on each server!
      if (this.LockType == SPJobLockType.None) {
         // our job has only one very simple task.
         // call the ensure configured areas registered method of the DiagnosticsAreaEventSource class.

Two things are important in this job, which is quite simple. First, you need to provide a public parameter less constructor for the serialization. Second, the type of job specified should be of type SPJobLockType.None. This will ensure that my timer job will be run on each server within the farm.

The call to the DiagnosticsAreaEventSource.EnsureConfiguredAreasRegistered method will make sure that an event source for each of the configured diagnostic areas exists on the specific server.

Once the timer job has run, you can go to Central Admin à Diagnostic logging to see your own categories and events. They will be treated the same as any out of the box configured sources and categories.

The Visual Studio solution can be downloaded from here.


My Windows Phone 7 has arrived!

So yesterday I was finally able to pick up my Windows Phone 7 phone. As I posted recently, Avanade Netherlands was the first company within the Netherlands to integrally move to this new mobile OS.

Avanade Netherlands has chosen the HTC Trophy 7 to be the first phone 7 phone for all employees. There are more models, but we will have to do with this one for now. And what a phone!

Obviously, we as a Microsoft consulting company are a bit biassed towards anything that comes from Microsoft, but also as real techies one of the more critical consumers. Because many of the services are not available in the Netherlands for the time being, we have pulled some tricks to be able to use the US based services, like the Marketplace, Zune and Bing.

I have to hand it to Redmond; they have outperformed themselves with this first release of this new OS. Yes, features are missing (like the most blogged tethering and copy and paste), but the overall experience I had when switching on the phone was WOW. Initial setup only took a minute (with some preparation like a US based live ID), but after that, all worked pretty smooth.

What first hit me was the speed. The phone is fast. Did I say it was fast? I mean it was fast! No lag experienced at any time. Secondly, the mail interface is great. It connected to my company exchange server without a problem and synchronized all mail, contacts and agenda items really fast. The Peoples Hub also picked up on their Facebook and Twitter accounts and this integration is pretty awesome.

Started the marketplace and the number of apps is reasonable. Yes, it does not have the amount of apps that the AppStore¬†or Android market have to offer, but quantity does not tell the whole story. Like with the AppStore, there are 300.000 apps of which you do not want to have 298.567 on your phone. They are crap. In time, I am guessing this will also be valid for the marketplace, but for now, there are already pretty useful¬†apps in the store, even when you’re residing¬†in the Netherlands. The Dutch marketplace is not expected until summer 2011. Facebook, Twitter,, IMDB and many more are there.

The Metro interface looks crisp¬†and finally something different. Most of the phones features are that intuitive that even my youngest daughter could use it (well, matter of speaking, she’s 6).

The best part for me came from the Zune integration. I never used the Zune software, as the Zune and the Zune marketplace never made it to the Netherlands, but man, that’s a quality piece of software. The Zune client software is used like the iTunes for the iPhone. It can synchronize content to your phone and delivers the updates. Syncing music on the¬†phone was as easy as drawing an album from the collection and drop it on the phone. I did not even know where that album was stored on my home network. The phone (or maybe the zune¬†software) than captures all the folder and album images for that particular album, much like XBMC does it. But once on the phone, selecting an artist also delivers more content related to that artist, without me loading anything on the phone. Pretty cool.

I also created an XBox Live account, although I have am XBox 360 for years already (besides the XBox 1 and Wii), but never played online. Games from the marketplace looked cool and I downloaded the Bejeweled game right away (much obligated to do so ;-)). But also a game like the Sims 3 is available.

Downsides to the phone are already known and most will be covered in a next update shortly, like the tethering and the copy and paste. Other things that I found missing was the smart dialing for example. So just start typing the name on the phone pad where it also filters the contact list. You can use the search integration, but the smart dialing was faster. Also like not being able to put on custom apps (well, at least not until I unlock it) and the Dutch language support. But all that are just minor things that will be corrected shortly.

I think the Windows Phone 7 is very well positioned to take its fair share in the market among the smartphones. For me, it is very promising.

Windows Phone 7 has arrived @ Avanade

Yeah, don’t I just love to work at Avanade. Last month, Avanade Netherlands announced to supply all their employees with the new HTC Trophy 7 with Windows Phone 7.

This means that 200+ employees will receive this new mobile phone and that Avanade Netherlands is the first company within the Netherlands to completely switch to the new mobile OS. Some articles online about this can be found here and here. Recently, also Dell announced to provide their employees with the new Dell Venue Pro which also runs on Windows Phone 7. There, it will replace the current BlackBerry phones.

Can’t wait to get my hands on¬†the new device and request a dev account. Should’nt be long now.