SCOM 2012: UNIX/Linux Monitoring with Scripts
Script Monitoring Scenarios
These examples assume the use of the UNIX/Linux Authoring Library example MP. For more information on creating and building the MP authoring project, see Getting Started.
Monitoring with a Shell Script
Similarly to the Shell Command case, this example demonstrates monitoring with a Shell Script that is run on the UNIX/Linux agent. The output of the shell script (StdOut), is evaluated with numeric thresholds to determine if the monitor is in a Warning or Error State (with a “Less Than” threshold comparison). A Regular Expression is used to validate that the StdOut value is numeric, prior to performing the numeric comparison. The shell script is transferred from the Management Server to the agent on each invocation of the script.
For additional information about the UnitMonitorType used in this example, as well as other shell script monitor types, review the documentation of the following Monitor Types in the Unix.Authoring.Library Module Reference:
- UNIX/Linux Shell Script Matches Expression Two-State Monitor Type
- UNIX/Linux Shell Script Matches Expression Three-State Monitor Type
- UNIX/Linux Shell Script Less Than Threshold Three-State Monitor Type
- UNIX/Linux Shell Script Greater Than Threshold Three-State Monitor Type
Note: contents located between pairs of ## characters should be customized for your environment. This includes ID and property values. Be sure to remove the ## characters before building the MP.
<ManagementPackFragment SchemaVersion="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Monitoring>
<Monitors>
<UnitMonitor ID="##MyMP.ShellScript.LessThan.ThreeState.Monitor##" Accessibility="Internal" Enabled="true" Target="##MyMP.MyCustomRole##" ParentMonitorID="Health!System.Health.AvailabilityState" Remotable="true" Priority="Normal" TypeID="UnixAuth!Unix.Authoring.ShellScript.LessThanThreshold.ThreeState.MonitorType" ConfirmDelivery="false">
<Category>AvailabilityHealth</Category>
<AlertSettings AlertMessage="##MyMP.ShellScript.LessThan.ThreeState.Monitor.AlertMessage##">
<AlertOnState>##Warning##</AlertOnState>
<AutoResolve>true</AutoResolve>
<AlertPriority>Normal</AlertPriority>
<AlertSeverity>##MatchMonitorHealth##</AlertSeverity>
<AlertParameters>
<AlertParameter1>
##$Target/Host/Property[Type="Unix!Microsoft.Unix.Computer"]/NetworkName$##
</AlertParameter1>
<AlertParameter2>##$Data/Context///*[local-name()="StdOut"]$##</AlertParameter2>
</AlertParameters>
</AlertSettings>
<OperationalStates>
<OperationalState ID="StatusOK" MonitorTypeStateID="StatusOK" HealthState="Success" />
<OperationalState ID="StatusWarning" MonitorTypeStateID="StatusWarning" HealthState="Warning" />
<OperationalState ID="StatusError" MonitorTypeStateID="StatusError" HealthState="Error" />
</OperationalStates>
<Configuration>
<Interval>300</Interval>
<TargetSystem>
$Target/Host/Property[Type="Unix!Microsoft.Unix.Computer"]/NetworkName$
</TargetSystem>
<ShellScript>
##<![CDATA[
echo $1
]]> ##
</ShellScript>
<ScriptArguments>75</ScriptArguments>
<Timeout>##60##</Timeout>
<UserName>##$RunAs[Name="Unix!Microsoft.Unix.ActionAccount"]/UserName$##</UserName>
<Password>##$RunAs[Name="Unix!Microsoft.Unix.ActionAccount"]/Password$##</Password>
<FilterExpression>
<RegExExpression>
<ValueExpression>
<XPathQuery>//*[local-name()="StdOut"]</XPathQuery>
</ValueExpression>
<Operator>MatchesRegularExpression</Operator>
<Pattern>^[-+]?\d*[0-9]*(\.[0-9]+)?[Ee]?[-+]?[0-9]*$</Pattern>
</RegExExpression>
</FilterExpression>
<WarningThreshold>##100##</WarningThreshold>
<ErrorThreshold>##50##</ErrorThreshold>
</Configuration>
</UnitMonitor>
</Monitors>
</Monitoring>
<Presentation>
<StringResources>
<StringResource ID="##MyMP.ShellScript.LessThan.ThreeState.Monitor.AlertMessage##" />
</StringResources>
</Presentation>
<LanguagePacks>
<LanguagePack ID="ENU" IsDefault="true">
<DisplayStrings>
<DisplayString ElementID="##MyMP.ShellScript.LessThan.ThreeState.Monitor##">
<Name>##My shell script monitor##</Name>
<Description>##Monitors the output of a shell command and generates an alert if the output is less than the threshold. ##</Description>
</DisplayString>
<DisplayString ElementID="##MyMP.ShellScript.LessThan.ThreeState.Monitor.AlertMessage##">
<Name>##Shell script output is too low##</Name>
<Description>##The output of the shell script on the host: {0} is lower than the threshold. The output is: {1}##</Description>
</DisplayString>
<DisplayString ElementID="##MyMP.ShellScript.LessThan.ThreeState.Monitor##" SubElementID="StatusOK">
<Name>StatusOK</Name>
<Description>StatusOK</Description>
</DisplayString>
<DisplayString ElementID="##MyMP.ShellScript.LessThan.ThreeState.Monitor##" SubElementID="StatusWarning">
<Name>StatusWarning</Name>
<Description>StatusWarning</Description>
</DisplayString>
<DisplayString ElementID="##MyMP.ShellScript.LessThan.ThreeState.Monitor##" SubElementID="StatusError">
<Name>StatusError</Name>
<Description>StatusError</Description>
</DisplayString>
</DisplayStrings>
</LanguagePack>
</LanguagePacks>
</ManagementPackFragment>
Handling complex shell command/script output with PowerShell scripts
When running a shell command or shell script, the Operations Manager UNIX/Linux agent returns StdOut, StdErr, and ReturnCode values as a single DataItem. If a shell command or script returns multiple values in its output (StdOut), and these values need to be handled as distinct DataItems, a PowerShell script can be used (in the form of a PropertyBag probe) to parse the shell command/script output, perform splitting or filtering operations, and create Property Bags. The Property Bags can then be uniquely evaluated for separate monitors or rules.
This example demonstrates the use of a Shell Script which returns multiple values in StdOut, and the use of a PowerShell Property Bag probe to parse the values and create Property Bags. The Property Bag DataItems are evaluated with numeric thresholds to determine the monitor state.
For additional information about the UnitMonitorType used in this example, as well as other shell command and shell script monitor types that use PowerShell parsing for multiple values, review the documentation of the following Monitor Types in the Unix.Authoring.Library Module Reference:
- UNIX/Linux Shell Command Property Bag Matches Expression Two-State Monitor Type
- UNIX/Linux Shell Command Property Bag Matches Expression Three-State Monitor Type
- UNIX/Linux Shell Command Property Bag Less Than Threshold Three-State Monitor Type
- UNIX/Linux Shell Command Property Greater Than Threshold Three-State Monitor Type
- UNIX/Linux Shell Script Property Bag Matches Expression Two-State Monitor Type
- UNIX/Linux Shell Script Property Bag Matches Expression Three-State Monitor Type
- UNIX/Linux Shell Script Property Bag Less Than Threshold Three-State Monitor Type
- UNIX/Linux Shell Script Property Bag Greater Than Threshold Three-State Monitor Type
For more information about quotes and special characters in shell commands, see the appendix section - Commands and Scripts: Quotes and Special Characters
Note: contents located between pairs of ## characters should be customized for your environment. This includes ID and property values. Be sure to remove the ## characters before building the MP.
<ManagementPackFragment SchemaVersion="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Monitoring>
<Monitors>
<UnitMonitor ID="##MyMP.ShellScript.PropertyBag.GreaterThan.ThreeState.Monitor##" Accessibility="Internal" Enabled="true" Target="##MyMP.MyCustomRole##" ParentMonitorID="Health!System.Health.AvailabilityState" Remotable="true" Priority="Normal" TypeID="UnixAuth!Unix.Authoring.ShellScript.PropertyBag.GreaterThanThreshold.ThreeState.MonitorType" ConfirmDelivery="false">
<Category>AvailabilityHealth</Category>
<AlertSettings AlertMessage="##MyMP.ShellScript.PropertyBag.GreaterThan.ThreeState.Monitor.AlertMessage##">
<AlertOnState>##Warning##</AlertOnState>
<AutoResolve>true</AutoResolve>
<AlertPriority>Normal</AlertPriority>
<AlertSeverity>##MatchMonitorHealth##</AlertSeverity>
<AlertParameters>
<AlertParameter1>
##$Target/Host/Property[Type="Unix!Microsoft.Unix.Computer"]/NetworkName$##
</AlertParameter1>
<AlertParameter2>##$Data/Context/DataItem/Property[@Name='CounterValue']$ ##</AlertParameter2>
</AlertParameters>
</AlertSettings>
<OperationalStates>
<OperationalState ID="StatusOK" MonitorTypeStateID="StatusOK" HealthState="Success" />
<OperationalState ID="StatusWarning" MonitorTypeStateID="StatusWarning" HealthState="Warning" />
<OperationalState ID="StatusError" MonitorTypeStateID="StatusError" HealthState="Error" />
</OperationalStates>
<Configuration>
<Interval>300</Interval>
<TargetSystem>
$Target/Host/Property[Type="Unix!Microsoft.Unix.Computer"]/NetworkName$
</TargetSystem>
<ShellScript>
##<![CDATA[
echo "MyCounterA:$1,MyCounterB:$2"
]]> ##
</ShellScript>
<ScriptArguments>##88 77##</ScriptArguments>
<Timeout>60</Timeout>
<UserName>##$RunAs[Name="Unix!Microsoft.Unix.ActionAccount"]/UserName$##</UserName>
<Password>##$RunAs[Name="Unix!Microsoft.Unix.ActionAccount"]/Password$##</Password>
<PSScriptName>##MyPSScript.ps1##</PSScriptName>
<PSScriptBody>
##<![CDATA[
param([string]$StdOut,[string]$StdErr,[string]$ReturnCode)
$api = New-Object -comObject 'MOM.ScriptAPI'
[array]$arCounters=$StdOut.Split(",")
ForEach($counter in $ArCounters){
$sName=$counter.Split(":")[0]
$sValue=$counter.split(":")[1].trim()
if ($sValue -ne $null){
$bag = $api.CreatePropertyBag()
$bag.AddValue("CounterName",$sName)
$bag.AddValue("CounterValue",$sValue)
$bag
}
}
]]> ##
</PSScriptBody>
<FilterExpression>
<RegExExpression>
<ValueExpression>
<XPathQuery>##Property[@Name='CounterName'] ##</XPathQuery>
</ValueExpression>
<Operator>##MatchesRegularExpression##</Operator>
<Pattern>##MyCounterA##</Pattern>
</RegExExpression>
</FilterExpression>
<ValueXPath>##Property[@Name='CounterValue'] ##</ValueXPath>
<WarningThreshold>##50##</WarningThreshold>
<ErrorThreshold>##100##</ErrorThreshold>
</Configuration>
</UnitMonitor>
</Monitors>
</Monitoring>
<Presentation>
<StringResources>
<StringResource ID="##MyMP.ShellScript.PropertyBag.GreaterThan.ThreeState.Monitor.AlertMessage##" />
</StringResources>
</Presentation>
<LanguagePacks>
<LanguagePack ID="ENU" IsDefault="true">
<DisplayStrings>
<DisplayString ElementID="##MyMP.ShellScript.PropertyBag.GreaterThan.ThreeState.Monitor##">
<Name>##My shell script monitor - MyCounterA##</Name>
<Description>##Monitors the output of a shell command and generates an alert if MyCounterA is greater than the threshold.##</Description>
</DisplayString>
<DisplayString ElementID="##MyMP.ShellScript.PropertyBag.GreaterThan.ThreeState.Monitor.AlertMessage##">
<Name>##MyCounterA value is too high##</Name>
<Description>##The value of MyCounterA on the host: {0} is higher than the threshold. The value is: {1}##</Description>
</DisplayString>
<DisplayString ElementID="##MyMP.ShellScript.PropertyBag.GreaterThan.ThreeState.Monitor##" SubElementID="StatusOK">
<Name>StatusOK</Name>
<Description>StatusOK</Description>
</DisplayString>
<DisplayString ElementID="##MyMP.ShellScript.PropertyBag.GreaterThan.ThreeState.Monitor##" SubElementID="StatusWarning">
<Name>StatusWarning</Name>
<Description>StatusWarning</Description>
</DisplayString>
<DisplayString ElementID="##MyMP.ShellScript.PropertyBag.GreaterThan.ThreeState.Monitor##" SubElementID="StatusError">
<Name>StatusError</Name>
<Description>StatusError</Description>
</DisplayString>
</DisplayStrings>
</LanguagePack>
</LanguagePacks>
</ManagementPackFragment>