Friday, February 11, 2011

Retrieving Performance Data from System Center Operations Manager

System Center Operations Manager’s agent model means it can collect performance metrics from across a diverse technology environment. You use Rules to define the data collection and typically you use the Console to view the data in graphical format.

But, the Console by itself doesn’t allow any numerical analysis. If you want to do that you need to get the data out. You can copy to the clipboard within the Console Action menu but that’s very manual. A better approach is obviously programmatic access and this is  where things get interesting.

For some reason there’s little information on the net on how you get data out of SCOM. What is there usuall refers to querying the SCOM database directly. This doesn’t seem right to me. I’d far prefer an API that stood a chance of staying intact in future versions. So here’s what I’ve done.

Firstly, use the Powershell integration to SCOM to get the data. (This is easiest if you setup the Powershell ISE to connect to SCOM.) You can then use the get-performancecounter and get-performancecountervalue cmdlets to retrieve data, for example:

$starttime = [datetime]::today.adddays(-20)
$endtime = [datetime]::today.adddays(1)

get-performancecounter |
? {$_.ObjectName -eq 'Web Service' -and
$_.CounterName -eq 'Connection Attempts/sec' -and
$_.InstanceName -eq '_Total' -and
$_.MonitoringObjectPath -like 'usuallyAServerNameFilter*' } |
get-performancecountervalue -starttime $starttime -endtime $endtime |
select SampleValue, TimeSampled |
export-csv "c:\temp\ConnectionAttemptsPerSec.csv"

You can also use the .Net framework and languages to get the data – the documentation isn’t great but this example works (I’ve reduced the font size to try and make it fit in this blog template):

/// <summary> 
/// Gather performance data
/// </summary>
using System;
using System.Collections.ObjectModel;
using Microsoft.EnterpriseManagement;
using Microsoft.EnterpriseManagement.Common;
using Microsoft.EnterpriseManagement.Configuration;
using Microsoft.EnterpriseManagement.Monitoring;

namespace MySamples
class Program
static void Main(string[] args)
ManagementGroup mg = new ManagementGroup("someManagementServer");

MonitoringPerformanceDataCriteria mpdc =
new MonitoringPerformanceDataCriteria(
@"ObjectName = 'ASP.NET' and CounterName like 'Request Execution%' and MonitoringObjectPath like 'usuallyAServerNameFilter%'");
ReadOnlyCollection<MonitoringPerformanceData> mpds =

if (mpds.Count > 0) {
ReadOnlyCollection<MonitoringPerformanceDataValue> mpdvs = mpds[0].GetValues(DateTime.Today.AddDays(-1), DateTime.Today);

foreach (MonitoringPerformanceDataValue mpdv in mpdvs) {
Console.WriteLine("TimeSampled = " + mpdv.TimeSampled +
", SampleValue = " + mpdv.SampleValue);

Now I typically take the data out to F# and/or Excel and graph/model it to help figure my way through a problem. However, Microsoft have just released a nicely packaged analysis tool in Microsoft Sho – basically IronPython wrapped up with some plotting/graphing/math libraries – much like many of the other Python packages out there.

I thought this would be a fun way to interactively deal with performance data collection and analysis so I tried the following as an experiment (put in appropriate management server/monitoring object filters for you – I just used ASP.NET request execution times from a test environment as in the programs above).  The hist command takes a list, or I guess anything it can enumerate over and get numbers from, and returns a histogram dialog and plot.

ShoLoadAssembly("c:\Program Files\System Center Operations Manager 2007\SDK Binaries\Microsoft.EnterpriseManagement.OperationsManager.dll")
ShoLoadAssembly("c:\Program Files\System Center Operations Manager 2007\SDK Binaries\Microsoft.EnterpriseManagement.OperationsManager.dll")

import Microsoft.EnterpriseManagement
import Microsoft.EnterpriseManagement.Configuration
from Microsoft.EnterpriseManagement.Monitoring import *
from System import *

mg = Microsoft.EnterpriseManagement.ManagementGroup("aManagementServer")

mpdc = MonitoringPerformanceDataCriteria("ObjectName = 'ASP.NET' and CounterName like 'Request Execution%' and MonitoringObjectPath like 'someMonitoringObjectFilter%'")

mpds = mg.GetMonitoringPerformanceData(mpdc)

hist([mpdv.SampleValue for mpdv in mpds[0].GetValues(DateTime.Today.AddDays(-1), DateTime.Today)]

And here’s the output:


Cool huh!?

No comments: