How to: Create, Modify, and Change a Bucket-Style Health-Score Calculator
Applies to: SharePoint Foundation 2010
This topic explains how to create, replace, and modify bucket-style health-score calculators that are associated with performance monitors in Microsoft SharePoint Foundation.
Important
The example in this topic uses a console application. Regardless of the type of project, it is critical that you set the correct target .NET Framework and CPU. The project must target Microsoft .NET Framework 3.5 (not Microsoft .NET Framework 4). The target CPU must be either Any CPU or x64. For information about the choice, see How to: Set the Correct Target Framework and CPU. The target CPU is usually x86 by default. To change it, right-click the project name in Solution Explorer and select Properties. You can change the CPU on the Build tab by using the Platform target drop-down list.
To begin the Visual Studio solution
Create a console application project in Visual Studio and set the target .NET Framework and CPU platform.
Add a reference to the Microsoft.SharePoint.dll to the project. It is in %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\ISAPI.
Open the program.cs file, set an appropriate namespace and class name, and add using statements for the Microsoft.SharePoint, Microsoft.SharePoint.Administration, and Microsoft.SharePoint.Utilities namespaces. Your code should now resemble the following:
using System; using Microsoft.SharePoint; using Microsoft.SharePoint.Administration; using Microsoft.SharePoint.Utilities; namespace Contoso.SharePoint.Utilities { class HealthCalculatorsUtility { static void Main(string[] args) { }// end Main } }
Continue with one of the procedures later in this topic.
Replacing a Health-Score Calculator
If you want to replace the health-score calculator associated with a monitor with a new one that has different bucket boundaries and possibly also changes the bucket-value ordering from ascending to descending, or vice versa, use the following procedure.
To replace the health-score calculator associated with a monitor
In the Main method, declare an array of Double values that define the boundaries of the buckets that the replacement health-score calculator uses to assign health scores to the values. Buckets are subranges of possible counter values. There are restrictions on how this array must be declared. For details about the restrictions, see the procedure "To add a performance monitor" in How to: Register or Deregister a Performance Counter. The following code shows a declaration of an array that is intended to create buckets for the Windows Server 2008 counter named "Processor\% Processor Time". This counter reports the percentage of time the processors of the server are spending on processes other than the System Idle process. For more information about this counter, see Processor Object.
double[] busyProcessorBuckets = new double[10] {20.0, 28.8, 37.6, 46.4, 55.2, 64.0, 72.8, 81.6, 90.4, 99.2};
Call the SPBucketHealthScoreCalculator constructor and pass the buckets array object as a parameter. Pass true or false for the second parameter depending on whether the array is ascending or descending, respectively. The following code continues the example.
SPBucketHealthScoreCalculator nonIdleTimeHealthCalculator = new SPBucketHealthScoreCalculator(busyProcessorBuckets, true);
In the Main method, get a reference to the Web application and then get a reference to the throttle settings by calling the GetHttpThrottleSettings(SPPersistedObject) method. The following example shows how.
Uri webApplicationUri = new Uri("Http://localhost/"); SPWebApplication webApplication = SPWebApplication.Lookup(webApplicationUri); SPHttpThrottleSettings throttleSettings = SPHttpThrottleSettings.GetHttpThrottleSettings(webApplication);
Inside the Main method, get a reference to the persisted collection of SPPerformanceMonitorCreationData objects. (The actual performance monitor objects [SPSystemPerformanceCounterMonitor] are created at run time from these stored creation-data objects.)
SPHttpThrottlingMonitors myMonitors = throttleSettings.PerformanceMonitors;
Still in the Main method, get a reference to the particular instance of the performance monitor whose health-score calculator you want to replace and assign the new calculator to its AssociatedHealthScoreCalculator property. In some cases, you know at design time the index of the monitor in the collection. More often, your code identifies it by category, counter, and instance name, as in the following example. Notice that Update() is called to save the changes to the configuration database.
foreach (SPPerformanceMonitorCreationData creationData in myMonitors) { if (creationData.Category.Equals("Processor", StringComparison.OrdinalIgnoreCase) & creationData.Counter.Equals("% Processor Time", StringComparison.OrdinalIgnoreCase) & creationData.Instance.Equals("0", StringComparison.OrdinalIgnoreCase)) { creationData.AssociatedHealthScoreCalculator = nonIdleTimeHealthCalculator; throttleSettings.Update(); break; } }
Modifying the Bucket Boundaries
You do not have to replace the entire health-score calculator that is associated with a monitor if you need to change only the bucket boundaries. If the new boundaries match the ascending or descending ordering of the existing boundaries, you can use the SetScoreBuckets([]) method to change the boundaries.
To modify the boundaries of the buckets
In the Main method, declare an array of Double values that define the new boundaries of the buckets. Buckets are subranges of possible counter values. There are restrictions on how this array must be declared. For details about the restrictions, see the procedure "To add a performance monitor" in How to: Register or Deregister a Performance Counter. The following code shows a declaration of an array that is intended to create buckets for the Windows Server 2008 counter named "Processor\% Processor Time". But, unlike the buckets defined in the section Replacing a Health-Score Calculator earlier in this topic, this array defines an exponentially rising set of values.
double[] busyProcessorBuckets = new double[5] {5.0, 10.0, 20.0, 40.0, 80.0};
Instead of creating a new calculator object, get a reference to the existing calculator you want to modify and cast it to the class that represents bucket-style calculators. The steps are the same as in the section Replacing a Health-Score Calculator earlier in this topic. The following code shows the outcome of the steps:
Uri webApplicationUri = new Uri("Http://localhost/"); SPWebApplication webApplication = SPWebApplication.Lookup(webApplicationUri); SPHttpThrottleSettings throttleSettings = SPHttpThrottleSettings.GetHttpThrottleSettings(webApplication); SPHttpThrottlingMonitors myMonitors = throttleSettings.PerformanceMonitors; foreach (SPPerformanceMonitorCreationData creationData in myMonitors) { if (creationData.Category.Equals("Processor", StringComparison.OrdinalIgnoreCase) & creationData.Counter.Equals("% Processor Time", StringComparison.OrdinalIgnoreCase) & creationData.Instance.Equals("0", StringComparison.OrdinalIgnoreCase)) { SPBucketHealthScoreCalculator bucketScoreCalculator = (SPBucketHealthScoreCalculator)creationData.AssociatedHealthScoreCalculator; } }
Still inside the if structure, call the SetScoreBuckets([]) method of the monitor creation-data object and pass the new bucket array. Be sure to call Update() to save the change.
bucketScoreCalculator.SetScoreBuckets(busyProcessorBuckets); throttleSettings.Update(); break;