Memory and processor monitoring [SNMP MP Chap 3] #scom #sysctr


As I anticipated in the first chapter of this guide, in the current OpsMgr version (2012 SP1) one of the main differences between generic and certified devices is memory and processor monitoring. The most evident of the two is the lack of processor monitoring because it is plotted in then network devices dashboard.

Now that we have uniquely identified our device we’re ready to add processor and memory monitoring. The only thing that we must check for is the device support for processor and memory monitoring through SNMP: I have old Procurve switches that don’t expose them through SNMP.

To check for device support we can check the device SNMP documentation, it usually comes in a list of supported MIBs, or we can dumb dump the entire SNMP tree directly from the device. The latter can be time consuming and troublesome since if there’s no string hint on the returned values it can be impossible to understand which of them is memory or processor related.

In any case, since taking a complete device dump is good diagnostic and troubleshooting practice, I strongly encourage to go for it and cross check with the documentation. Using our SharpSNMPLib we can issue the following command for a device identified with IP 1.1.1.1 supporting SNMPv2 with a community of public:

snmpwalk -v=2 -c=public 1.1.1.1

Some SNMP implementation don’t allow to recursively walk all the tree branches, so if some of the documented OIDs do not list in the dump, you have to try walking them explicitly, in this case I’m dumping everything under the enterprise OID 41091:

 snmpwalk -v=2 -c=public 1.1.1.1 .1.3.6.1.4.1.41091

Whichever utility you use to dump the device SNMP tree, please remember to dump numeric OIDs (not mnemonics) since OpsMgr modules accept numeric OIDs only.

In the next chapter we will see how to do this via Powershell.

Once we have the OIDs for memory and processor, adding the monitoring part is really straightforward since the basic classes, monitors and rules types are already in place.

We just need to define:

          A proper class for processor and memory that inherits from base processor and memory classes System.NetworkManagement.Processor and System.NetworkManagement.Memory

          A proper discovery for memory and processor using the same technique we leveraged in device discovery

          A monitor to check for consumption and a rule to collect the usage

Class definitions

     <EntityTypes>
  <ClassTypes>
    <ClassType ID="QND.MyDevice.Memory" Accessibility="Public" Abstract="false" Base="Network!System.NetworkManagement.Memory" Hosted="true" Singleton="false" Extension="false" />
    <ClassType ID="QND.MyDevice.Processor" Accessibility="Public" Abstract="false" Base="Network!System.NetworkManagement.Processor" Hosted="true" Singleton="false" Extension="false" />
 
  </ClassTypes>
</EntityTypes>

 

Before defining any discovery a proper module must be defined, both discovery modules are composed by:

          A discovery scheduler, to set the discovery frequency (System.Discovery.Scheduler)

          An SNMP probe to check for the OID existence. The OID must be the one we used for idientying the device. In my example I will use standard host OIDs. .1.3.6.1.4.1.2021.4.6.0 for memoery (iso.org.dod.internet.private.enterprises.ucdavis.memory) and .1.3.6.1.4.1.2021.10.1.2.2 for processor. Again these are only ecamples, you must identify the correct OIDs for your device. The advice here is to use the same OIDs that can be used to get the performance data. (System.NetworkManagement.SnmpProbe)

          A discovery data mapper to map the discovered logical device to the previously defined class. QND.MyDevice.Processor|Memory in our example. (System.Discovery.ClassSnapshotDataMapper)

As you can see it’s really a matter of copy and paste and change only the highlighted tags. You can even create a VSAE snippet, but this is something we’ll build if this articles series will get some community support.

Module types definition

<DataSourceModuleType ID="QND.MyDevice.Processor.Discovery.DS" Accessibility="Public" Batching="false">
    <Configuration>
      <xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer" />
      <xsd:element minOccurs="0" name="SyncTime" type="xsd:string" />
      <xsd:element minOccurs="0" maxOccurs="1" name="Port" type="xsd:unsignedInt" default="161" />
      <xsd:element name="IP" type="xsd:string" />
      <xsd:element name="CommunityString" type="xsd:string" />
      <xsd:element minOccurs="0" maxOccurs="1" name="Version" type="xsd:string" />
      <xsd:element minOccurs="1" name="DeviceKey" type="xsd:string" />
    </Configuration>
    <ModuleImplementation Isolation="Any">
      <Composite>
        <MemberModules>
          <DataSource ID="Scheduler" TypeID="System!System.Discovery.Scheduler">
            <Scheduler>
              <SimpleReccuringSchedule>
                <Interval>$Config/IntervalSeconds$</Interval>
                <SyncTime>$Config/SyncTime$</SyncTime>
              </SimpleReccuringSchedule>
              <ExcludeDates />
            </Scheduler>
          </DataSource>
          <ProbeAction ID="Probe" TypeID="Network!System.NetworkManagement.SnmpProbe">
            <Walk>false</Walk>
            <WalkReturnMultipleItems>false</WalkReturnMultipleItems>
            <NoOfRetries>3</NoOfRetries>
            <Timeout>500</Timeout>
            <Port>$Config/Port$</Port>
            <SNMPv3UserName>$RunAs[Name="Network!System.NetworkManagement.SnmpV3.MonitoringAccount"]/UserName$</SNMPv3UserName>
            <SNMPv3AuthProtocol>$RunAs[Name="Network!System.NetworkManagement.SnmpV3.MonitoringAccount"]/AuthenticationProtocol$</SNMPv3AuthProtocol>
            <SNMPv3AuthPassword>$RunAs[Name="Network!System.NetworkManagement.SnmpV3.MonitoringAccount"]/AuthenticationKey$</SNMPv3AuthPassword>
            <SNMPv3PrivProtocol>$RunAs[Name="Network!System.NetworkManagement.SnmpV3.MonitoringAccount"]/PrivacyProtocol$</SNMPv3PrivProtocol>
            <SNMPv3PrivPassword>$RunAs[Name="Network!System.NetworkManagement.SnmpV3.MonitoringAccount"]/PrivacyKey$</SNMPv3PrivPassword>
            <SNMPv3ContextName>$RunAs[Name="Network!System.NetworkManagement.SnmpV3.MonitoringAccount"]/ContextName$</SNMPv3ContextName>
            <IsWriteAction>false</IsWriteAction>
            <IP>$Config/IP$</IP>
            <CommunityString>$Config/CommunityString$</CommunityString>
            <Version>$Config/Version$</Version>
            <SnmpVarBinds>
              <SnmpVarBind>
                <OID>.1.3.6.1.4.1.2021.10.1.2.2</OID>
                <!-- ** iso.3.6.1.4.1.2021.10.1.2.2 = STRING: "Load-5" -->
                <Syntax>0</Syntax>
                <Value VariantType="8" />
              </SnmpVarBind>
            </SnmpVarBinds>
            <OutputOnError>false</OutputOnError>
          </ProbeAction>
          <ConditionDetection ID="MapToDiscovery" TypeID="System!System.Discovery.ClassSnapshotDataMapper">
            <ClassId>$MPElement[Name='QND.MyDevice.Processor']$</ClassId>
            <InstanceSettings>
              <Settings>
                <Setting>
                  <Name>$MPElement[Name='Network!System.NetworkManagement.Node']/DeviceKey$</Name>
                  <Value>$Config/DeviceKey$</Value>
                </Setting>
                <Setting>
                  <Name>$MPElement[Name='Network!System.NetworkManagement.LogicalDevice']/Key$</Name>
                  <Value>.1.3.6.1.4.1.2021.10.1.5.2</Value>
                  <!-- sys load 5 mins iso.3.6.1.4.1.2021.10.1.5.2 = INTEGER: 5 -->
                </Setting>
                <Setting>
                  <Name>$MPElement[Name='Network!System.NetworkManagement.LogicalDevice']/Index$</Name>
                  <Value>2</Value>
                </Setting>
                <Setting>
                  <Name>$MPElement[Name='Network!System.NetworkManagement.LogicalDevice']/Description$</Name>
                  <Value>Processor Load</Value>
                </Setting>
                <Setting>
                  <Name>$MPElement[Name='System!System.Entity']/DisplayName$</Name>
                  <Value>Processor</Value>
                </Setting>
              </Settings>
            </InstanceSettings>
          </ConditionDetection>
        </MemberModules>
        <Composition>
          <Node ID="MapToDiscovery">
            <Node ID="Probe">
              <Node ID="Scheduler" />
            </Node>
          </Node>
        </Composition>
      </Composite>
    </ModuleImplementation>
    <OutputType>System!System.Discovery.Data</OutputType>
  </DataSourceModuleType>
 
  <DataSourceModuleType ID="QND.MyDevice.Memory.Discovery.DS" Accessibility="Public" Batching="false">
    <Configuration>
      <xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer" />
      <xsd:element minOccurs="0" name="SyncTime" type="xsd:string" />
      <xsd:element minOccurs="0" maxOccurs="1" name="Port" type="xsd:unsignedInt" default="161" />
      <xsd:element name="IP" type="xsd:string" />
      <xsd:element name="CommunityString" type="xsd:string" />
      <xsd:element minOccurs="0" maxOccurs="1" name="Version" type="xsd:string" />
      <xsd:element minOccurs="1" name="DeviceKey" type="xsd:string" />
    </Configuration>
    <ModuleImplementation Isolation="Any">
      <Composite>
        <MemberModules>
          <DataSource ID="Scheduler" TypeID="System!System.Discovery.Scheduler">
            <Scheduler>
              <SimpleReccuringSchedule>
                <Interval>$Config/IntervalSeconds$</Interval>
                <SyncTime>$Config/SyncTime$</SyncTime>
              </SimpleReccuringSchedule>
              <ExcludeDates />
            </Scheduler>
          </DataSource>
          <ProbeAction ID="Probe" TypeID="Network!System.NetworkManagement.SnmpProbe">
            <Walk>false</Walk>
            <WalkReturnMultipleItems>false</WalkReturnMultipleItems>
            <NoOfRetries>3</NoOfRetries>
            <Timeout>500</Timeout>
            <Port>$Config/Port$</Port>
            <SNMPv3UserName>$RunAs[Name="Network!System.NetworkManagement.SnmpV3.MonitoringAccount"]/UserName$</SNMPv3UserName>
            <SNMPv3AuthProtocol>$RunAs[Name="Network!System.NetworkManagement.SnmpV3.MonitoringAccount"]/AuthenticationProtocol$</SNMPv3AuthProtocol>
            <SNMPv3AuthPassword>$RunAs[Name="Network!System.NetworkManagement.SnmpV3.MonitoringAccount"]/AuthenticationKey$</SNMPv3AuthPassword>
            <SNMPv3PrivProtocol>$RunAs[Name="Network!System.NetworkManagement.SnmpV3.MonitoringAccount"]/PrivacyProtocol$</SNMPv3PrivProtocol>
            <SNMPv3PrivPassword>$RunAs[Name="Network!System.NetworkManagement.SnmpV3.MonitoringAccount"]/PrivacyKey$</SNMPv3PrivPassword>
            <SNMPv3ContextName>$RunAs[Name="Network!System.NetworkManagement.SnmpV3.MonitoringAccount"]/ContextName$</SNMPv3ContextName>
            <IsWriteAction>false</IsWriteAction>
            <IP>$Config/IP$</IP>
            <CommunityString>$Config/CommunityString$</CommunityString>
            <Version>$Config/Version$</Version>
            <SnmpVarBinds>
              <SnmpVarBind>
                <OID>.1.3.6.1.4.1.2021.4.6.0</OID>
                <!-- iso.3.6.1.4.1.2021.4.6.0 = INTEGER: 204984 ** Avail Real KB -->
                <Syntax>0</Syntax>
                <Value VariantType="8" />
              </SnmpVarBind>
            </SnmpVarBinds>
            <OutputOnError>false</OutputOnError>
          </ProbeAction>
          <ConditionDetection ID="MapToDiscovery" TypeID="System!System.Discovery.ClassSnapshotDataMapper">
            <ClassId>$MPElement[Name='QND.MyDevice.Memory']$</ClassId>
            <InstanceSettings>
              <Settings>
                <Setting>
                  <Name>$MPElement[Name='Network!System.NetworkManagement.Node']/DeviceKey$</Name>
                  <Value>$Config/DeviceKey$</Value>
                </Setting>
                <Setting>
                  <Name>$MPElement[Name='Network!System.NetworkManagement.LogicalDevice']/Key$</Name>
                  <Value>.1.3.6.1.4.1.2021.4.6</Value>
                  <!-- iso.3.6.1.4.1.2021.4.6.0 = INTEGER: 204984 ** Avail Real KB -->
                </Setting>
                <Setting>
                  <Name>$MPElement[Name='Network!System.NetworkManagement.LogicalDevice']/Index$</Name>
                  <Value>0</Value>
                </Setting>
                <Setting>
                  <Name>$MPElement[Name='Network!System.NetworkManagement.LogicalDevice']/Description$</Name>
                  <Value>System Memory</Value>
                </Setting>
                <Setting>
                  <Name>$MPElement[Name='System!System.Entity']/DisplayName$</Name>
                  <Value>Memory</Value>
                </Setting>
              </Settings>
            </InstanceSettings>
          </ConditionDetection>
        </MemberModules>
        <Composition>
          <Node ID="MapToDiscovery">
            <Node ID="Probe">
              <Node ID="Scheduler" />
            </Node>
          </Node>
        </Composition>
      </Composite>
    </ModuleImplementation>
    <OutputType>System!System.Discovery.Data</OutputType>
  </DataSourceModuleType>

 

 

The same technique can be used for any single instance logical device hosted by our device. We will talk of multiple instances device in a specific chapter.

The discovery rules

<Discovery ID="QND.MyDevice.Processor.Discovery" Enabled="true" ConfirmDelivery="false" Remotable="true" Priority="Normal" Target="QND.MyDevice.Device">
  <Category>Discovery</Category>
  <DiscoveryTypes>
    <DiscoveryClass TypeID="QND.MyDevice.Processor" />
  </DiscoveryTypes>
  <DataSource ID="DS" TypeID="QND.MyDevice.Processor.Discovery.DS">
    <IntervalSeconds>43200</IntervalSeconds>
    <SyncTime />
    <Port>$Target/Property[Type="Network!System.NetworkManagement.Node"]/PortNumber$</Port>
    <IP>$Target/Property[Type="Network!System.NetworkManagement.Node"]/SNMPAddress$</IP>
    <CommunityString>$RunAs[Name="Network!System.NetworkManagement.Snmp.MonitoringAccount"]/CommunityString$$Target/Property[Type="Network!System.NetworkManagement.Node"]/VirtualCommunitySuffix$</CommunityString>
    <Version>$Target/Property[Type="Network!System.NetworkManagement.Node"]/SNMPVersion$</Version>
    <DeviceKey>$Target/Property[Type="Network!System.NetworkManagement.Node"]/DeviceKey$</DeviceKey>
  </DataSource>
</Discovery>
<Discovery ID="QND.MyDevice.Memory.Discovery" Enabled="true" ConfirmDelivery="false" Remotable="true" Priority="Normal" Target="QND.MyDevice.Device">
  <Category>Discovery</Category>
  <DiscoveryTypes>
    <DiscoveryClass TypeID="QND.MyDevice.Memory" />
  </DiscoveryTypes>
  <DataSource ID="DS" TypeID="QND.MyDevice.Memory.Discovery.MT">
    <IntervalSeconds>43200</IntervalSeconds>
    <SyncTime />
    <Port>$Target/Property[Type="Network!System.NetworkManagement.Node"]/PortNumber$</Port>
    <IP>$Target/Property[Type="Network!System.NetworkManagement.Node"]/SNMPAddress$</IP>
    <CommunityString>$RunAs[Name="Network!System.NetworkManagement.Snmp.MonitoringAccount"]/CommunityString$$Target/Property[Type="Network!System.NetworkManagement.Node"]/VirtualCommunitySuffix$</CommunityString>
    <Version>$Target/Property[Type="Network!System.NetworkManagement.Node"]/SNMPVersion$</Version>
    <DeviceKey>$Target/Property[Type="Network!System.NetworkManagement.Node"]/DeviceKey$</DeviceKey>
  </DataSource>
</Discovery>

 

Once we have discovered the memory and processor components we’re ready to check for their healthstate and to collect performance. For the purpose of this sample let’s say we want to monitor the processor and memory percentage usage. To make things a little more complex we assume the CPU performance is expressed in percentage, while memory is expressed in free memory and total memory. As soon as we leave the discovery space we can start to leverage several complex modules already defined for us. As you can remember in OpsMgr discovery is supposed to be performed by the Smarts modules outside standard OpsMgr discovery rules, so the modules for discovery are not specifically developed.

To monitor for processor utilization we can use the System.NetworkManagement.ThresholdMonitor Unit monitor type, the usage is pretty straightforward. AS you can see I use the DeviceKey previously discovered to collect processor usage and set a default threshold of 90% for three consecutive samples. Working with the SNMP modules I find pretty useful to use the device key e index to memorize the device OID we can then use in monitors and rules, this is not a fixed rule, but I think it’s a practice that gives a lot of flexibility and code reuse:

Monitoring processor usage

<UnitMonitor ID=QND.MyDevice.ProcessorUsage.Monitor Accessibility=Public Enabled=false Target=QND.MyDevice.Processor ParentMonitorID=Health!System.Health.PerformanceState Remotable=true Priority=Normal

             TypeID=NetworkMonitor!System.NetworkManagement.ThresholdMonitor ConfirmDelivery=false>

  <Category>PerformanceHealth</Category>

  <AlertSettings AlertMessage=QND.MyDevice.ProcessorUsage.AlertMessage>

    <AlertOnState>Error</AlertOnState>

    <AutoResolve>true</AutoResolve>

    <AlertPriority>Normal</AlertPriority>

    <AlertSeverity>MatchMonitorHealth</AlertSeverity>

    <AlertParameters>

      <AlertParameter1>$Target/Host/Property[Type=”System!System.Entity”]/DisplayName$</AlertParameter1>

      <AlertParameter2>$Data/Context/SampleValue$</AlertParameter2>

    </AlertParameters>

  </AlertSettings>

  <OperationalStates>

    <OperationalState ID=OverThreshold MonitorTypeStateID=MTSThresholdError HealthState=Error />

    <OperationalState ID=UnderThreshold MonitorTypeStateID=MTSThresholdSuccess HealthState=Success />

  </OperationalStates>

  <Configuration>

    <Interval>300</Interval>

    <NoOfRetries>3</NoOfRetries>

    <Timeout>3500</Timeout>

    <OID>$Target/Property[Type=”Network!System.NetworkManagement.LogicalDevice”]/Key$</OID>

    <Threshold>90</Threshold>

    <NumberOfSamples>3</NumberOfSamples>

    <ObjectName>Processor</ObjectName>

    <CounterName>% Processor Time</CounterName>

  </Configuration>

</UnitMonitor>

 

The memory side is a little more complicated, in fact we need to calculate the free memory percentage. Without the specific SNMP module “System.NetworkManagement.ComputedThresholdMonitorType” we should have used a powershell probe to transform the returned data. With this module we can build the following expression: (free / total) * 100. As for OpMgr expression the syntax is in Reverse Polish Notation where operands come after the operator.

Calculating SNMP values

    <ComputedPerformanceValue>
      <Product>
        <NumericValue>
          <Division>
            <NumericValue>
              <XPathQuery Type="Double">SnmpVarBinds/SnmpVarBind[OID=".1.3.6.1.4.1.2021.4.6.0"]/Value</XPathQuery>
            </NumericValue>
            <NumericValue>
              <XPathQuery Type="Double">SnmpVarBinds/SnmpVarBind[OID=".1.3.6.1.4.1.2021.4.5.0"]/Value</XPathQuery>
            </NumericValue>
          </Division>
        </NumericValue>
        <NumericValue>
          <Value Type="Double">100.0</Value>
        </NumericValue>
      </Product>
    </ComputedPerformanceValue>

 

The complete monitor is:

Free memory percentage monitor

<UnitMonitor ID="QND.MyDevice.MemoryUsage.Monitor" Accessibility="Public" Enabled="true" Target="QND.MyDevice.Memory" ParentMonitorID="Health!System.Health.PerformanceState" Remotable="true" Priority="Normal"
             TypeID="NetworkMonitor!System.NetworkManagement.ComputedThresholdMonitorType" ConfirmDelivery="false">
  <Category>PerformanceHealth</Category>
  <AlertSettings AlertMessage="QND.MyDevice.MemoryUsage.AlertMessage">
    <AlertOnState>Error</AlertOnState>
    <AutoResolve>true</AutoResolve>
    <AlertPriority>Normal</AlertPriority>
    <AlertSeverity>MatchMonitorHealth</AlertSeverity>
    <AlertParameters>
      <AlertParameter1>$Target/Host/Property[Type="System!System.Entity"]/DisplayName$</AlertParameter1>
      <AlertParameter2>$Data/Context/Value$</AlertParameter2>
    </AlertParameters>
  </AlertSettings>
  <OperationalStates>
    <OperationalState ID="OverThreshold" MonitorTypeStateID="MTSThresholdError" HealthState="Success" />
    <!-- the logic is inverted Monitor type author has choosen a bad naming convention -->
    <OperationalState ID="UnderThreshold" MonitorTypeStateID="MTSThresholdSuccess" HealthState="Error" />
  </OperationalStates>
  <Configuration>
    <Interval>300</Interval>
    <NoOfRetries>3</NoOfRetries>
    <NumberOfSamples>3</NumberOfSamples>
    <Timeout>3500</Timeout>
    <SnmpVarBinds>
      <SnmpVarBind>
        <OID>.1.3.6.1.4.1.2021.4.5.0</OID>
        <!-- Total Real -->
        <Syntax>0</Syntax>
        <Value VariantType="8" />
      </SnmpVarBind>
      <SnmpVarBind>
        <OID>.1.3.6.1.4.1.2021.4.6.0</OID>
        <!-- Free Real -->
        <Syntax>0</Syntax>
        <Value VariantType="8" />
      </SnmpVarBind>
    </SnmpVarBinds>
    <ComputedPerformanceValue>
      <Product>
        <NumericValue>
          <Division>
            <NumericValue>
              <XPathQuery Type="Double">SnmpVarBinds/SnmpVarBind[OID=".1.3.6.1.4.1.2021.4.6.0"]/Value</XPathQuery>
            </NumericValue>
            <NumericValue>
              <XPathQuery Type="Double">SnmpVarBinds/SnmpVarBind[OID=".1.3.6.1.4.1.2021.4.5.0"]/Value</XPathQuery>
            </NumericValue>
          </Division>
        </NumericValue>
        <NumericValue>
          <Value Type="Double">100.0</Value>
        </NumericValue>
      </Product>
    </ComputedPerformanceValue>
    <Threshold>5</Threshold>
    <ObjectName>Memory</ObjectName>
    <CounterName>% Memory Free</CounterName>
  </Configuration>
</UnitMonitor>

 

I know this XML code is pretty verbose, but really it’s a matter of copy and paste, once you get here you can monitor any device component hosted by your device.

We still miss the performance collection:

XML

<Rule ID="QND.MyDevice.ProcessorUsage.Rule" Enabled="true" Target="QND.MyDevice.Processor" ConfirmDelivery="false" Remotable="true" Priority="Normal" DiscardLevel="100">
  <Category>PerformanceCollection</Category>
  <DataSources>
    <DataSource ID="DS" TypeID="NetworkMonitor!System.NetworkManagement.ExtendedSnmpPerformanceProvider">
      <Interval>300</Interval>
      <NoOfRetries>3</NoOfRetries>
      <Timeout>3500</Timeout>
      <OID>$Target/Property[Type="Network!System.NetworkManagement.LogicalDevice"]/Key$</OID>
      <ObjectName>Processor</ObjectName>
      <CounterName>% Processor Time</CounterName>
    </DataSource>
  </DataSources>
  <ConditionDetection ID="OptimizedFilter" TypeID="Perf!System.Performance.OptimizedCollectionFilter">
    <Tolerance>3</Tolerance>
    <ToleranceType>Absolute</ToleranceType>
    <MaximumSampleSeparation>6</MaximumSampleSeparation>
    <SamplingPeriodInSeconds>300</SamplingPeriodInSeconds>
  </ConditionDetection>
  <WriteActions>
    <WriteAction ID="WriteToDB" TypeID="SC!Microsoft.SystemCenter.CollectPerformanceData" />
    <WriteAction ID="WriteToDW" TypeID="SCDW!Microsoft.SystemCenter.DataWarehouse.PublishPerformanceData" />
  </WriteActions>
</Rule>
<Rule ID="QND.MyDevice.FreeMemory.Rule" Enabled="true" Target="QND.MyDevice.Memory" ConfirmDelivery="false" Remotable="true" Priority="Normal" DiscardLevel="100">
  <Category>PerformanceCollection</Category>
  <DataSources>
    <DataSource ID="DS" TypeID="NetworkMonitor!System.NetworkManagement.ComputedPerfProvider">
      <Interval>300</Interval>
      <NoOfRetries>3</NoOfRetries>
      <Timeout>3500</Timeout>
      <SnmpVarBinds>
        <SnmpVarBind>
          <OID>.1.3.6.1.4.1.2021.4.5.0</OID>
          <!-- Total Real -->
          <Syntax>0</Syntax>
          <Value VariantType="8" />
        </SnmpVarBind>
        <SnmpVarBind>
          <OID>.1.3.6.1.4.1.2021.4.6.0</OID>
          <!-- Free Real -->
          <Syntax>0</Syntax>
          <Value VariantType="8" />
        </SnmpVarBind>
      </SnmpVarBinds>
      <ComputedPerformanceValue>
        <Product>
          <NumericValue>
            <Division>
              <NumericValue>
                <XPathQuery Type="Double">SnmpVarBinds/SnmpVarBind[OID=".1.3.6.1.4.1.2021.4.6.0"]/Value</XPathQuery>
              </NumericValue>
              <NumericValue>
                <XPathQuery Type="Double">SnmpVarBinds/SnmpVarBind[OID=".1.3.6.1.4.1.2021.4.5.0"]/Value</XPathQuery>
              </NumericValue>
            </Division>
          </NumericValue>
          <NumericValue>
            <Value Type="Double">100.0</Value>
          </NumericValue>
        </Product>
      </ComputedPerformanceValue>
      <ObjectName>Memory</ObjectName>
      <CounterName>% Memory Free</CounterName>
    </DataSource>
  </DataSources>
  <ConditionDetection ID="OptimizedFilter" TypeID="Perf!System.Performance.OptimizedCollectionFilter">
    <Tolerance>3</Tolerance>
    <ToleranceType>Absolute</ToleranceType>
    <MaximumSampleSeparation>6</MaximumSampleSeparation>
    <SamplingPeriodInSeconds>300</SamplingPeriodInSeconds>
  </ConditionDetection>
  <WriteActions>
    <WriteAction ID="WriteToDB" TypeID="SC!Microsoft.SystemCenter.CollectPerformanceData" />
    <WriteAction ID="WriteToDW" TypeID="SCDW!Microsoft.SystemCenter.DataWarehouse.PublishPerformanceData" />
  </WriteActions>
</Rule>

 

Two things to highlight here:

          Personally I don’t like performance collecting rules not ‘optimized’, so in both cases I added an optimization with a tolerance of 3%

          To have your device plotted in the network device dashboard you must use the Processor / % Processor Time object and counter

That’s it, you generic device is now on par with the certified ones. In many cases we are going to want more, but what I’m going to show in the next chapters will apply indifferently to both generic and certified devices.

– Daniele

This posting is provided “AS IS” with no warranties, and confers no rights.

Advertisements
  1. #1 by bluej on February 10, 2016 - 7:57 am

    Hi Daniele,

    further to the first question, I created the processor and memory monitor exactly as your instruction, both works fine. However once I change the monitor to target the main class instead of the processor or memory class, the monitors stop working. It shows as uninitialized. Tried to figure it out for the whole day but no luck. Any suggestions? Thanks a lot!

    • #2 by Daniele Grandini on February 12, 2016 - 8:06 am

      Only thing I can think of is a mismatach on the OID if memory serves I’m building the OID starting form the target class, if you change the target you need to change the OID as well.

      • #3 by bluej on February 12, 2016 - 7:36 pm

        Hi Daniele,

        Thanks for the reply. I changed the correct OID but got the same thing.
        My monitor’s configuration is as following. .1.3.6.1.4.1.3417.2.11.3.1.3.1.0 is the OID stores the http connection number.

        300
        3
        60
        .1.3.6.1.4.1.3417.2.11.3.1.3.1.0
        45000
        3
        Network
        ClientHttpConnection

        However I found an alternative.

        By reading the XML of System.NetworkManagement.Monitoring, I found monitor type System.NetworkManagement.ThresholdMonitor using System.NetworkManagement.Host.ExtendedSnmpQueryProvider as data source which has its own data source defined as following

        $Config/Interval$
        $Config/NoOfRetries$
        $Config/Timeout$
        $Target/Host/Property[Type=”NetworkLibrary!System.NetworkManagement.Node”]/PortNumber$
        $Target/Host/Property[Type=”NetworkLibrary!System.NetworkManagement.Node”]/SNMPAddress$
        $RunAs[Name=”NetworkLibrary!System.NetworkManagement.Snmp.MonitoringAccount”]/CommunityString$$Target/Host/Property[Type=”NetworkLibrary!System.NetworkManagement.Node”]/VirtualCommunitySuffix$
        $Target/Host/Property[Type=”NetworkLibrary!System.NetworkManagement.Node”]/SNMPVersion$
        $Config/SnmpVarBinds$
        $Config/OutputOnError$

        See those Target/Host used in the parameters? The main class is created from System.NetworkManagement.Node and I guess it doesn’t support “Host” like a normal windows server or logical device.

        So as a quick and dirty job, I just simply copied everything of System.NetworkManagement.ThresholdMonitor into my MP, then change “Target/Host” to “Target”. At the last instead of using the default System.NetworkManagement.ThresholdMonitor monitor type, I used the modified version in my MP and it works.

        Hope it helps.

      • #4 by Daniele Grandini on February 13, 2016 - 10:42 am

        hi bluej, I probably assumed too many things were clear, obviously if you change the target, you must take care of any hosting relationship. Relationships work in a consistent way across SCOM MPs and classes. So if you target a class that is hosted by another class (device hosts cpu) and need to access properties of the hosting class (device) you must specify /host/ in the property path, but if you target directly the device, since the property is from the target itself, you don’t need to specify /host/. Anyway glad that now it works.

  2. #5 by bluej on February 6, 2016 - 6:12 am

    Thanks for the detailed step-by-step article. Very useful. Got few questions
    1. To monitor processor and memory, you created a class and populate it using discovery at the first, is this a must step? Could we create monitor and target it to “QND.MyDevice.Device” directly? If so, what monitor type should be used, System.NetworkManagement.ThresholdMonitor?
    2. I need to monitor a Bluecoat proxy which has one performance counter exposed with OID .1.3.6.1.4.1.3417.2.11.3.1.3.1.0. If I use snmpget to query this OID I can get the value as expected. I tried to follow your steps to create the monitor. However this means I need to create a class/discovery at the first. Then for the class, what base class I should use then?

    Thanks!

    • #6 by Daniele Grandini on February 8, 2016 - 7:43 am

      Hi bluej,
      You don’t have to create a class for CPU and/or memory, my choice was out of a matter of consistency on one side and an example to build a complete health model on the other. You can definitely bind the monitor to the main device without the need to create and discover specific classes.
      Same story for BlueCoat, just discover the main device and bind the monitor to it, if you don’t want to create specific classes for components.

      -Daniele

      • #7 by bluej on February 8, 2016 - 7:44 pm

        Thanks for quick reply.
        I created a System.NetworkManagement.ThresholdMonitor type monitor and make it target to the main class. However when I import it into SCOM, the monitor showing enabled but not initialized. When checking in Health Explorer, there is not green check mark in front of the monitor. But when trying the create the overwrite, the UI showing effect setting for the monitor is enabled for main class already. Any suggestion?

        it would be very helpful if you could kindly provide a sample code, CPU monitoring for instance, which is targeting to the main class, Thanks!

      • #8 by bluej on February 8, 2016 - 8:04 pm

        Thanks Daniel. I don’t where my first reply gone so I type it again here. Sorry if it is duplicate.

        I tried to create a System.NetworkManagement.ThresholdMonitor type monitor and target it to the main class. However after imported in SCOM, when checking in Health explorer, the monitor doesn’t have the green check mark in the front. I then tried to create the override but the UI showing the monitor has been enabled for the class. Using powershell command checking monitor, showing status as uninitialized.

        it would be very helpful if you could kindly provide sample code, CPU monitoring for instance, which create monitor and targeting to the main class.

        Any suggestion?

      • #9 by bluej on February 10, 2016 - 5:14 am

        Hi Daniele,

        Good day. I followed your step and created the processor class, discovery and the monitor. The processor monitor shows as active and initialized as expected.
        Then I change the monitor target from the processor class to the main class, enter the exact OID in the monitor configuration instead of using logicaldevice/key, nothing else was changed. Then the monitor shows as uninitialized.

        Really strange. Is it because the main class was not “discovered” but copied using the snapshot? snapshot doesn’t have probe action and that might be the reason why monitor not initialized?

      • #10 by Daniele Grandini on February 12, 2016 - 8:08 am

        Uhm what do you mean with the main class is not discovered? If you target the monitor ad the device the device itself is discovered by the standard snmp discovery of SCOM.

  3. #11 by MyCo on July 17, 2014 - 11:46 am

    Hi Daniele,
    I wrote something but in certain point something weird happens, There are 2 erros:
    1. Error 38 Invocation of template instance ‘ProcessorUsage.Monitor’ failed. Please configure the operational states for this monitor. C:\Users\administrator.CN\Desktop\MPAuthor Network Sample Management Pack\MPAuthor.NetworkSampleOWN\MPAuthor.NetworkSample\Discovery\ProcessorUsage.mptg .
    I can not set the ‘operational states’ value on ProcessorUsage.mptg property window. there is a alert window with “Reference ‘System.NetworkManagement.ThresholdMonitor’ points to an MP element that does not exist”. So, I open ‘System.NetworkMangement.Monitoring’ with VSAE management pack browser, I can not find ‘System.NetworkManagement.ThresholdMonitor’ under “System.NetworkMangement.Monitoring -> Health Model -> Monitor -> Unit Monitor”. In my opinion, Problems appeared in there.

    2. Error 197 Detected malicious verification code when verifying element of type Microsoft.EnterpriseManagement.Configuration.ManagementPackRule with inner exception: : Could not load management pack [ID=System.Performance.Library, KeyToken=31bf3856ad364e35, Version=7.0.8432.0]. The management pack was not found in the store.
    An object of class ManagementPack with name System.Performance.Library was not found. (Path = MPAuthor.NetworkSample) Language.mpx 5 10 MPAuthor.NetworkSample
    How can I modify my MP file version, my ‘System.NetworkMangement.Monitoring’ version is : 7.0.8560.0

    If you need my code, I will share to you.

    Any assistance will be greatly appreciated.

    • #12 by Daniele Grandini on July 21, 2014 - 3:57 pm

      Hi,
      I don’t get where you get the MpAuthor stuff. Are you sure you’re using my samples? I can confirm System.NetworkManagement.ThresholdMonitor exists in System.NetworkManagement.Monitoring. The second error refers to the Performance system library and states you miss a reference and/or the referenced MP is not in the default store.

  4. #13 by HVA on January 12, 2014 - 10:20 am

    Hi Daniele,

    I am facing a grave problem for authoring in SCOM 2012. I am trying to monitor all the disks in isilon storage bays. The detailed problem listing is done in technet here (http://social.technet.microsoft.com/Forums/systemcenter/en-US/8a30c842-2811-476c-b036-9191606db581/help-needed-to-create-a-probe-monitor-to-traverse-a-list-of-oids-in-an-indexed-table?forum=operationsmanagerauthoring&prof=required). Please help me to complete this puzzle. I am sure that chap 3 and chap 4 resemble close to my requirements but I can’t find what. Your help on this will be greatly useful for me.

    Thanks

  5. #15 by Alexey Zhuravlev on June 22, 2013 - 7:55 am

    $Data/Context/SampleValue$ Should be the $Data/Context/Value$ in the Monitoring processor usage section.

  1. Creating SNMP monitoring Management Packs for System Center 2012 Operations Manager [SNMP MP Chap 1] #scom #sysctr | Quae Nocent Docent

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: