Lors de la création d’un moniteur de performance, il peut arriver qu’il soit nécessaire de superviser plusieurs instances du compteur et d’alerter lorsque n’importe laquelle de ces instances dépasse le seuil paramétré.
La solution qui vient alors immédiatement à l’esprit est alors d’utiliser les wildcard (jokers) dans le nom de l’instance :
Malheureusement, voici ce qui se produit dans ce cas :
Le moniteur détecte bien que l’instance w3wp dépasse le seuil paramétré et passe donc en Critical, mais instantanément après le moniteur détecte que l’instance w3wp#10 est elle toujours sous le seuil et il repasse donc en Healthy : la vérification se fait pour chaque instance du compteur l’une après l’autre, et si un seul d’entre eux n’est pas en critical, le moniteur repasse en vert immédiatement.
Et ce manège recommence à chaque exécution du moniteur…
Une première bonne solution consiste alors à utiliser une variable à la place d’un wildcard en tant qu’Instance.
Prenons l’exemple d’un moniteur de performance qui serait ciblé sur la classe Logical Disk.
Cette classe dispose de propriétés, dont plusieurs correspondent au nom des instances de compteurs :
On peut alors réutiliser une de ces variable dans le champ Instance de l’assistant de création du moniteur, à l’aide de la petite flèche située à sa droite :
On aura donc un moniteur pour chaque instance SCOM de la classe logical disk, ciblé uniquement sur l’instance du compteur de performance qui lui correspond.
Il arrive cependant qu’aucune classe SCOM ne dispose de propriétés utilisables en tant que variable, typiquement en reprenant le premier exemple du process w3wp.exe.
Dans ce cas, une autre solution existe : le module de détection de condition (condition detection module) System.LogicalSet.ExpressionFilter introduit dans SCOM 2007 R2 permet de déterminer quand arrêter le traitement des données provenant d’une datasource lorsque celle-ci renvoie plusieurs résultats (ce qui est le cas quand un System.Performance.DataProvider est ciblé sur plusieurs instances d’un compteur perfmon).
Autrement dit, en utilisant ce module, les valeurs de chaque instance du compteur sont analysées l’une après l’autre. Dès qu’une de ces instances dépasse le seuil défini, le moniteur passe en Critical et s’arrête sans analyser les instances suivantes, empêchant donc le moniteur de repasser en Healthy.
L’utilisation de ce module n’est toutefois pas possible directement depuis la console SCOM et nécessite de créer son propre MonitorType :
<TypeDefinitions> <MonitorTypes> <UnitMonitorType ID="MultipleInstance.Perf.MonitorType" Accessibility="Public"> <MonitorTypeStates> <MonitorTypeState ID="AboveThreshold" NoDetection="false" /> <MonitorTypeState ID="BelowThreshold" NoDetection="false" /> </MonitorTypeStates> <Configuration> <xsd:element name="ComputerName" type="xsd:string" /> <xsd:element name="CounterName" type="xsd:string" /> <xsd:element name="ObjectName" type="xsd:string" /> <xsd:element name="InstanceName" type="xsd:string" /> <xsd:element name="AllInstances" type="xsd:boolean" /> <xsd:element name="Frequency" type="xsd:unsignedInt" /> <xsd:element name="Threshold" type="xsd:double" /> </Configuration> <OverrideableParameters> <OverrideableParameter ID="Frequency" Selector="$Config/Frequency$" ParameterType="int" /> <OverrideableParameter ID="Threshold" Selector="$Config/Threshold$" ParameterType="double" /> </OverrideableParameters> <MonitorImplementation> <MemberModules> <DataSource ID="DS_PerfData" TypeID="Performance!System.Performance.DataProvider"> <ComputerName>$Config/ComputerName$</ComputerName> <CounterName>$Config/CounterName$</CounterName> <ObjectName>$Config/ObjectName$</ObjectName> <InstanceName>$Config/InstanceName$</InstanceName> <AllInstances>$Config/AllInstances$</AllInstances> <Frequency>$Config/Frequency$</Frequency> </DataSource> <ConditionDetection ID="BelowThresholdDetection" TypeID="SystemLibrary7585010!System.LogicalSet.ExpressionFilter"> <Expression> <SimpleExpression> <ValueExpression> <XPathQuery Type="Double">Value</XPathQuery> </ValueExpression> <Operator>LessEqual</Operator> <ValueExpression> <Value Type="Double">$Config/Threshold$</Value> </ValueExpression> </SimpleExpression> </Expression> <EmptySet>Passthrough</EmptySet> <SetEvaluation>All</SetEvaluation> </ConditionDetection> <ConditionDetection ID="AboveThresholdDetection" TypeID="SystemLibrary7585010!System.LogicalSet.ExpressionFilter"> <Expression> <SimpleExpression> <ValueExpression> <XPathQuery Type="Double">Value</XPathQuery> </ValueExpression> <Operator>Greater</Operator> <ValueExpression> <Value Type="Double">$Config/Threshold$</Value> </ValueExpression> </SimpleExpression> </Expression> <EmptySet>Block</EmptySet> <SetEvaluation>Any</SetEvaluation> </ConditionDetection> </MemberModules> <RegularDetections> <RegularDetection MonitorTypeStateID="BelowThreshold"> <Node ID="BelowThresholdDetection"> <Node ID="DS_PerfData" /> </Node> </RegularDetection> <RegularDetection MonitorTypeStateID="AboveThreshold"> <Node ID="AboveThresholdDetection"> <Node ID="DS_PerfData" /> </Node> </RegularDetection> </RegularDetections> </MonitorImplementation> </UnitMonitorType> </MonitorTypes> </TypeDefinitions> |
On constate que ce module se configure très simplement à l’aide de deux balises xml : EmptySet et SetEvaluation.
EmptySet indique le traitement à appliquer : Passthrough (on continue le traitement des données vers les modules suivants dans le workflow, c’est le mode par défaut) ou Block (qui arrête le traitement du wokflow).
SetEvaluation indique si les données de chaque instance doivent correspondre (All), ou si une seule suffit (Any).
Dans l’exemple ci-dessus, on demande donc d’arrêter le traitement (Block) dès que n’importe quelle instance du compteur (Any) passe au dessus du seuil défini.
Ne reste alors plus qu’à implémenter le Moniteur à proprement parler :
<UnitMonitor ID="w3wp.process.privatebytes.monitor" Accessibility="Public" Enabled="false" Target="SharePoint2!Microsoft.SharePoint.2013.SPServiceInstance.Excel" ParentMonitorID="Health!System.Health.AvailabilityState" Remotable="true" Priority="Normal" TypeID="MultipleInstance.Perf.MonitorType" ConfirmDelivery="true"> <Category>PerformanceHealth</Category> <AlertSettings AlertMessage="w3wp.process.privatebytes.monitor_AlertMessageResourceID"> <AlertOnState>Error</AlertOnState> <AutoResolve>true</AutoResolve> <AlertPriority>Normal</AlertPriority> <AlertSeverity>Error</AlertSeverity> </AlertSettings> <OperationalStates> <OperationalState ID="AboveThreshold" MonitorTypeStateID="AboveThreshold" HealthState="Error" /> <OperationalState ID="BelowThreshold" MonitorTypeStateID="BelowThreshold" HealthState="Success" /> </OperationalStates> <Configuration> <ComputerName>$Target/Host/Property[Type="MicrosoftWindowsLibrary7585010!Microsoft.Windows.Computer"]/NetworkName$</ComputerName> <CounterName>Private Bytes</CounterName> <ObjectName>Process</ObjectName> <InstanceName>w3wp*</InstanceName> <AllInstances>false</AllInstances> <Frequency>300</Frequency> <Threshold>2000000000</Threshold> </Configuration> </UnitMonitor> |
Et cette fois-ci le moniteur ne bagotte plus, tant que n’importe laquelle des instances du compteur sera au dessus du seuil, le moniteur restera en Critical :
Pour aller plus loin : https://msdn.microsoft.com/en-us/library/hh442318.aspx?f=255&MSPPError=-2147217396