SharePoint 2010 Custom Health Rule to check if the Solution Resource timerjobs are enabled when the Sandboxed Code Service is started

To monitor additional items not by default set up in SharePoint, custom health analyzer rules can be defined. For example the sandboxed solutions can be monitored a little bit better than SharePoint default provides.
When the Microsoft SharePoint Foundation Sandboxed Code Service is started sandboxed solutions can be deployed and used. To monitor the resources consumed by the sandboxed solutions a couple of timerjobs do the work of measuring and collecting the consumed resources:      

  • Solution Daily Resource Usage Update
  • Solution Resource Usage Log Processing
  • Solution Resource Usage Update

 

Wouldn’t it be nice to be sure the timerjobs are running when the Sandboxed Code Service is running?
Please continue reading on how to set this up.      

Building the rule

To set up a health analyzer rule, start with an empty SharePoint project. Add a class and inherit from SPHealthAnalysisRule. This is the class for the rule definition.
The class can also be inherited from SPRepairableHealthAnalysisRule. This means the rule can repair the problem. When using this the method Repair() has to be implemented as well.      

To define a rule some properties has to be overridden, like      

  • Category – Health Analyzer Rule Definitions are grouped by Category in the default view.
  • Summary – the title for the rule.
  • Explanation – displayed in the Health Reports list when the rule fails.
  • Remedy – displayed in the Health Reports list when the rule fails.
  • ErrorLevel – severity of the failure of the rule.

All rule definitions can be found in the rule definition list: Central Administration, Monitoring, Review rule definitions.
The Health Reports list can be found in the Central Administration, Monitoring, Review problems and solutions.      

The rule can be scheduled by overriding the AutomaticExecutionParameters property. In the get accessor return a SPHealthAnalysisRuleAutomaticExecutionParameters object.
When you don’t override the property the rule can be scheduled manually by a farm administrator.      

public override SPHealthAnalysisRuleAutomaticExecutionParameters AutomaticExecutionParameters
{
    get
    {
        SPHealthAnalysisRuleAutomaticExecutionParameters parameter = new SPHealthAnalysisRuleAutomaticExecutionParameters();
        parameter.Schedule = SPHealthCheckSchedule.Hourly;
        parameter.Scope = SPHealthCheckScope.Any;
        parameter.RepairAutomatically = false;
        parameter.ServiceType = typeof(SPTimerService);
        return parameter;
    }
}

In the code above the rule is scheduled on an hourly basis and the scope is set to SPHealthCheckScope.Any. This means the rule will run on the first available computer with the specified service.  

The code that identifies the real problem is the Check() method. The Check() method returns the outcome of the check: SPHeathStatus.Failed or SPHealthStatus.Passed. When Failed is the outcome of the check the rule will be displayed in the Health Reports list.


public override SPHealthCheckStatus Check()
{
    jobTitleOfDisabledJobs.Clear(); 

    SPUserCodeService userCodeService = SPUserCodeService.Local;
    if (userCodeService.IsEnabled)
    {
        using (SPSite site = new SPSite("your_site_url"))
            foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
            {
                switch (job.Title)
                {
                    case "Solution Daily Resource Usage Update":
                        AddJobTitle(job);
                        break;
                    case "Solution Resource Usage Log Processing":
                        AddJobTitle(job);
                        break;
                    case "Solution Resource Usage Update":
                        AddJobTitle(job);
                        break;
                    default:
                        break;
                }
            }

        if (jobTitleOfDisabledJobs.Count != 0)
        {
            return SPHealthCheckStatus.Failed;
        }
    }
    return SPHealthCheckStatus.Passed;
}

The above code first checks if the Sandboxes Code Service is started. If so, it checks if the timerjobs involved in measuring the resources consumed by the solutions are enabled.
The AddJobTitle() method adds the title(s) of the disabled job(s) to a generic list of strings:

private void AddJobTitle(SPJobDefinition job)
{
    if (job.IsDisabled)
    {
        jobTitleOfDisabledJobs.Add(job.Title);
    }
}

This list is used at the Explanation property to inform the farm administrator exactly which job(s) aren’t enabled:

public override string Explanation
{
    get
    {
        string jobTitles = string.Empty;
        for (int i = 0; i < jobTitleOfDisabledJobs.Count; i++)
        {
            jobTitles += jobTitleOfDisabledJobs[i].ToString();
            if (i != jobTitleOfDisabledJobs.Count - 1)
            {
                jobTitles += " / ";
            }
        }
        return "The Microsoft SharePoint Foundation Sandboxed Code Service is started, but not all the timerjobs are: " + jobTitles;
    }
}

Deploy the rule

To deploy the rule add a feature, scope it to farm level, and an event receiver to the feature.
Override the FeatureInstalled and FeatureUninstalling to register and unregister the rule:

public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
    try
    {
        Assembly currentAssembly = Assembly.GetExecutingAssembly();
        IDictionary<Type, Exception> exceptions = SPHealthAnalyzer.RegisterRules(currentAssembly); 

        if (exceptions != null)
        {
            if (exceptions.Count == 0)
            {
                //ok
            }
            else
            {
                //something went wrong, take appropriate action
            }
        }
    }
    catch (Exception ex)
    {
        throw new Exception("There was an error registering the health rule: " + ex.Message);
    }
} 

public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
    try
    {
        Assembly currentAssembly = Assembly.GetExecutingAssembly();
        IDictionary<Type, Exception> exceptions = SPHealthAnalyzer.UnregisterRules(currentAssembly); 

        if (exceptions != null)
        {
            if (exceptions.Count == 0)
            {
                //ok
            }
            else
            {
                //something went wrong, take appropriate action
            }
        }
    }
    catch (Exception ex)
    {
        throw new Exception("There was an error removing the health rule: " + ex.Message);
    }
}

After the deployment, the rule can be found in the rule definition list: Central Administration, Monitoring, Review rule definitions. The default view at this list is showing all the defined rules EXCEPT the rules defined with the categoy System. Ofcourse it’s possible to create an additional view to show all the rules.     

Run and test the rule

The rule is now scheduled to run every hour. To speed things up select the rule and press Run Now. The timerjob which actually runs the Health Analyzer jobs, this is dependent of the schedule, is in this case Health Analysis Job (Hourly, Microsoft SharePoint Foundation Timer, Any Server). Make this timerjob also run now and check the Health Reports list.
Check if the rule fails when enabling and disabling the sandbox timerjobs which are checked in the rule. Note that the Explanation of the rule changes when different sandbox timerjobs are disabled or enabled.
Keep in mind when debugging the rule that you attach the debugger to the timer services: OWSTimer.exe process.

Issues

Register Assemly in GAC

When developing the rule the following error occurred in my environment:
Error occurred in deployment step ‘Add Solution’: Health analyzer rule registration requires that the {0} assembly be registered in the global assembly cache.     

The workaround for me was to adjust the Site URL property of the project before every deployment. I know it’s not a nice solution and likely not THE solution, but it worked for me and restarting several services and jobs didn’t do the trick unfortunately.      

Settings are not updated

If you change your mind on for example the category or explanation while developing it is possible that after the deployment of the solution with the changed items and the rule fails, the rule shows up at the ‘old’ category or with the ‘old’ explanation. This is one of the possible ‘issues’ which can occur if you don’t restart the Timer Service Recyle timerjob. This job is like an iisreset, but for the timer service, it recycles the Timer Service to free resources. 

Summary

Health Analysis Rules are not that hard to program, except a few things to know, but can be really usefull to have an overview of issues at the farm.

One thought on “SharePoint 2010 Custom Health Rule to check if the Solution Resource timerjobs are enabled when the Sandboxed Code Service is started

  1. Pingback: Tweets die vermelden SharePoint 2010 Custom Health Rule to check if the Solution Resource timerjobs are enabled when the Sandboxed Code Service is started -- Topsy.com

Leave a Reply

Your email address will not be published. Required fields are marked *


two + 2 =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>