URL Monitoring Part V–Monitoring URLs from a Resource Pool

This post is a continuation of the following series:

URL Monitoring Part I – The Design
URL Monitoring Part II – The Classes and Discoveries
URL Monitoring Part III – The Monitors
URL Monitoring Part IV – Getting More Advanced
URL Monitoring Part V – Monitoring URLs from a Resource Pool

I made several modifications to the management pack and CSV file from the Part IV post. The first modification is that I consolidated the data sources from 3 down to 1. The previous solutions didn’t cook down so if you were using the performance, content, and availability monitoring for a website then it would hit that site 3 times, one for each request type. This solution changes that by consolidating the data sources so only one request is made. On the downside, if you never use content or performance monitoring then the requests cost a bit more in terms of performance. Ultimately my hope is that this solution be used as a framework that folks can customize to meet their specific needs as the data sources in the management pack can be tweaked for optimum performance depending on the scenario.

The second modification is that instead of using an agent watcher I’m using a custom resource pool. Resource Pools are only available in Operations Manager 2012 and provide redundancy.

Steps to Test Solution

  • Create a file share and copy URLMonitoringList.csv into it
  • Modify the Custom.Example.ResourcePoolWebsiteWatcher.xml
    • Change “<UNCPathToCSVFile>\\scom2012r2.contoso.com\URL\URLMonitoringList.CSV</UNCPathToCSVFile>” to your CSV file
 <?xml version="1.0" encoding="utf-8"?>
<ManagementPack SchemaVersion="2.0" ContentReadable="true" xmlns:xsd="https://www.w3.org/2001/XMLSchema">
  <Manifest>
    <Identity>
      <ID>Custom.Example.ResourcePoolWebsiteWatcher</ID>
      <Version>1.0.0.0</Version>
    </Identity>
    <Name>Resource Pool Website Watcher</Name>
    <References>
      <Reference Alias="SC">
        <ID>Microsoft.SystemCenter.Library</ID>
        <Version>7.0.8433.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Web">
        <ID>Microsoft.SystemCenter.WebApplication.Library</ID>
        <Version>7.1.10226.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Windows">
        <ID>Microsoft.Windows.Library</ID>
        <Version>7.5.8501.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Health">
        <ID>System.Health.Library</ID>
        <Version>7.0.8433.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="System">
        <ID>System.Library</ID>
        <Version>7.5.8501.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
    </References>
  </Manifest>
  <TypeDefinitions>
    <EntityTypes>
      <ClassTypes>
        <ClassType ID="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website" Accessibility="Public" Abstract="false" Base="System!System.ApplicationComponent" Hosted="false" Singleton="false">
          <Property ID="URL" Type="string" Key="true" CaseSensitive="false" MaxLength="512" MinLength="0" />
          <Property ID="WatchedBy" Type="string" Key="false" CaseSensitive="false" MaxLength="255" MinLength="0" />
          <Property ID="ContentMatchString" Type="string" Key="false" CaseSensitive="false" MaxLength="255" MinLength="0" />
          <Property ID="MaxResponseTime" Type="double" Key="false" CaseSensitive="false" MaxLength="38" MinLength="0" />
          <Property ID="MonitoringIntervalInSeconds" Type="int" Key="false" CaseSensitive="false" MaxLength="256" MinLength="0" />
          <Property ID="TimeWindowInSeconds" Type="int" Key="false" CaseSensitive="false" MaxLength="256" MinLength="0" />
          <Property ID="AttemptsBeforeTurningRed" Type="int" Key="false" CaseSensitive="false" MaxLength="256" MinLength="0" />
          <Property ID="MonitorAvailability" Type="bool" Key="false" CaseSensitive="false" MaxLength="256" MinLength="0" />
          <Property ID="MonitorPerformance" Type="bool" Key="false" CaseSensitive="false" MaxLength="256" MinLength="0" />
          <Property ID="MonitorContent" Type="bool" Key="false" CaseSensitive="false" MaxLength="256" MinLength="0" />
        </ClassType>
        <ClassType ID="Custom.Example.ResourcePoolWebsiteWatcher.Class.WebsiteWatcherPool" Accessibility="Public" Abstract="false" Base="SC!Microsoft.SystemCenter.ManagementServicePool" Hosted="false" Singleton="true" />
      </ClassTypes>
    </EntityTypes>
    <ModuleTypes>
      <DataSourceModuleType ID="Custom.Example.ResourcePoolWebsiteWatcher.DataSource.DiscoverWebsites" Accessibility="Public" Batching="false">
        <Configuration>
          <xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="UNCPathToCSVFile" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
        </Configuration>
        <ModuleImplementation Isolation="Any">
          <Composite>
            <MemberModules>
              <DataSource ID="DS" TypeID="System!System.Scheduler">
                <Scheduler>
                  <SimpleReccuringSchedule>
                    <Interval>$Config/IntervalSeconds$</Interval>
                  </SimpleReccuringSchedule>
                  <ExcludeDates />
                </Scheduler>
              </DataSource>
              <ProbeAction ID="Probe" TypeID="Windows!Microsoft.Windows.ScriptDiscoveryProbe">
                <ScriptName>DiscoverWebsites.vbs</ScriptName>
                <Arguments>$Config/UNCPathToCSVFile$</Arguments>
                <ScriptBody><![CDATA['Arg1 = UNC Path to CSV file
'CSV Format:
'URL,ResourcePoolName,ContentMatchString,MaxResponseTime,MonitoringIntervalInSeconds,AttemptsBeforeTurningRed,TimeWindowInSeconds,MonitorAvailability,MonitorPerformance,MonitorContent

Set oArgs = Wscript.Arguments
sCSV = UCase(oArgs(0))

WScript.Echo "Creating Discovery Data"
Set oAPI = CreateObject("MOM.ScriptAPI")
Set oDiscoveryData = oAPI.CreateDiscoveryData(0,"$MPElement$", "$Target/Id$")

WScript.Echo "Opening CSV"
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oCSV = oFSO.OpenTextFile(sCSV)

WScript.Echo "Reading CSV"
Do While Not oCSV.AtEndOfStream
  aRow = split(oCSV.ReadLine, ",")
  Set oWebsite = oDiscoveryData.CreateClassInstance("$MPElement[Name='Custom.Example.ResourcePoolWebsiteWatcher.Class.Website']$")
  oWebsite.AddProperty "$MPElement[Name='System!System.Entity']/DisplayName$", aRow(0)
  oWebsite.AddProperty "$MPElement[Name='Custom.Example.ResourcePoolWebsiteWatcher.Class.Website']/URL$", aRow(0)
  oWebsite.AddProperty "$MPElement[Name='Custom.Example.ResourcePoolWebsiteWatcher.Class.Website']/WatchedBy$", aRow(1)
  oWebsite.AddProperty "$MPElement[Name='Custom.Example.ResourcePoolWebsiteWatcher.Class.Website']/ContentMatchString$", aRow(2)
  oWebsite.AddProperty "$MPElement[Name='Custom.Example.ResourcePoolWebsiteWatcher.Class.Website']/MaxResponseTime$", aRow(3)
  oWebsite.AddProperty "$MPElement[Name='Custom.Example.ResourcePoolWebsiteWatcher.Class.Website']/MonitoringIntervalInSeconds$", aRow(4)
  oWebsite.AddProperty "$MPElement[Name='Custom.Example.ResourcePoolWebsiteWatcher.Class.Website']/AttemptsBeforeTurningRed$", aRow(5)
  oWebsite.AddProperty "$MPElement[Name='Custom.Example.ResourcePoolWebsiteWatcher.Class.Website']/TimeWindowInSeconds$", aRow(6)
  oWebsite.AddProperty "$MPElement[Name='Custom.Example.ResourcePoolWebsiteWatcher.Class.Website']/MonitorAvailability$", aRow(7)
  oWebsite.AddProperty "$MPElement[Name='Custom.Example.ResourcePoolWebsiteWatcher.Class.Website']/MonitorPerformance$", aRow(8)
  oWebsite.AddProperty "$MPElement[Name='Custom.Example.ResourcePoolWebsiteWatcher.Class.Website']/MonitorContent$", aRow(9)  
  oDiscoveryData.AddInstance(oWebsite)
Loop
Call oAPI.Return(oDiscoveryData)]]></ScriptBody>
                <TimeoutSeconds>300</TimeoutSeconds>
              </ProbeAction>
            </MemberModules>
            <Composition>
              <Node ID="Probe">
                <Node ID="DS" />
              </Node>
            </Composition>
          </Composite>
        </ModuleImplementation>
        <OutputType>System!System.Discovery.Data</OutputType>
      </DataSourceModuleType>
      <DataSourceModuleType ID="Custom.Example.ResourcePoolWebsiteWatcher.DataSource.WebsiteContent" Accessibility="Public" Batching="false">
        <Configuration>
          <xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="URL" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="MaximumResponseTime" type="xsd:double" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="ContentMatchString" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
        </Configuration>
        <ModuleImplementation Isolation="Any">
          <Composite>
            <MemberModules>
              <DataSource ID="DS" TypeID="Web!Microsoft.SystemCenter.WebApplication.PerProbe.Scheduler">
                <Scheduler>
                  <SimpleReccuringSchedule>
                    <Interval>$Config/IntervalSeconds$</Interval>
                    <SpreadInitializationOverInterval>$Config/IntervalSeconds$</SpreadInitializationOverInterval>
                  </SimpleReccuringSchedule>
                  <ExcludeDates />
                </Scheduler>
                <UniquenessKey>$Target/Id$</UniquenessKey>
              </DataSource>
              <ProbeAction ID="Probe" TypeID="Web!Microsoft.SystemCenter.WebApplication.UrlProbe">
                <Proxy />
                <ProxyUserName />
                <ProxyPassword />
                <ProxyAuthenticationScheme>None</ProxyAuthenticationScheme>
                <CredentialUserName />
                <CredentialPassword />
                <AuthenticationScheme>None</AuthenticationScheme>
                <FollowRedirects>true</FollowRedirects>
                <RetryCount>1</RetryCount>
                <RequestTimeout>180</RequestTimeout>
                <Requests>
                  <Request>
                    <RequestID>1</RequestID>
                    <URL>$Config/URL$</URL>
                    <Verb>GET</Verb>
                    <Version>HTTP/1.1</Version>
                    <HttpHeaders>
                      <HttpHeader>
                        <Name>User-Agent</Name>
                        <Value>Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)</Value>
                      </HttpHeader>
                    </HttpHeaders>
                    <Body />
                    <CheckContentChange>false</CheckContentChange>
                    <ContentHash>00000000-0000-0000-0000-000000000000</ContentHash>
                    <Depth>0</Depth>
                    <ThinkTime>0</ThinkTime>
                    <CheckInternalLinks>false</CheckInternalLinks>
                    <CheckExternalLinks>false</CheckExternalLinks>
                    <CheckResources>false</CheckResources>
                    <RequestEvaluationCriteria>
                      <StopProcessingIfWarningCriteriaIsMet>false</StopProcessingIfWarningCriteriaIsMet>
                      <StopProcessingIfErrorCriteriaIsMet>false</StopProcessingIfErrorCriteriaIsMet>
                      <BasePageEvaluationCriteria>
                        <WarningCriteria />
                        <ErrorCriteria>
                          <NumericCriteriaExpressions>
                            <NumericCriteriaExpression>
                              <NumericRequestMetric>BasePageData/StatusCode</NumericRequestMetric>
                              <Operator>GreaterEqual</Operator>
                              <Value>400</Value>
                            </NumericCriteriaExpression>
                            <NumericCriteriaExpression>
                              <NumericRequestMetric>BasePageData/TotalResponseTime</NumericRequestMetric>
                              <Operator>Greater</Operator>
                              <Value>$Config/MaximumResponseTime$</Value>
                            </NumericCriteriaExpression>
                          </NumericCriteriaExpressions>
                          <ContentMatchCriteria>
                            <RegExOperator>DoesNotContainSubstring</RegExOperator>
                            <Value>$Config/ContentMatchString$</Value>
                          </ContentMatchCriteria>
                        </ErrorCriteria>
                      </BasePageEvaluationCriteria>
                      <LinksEvaluationCriteria>
                        <WarningCriteria>
                          <StatusCodeCriteria>
                            <ListNumericRequestMetric>StatusCode</ListNumericRequestMetric>
                            <Operator>GreaterEqual</Operator>
                            <Value>400</Value>
                          </StatusCodeCriteria>
                        </WarningCriteria>
                        <ErrorCriteria />
                      </LinksEvaluationCriteria>
                      <ResourcesEvaluationCriteria>
                        <WarningCriteria>
                          <StatusCodeCriteria>
                            <ListNumericRequestMetric>StatusCode</ListNumericRequestMetric>
                            <Operator>GreaterEqual</Operator>
                            <Value>400</Value>
                          </StatusCodeCriteria>
                        </WarningCriteria>
                        <ErrorCriteria />
                      </ResourcesEvaluationCriteria>
                      <WebPageTotalEvaluationCriteria>
                        <WarningCriteria />
                        <ErrorCriteria />
                      </WebPageTotalEvaluationCriteria>
                      <DepthEvaluationCriteria>
                        <WarningCriteria />
                        <ErrorCriteria />
                      </DepthEvaluationCriteria>
                    </RequestEvaluationCriteria>
                    <FormsAuthCredentials />
                    <CollectResponseBody>OnContentMatchCriteria</CollectResponseBody>
                    <CollectLinksHeaders>false</CollectLinksHeaders>
                    <CollectResourcesHeaders>false</CollectResourcesHeaders>
                  </Request>
                </Requests>
              </ProbeAction>
            </MemberModules>
            <Composition>
              <Node ID="Probe">
                <Node ID="DS" />
              </Node>
            </Composition>
          </Composite>
        </ModuleImplementation>
        <OutputType>Web!Microsoft.SystemCenter.WebApplication.WebApplicationData</OutputType>
      </DataSourceModuleType>
    </ModuleTypes>
    <MonitorTypes>
      <UnitMonitorType ID="Custom.Example.ResourcePoolWebsiteWatcher.MonitorType.WebsiteAvailability" Accessibility="Public">
        <MonitorTypeStates>
          <MonitorTypeState ID="WebsiteUp" NoDetection="false" />
          <MonitorTypeState ID="WebsiteDown" NoDetection="false" />
        </MonitorTypeStates>
        <Configuration>
          <xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="ContentMatchString" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="URL" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="MaximumResponseTime" type="xsd:double" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="AttemptsBeforeTurningRed" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="TimeWindowInSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
        </Configuration>
        <MonitorImplementation>
          <MemberModules>
            <DataSource ID="DS" TypeID="Custom.Example.ResourcePoolWebsiteWatcher.DataSource.WebsiteContent">
              <IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
              <URL>$Config/URL$</URL>
              <MaximumResponseTime>$Config/MaximumResponseTime$</MaximumResponseTime>
              <ContentMatchString>$Config/ContentMatchString$</ContentMatchString>
            </DataSource>
            <ConditionDetection ID="CDUp" TypeID="System!System.ExpressionFilter">
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery Type="UnsignedInteger">RequestResults/RequestResult[@Id="1"]/BasePageData/ErrorCode</XPathQuery>
                  </ValueExpression>
                  <Operator>Equal</Operator>
                  <ValueExpression>
                    <Value Type="UnsignedInteger">0</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
            </ConditionDetection>
            <ConditionDetection ID="CDDown" TypeID="System!System.ExpressionFilter">
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery Type="UnsignedInteger">RequestResults/RequestResult[@Id="1"]/BasePageData/ErrorCode</XPathQuery>
                  </ValueExpression>
                  <Operator>NotEqual</Operator>
                  <ValueExpression>
                    <Value Type="UnsignedInteger">0</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
            </ConditionDetection>
            <ConditionDetection ID="CDConsolidate" TypeID="System!System.ConsolidatorCondition">
              <Consolidator>
                <ConsolidationProperties />
                <TimeControl>
                  <WithinTimeSchedule>
                    <Interval>$Config/TimeWindowInSeconds$</Interval>
                  </WithinTimeSchedule>
                </TimeControl>
                <CountingCondition>
                  <Count>$Config/AttemptsBeforeTurningRed$</Count>
                  <CountMode>OnNewItemTestOutputRestart_OnTimerSlideByOne</CountMode>
                </CountingCondition>
              </Consolidator>
            </ConditionDetection>
          </MemberModules>
          <RegularDetections>
            <RegularDetection MonitorTypeStateID="WebsiteUp">
              <Node ID="CDUp">
                <Node ID="DS" />
              </Node>
            </RegularDetection>
            <RegularDetection MonitorTypeStateID="WebsiteDown">
              <Node ID="CDConsolidate">
                <Node ID="CDDown">
                  <Node ID="DS" />
                </Node>
              </Node>
            </RegularDetection>
          </RegularDetections>
        </MonitorImplementation>
      </UnitMonitorType>
      <UnitMonitorType ID="Custom.Example.ResourcePoolWebsiteWatcher.MonitorType.WebsiteContent" Accessibility="Public">
        <MonitorTypeStates>
          <MonitorTypeState ID="ContentFound" NoDetection="false" />
          <MonitorTypeState ID="ContentNotFound" NoDetection="false" />
        </MonitorTypeStates>
        <Configuration>
          <xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="ContentMatchString" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="URL" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="MaximumResponseTime" type="xsd:double" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="AttemptsBeforeTurningRed" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="TimeWindowInSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
        </Configuration>
        <MonitorImplementation>
          <MemberModules>
            <DataSource ID="DS" TypeID="Custom.Example.ResourcePoolWebsiteWatcher.DataSource.WebsiteContent">
              <IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
              <URL>$Config/URL$</URL>
              <MaximumResponseTime>$Config/MaximumResponseTime$</MaximumResponseTime>
              <ContentMatchString>$Config/ContentMatchString$</ContentMatchString>
            </DataSource>
            <ConditionDetection ID="CDFound" TypeID="Web!Microsoft.SystemCenter.WebApplication.OKCriteriaMatch">
              <DataItemEvaluationQuery>RequestResults/RequestResult[@Id="1"]/BasePageData/ResponseBodyEvalResult</DataItemEvaluationQuery>
            </ConditionDetection>
            <ConditionDetection ID="CDNotFound" TypeID="Web!Microsoft.SystemCenter.WebApplication.ErrorCriteriaMatch">
              <DataItemEvaluationQuery>RequestResults/RequestResult[@Id="1"]/BasePageData/ResponseBodyEvalResult</DataItemEvaluationQuery>
            </ConditionDetection>
          </MemberModules>
          <RegularDetections>
            <RegularDetection MonitorTypeStateID="ContentFound">
              <Node ID="CDFound">
                <Node ID="DS" />
              </Node>
            </RegularDetection>
            <RegularDetection MonitorTypeStateID="ContentNotFound">
              <Node ID="CDNotFound">
                <Node ID="DS" />
              </Node>
            </RegularDetection>
          </RegularDetections>
        </MonitorImplementation>
      </UnitMonitorType>
      <UnitMonitorType ID="Custom.Example.ResourcePoolWebsiteWatcher.MonitorType.WebsitePerformance" Accessibility="Public">
        <MonitorTypeStates>
          <MonitorTypeState ID="WebsiteFast" NoDetection="false" />
          <MonitorTypeState ID="WebsiteSlow" NoDetection="false" />
        </MonitorTypeStates>
        <Configuration>
          <xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="ContentMatchString" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="URL" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="MaximumResponseTime" type="xsd:double" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="AttemptsBeforeTurningRed" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
          <xsd:element minOccurs="1" name="TimeWindowInSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
        </Configuration>
        <MonitorImplementation>
          <MemberModules>
            <DataSource ID="DS" TypeID="Custom.Example.ResourcePoolWebsiteWatcher.DataSource.WebsiteContent">
              <IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
              <URL>$Config/URL$</URL>
              <MaximumResponseTime>$Config/MaximumResponseTime$</MaximumResponseTime>
              <ContentMatchString>$Config/ContentMatchString$</ContentMatchString>
            </DataSource>
            <ConditionDetection ID="CDFast" TypeID="Web!Microsoft.SystemCenter.WebApplication.OKCriteriaMatch">
              <DataItemEvaluationQuery>RequestResults/RequestResult[@Id="1"]/BasePageData/TotalResponseTimeEvalResult</DataItemEvaluationQuery>
            </ConditionDetection>
            <ConditionDetection ID="CDSlow" TypeID="Web!Microsoft.SystemCenter.WebApplication.ErrorCriteriaMatch">
              <DataItemEvaluationQuery>RequestResults/RequestResult[@Id="1"]/BasePageData/TotalResponseTimeEvalResult</DataItemEvaluationQuery>
            </ConditionDetection>
            <ConditionDetection ID="CDConsolidate" TypeID="System!System.ConsolidatorCondition">
              <Consolidator>
                <ConsolidationProperties />
                <TimeControl>
                  <WithinTimeSchedule>
                    <Interval>$Config/TimeWindowInSeconds$</Interval>
                  </WithinTimeSchedule>
                </TimeControl>
                <CountingCondition>
                  <Count>$Config/AttemptsBeforeTurningRed$</Count>
                  <CountMode>OnNewItemTestOutputRestart_OnTimerSlideByOne</CountMode>
                </CountingCondition>
              </Consolidator>
            </ConditionDetection>
          </MemberModules>
          <RegularDetections>
            <RegularDetection MonitorTypeStateID="WebsiteFast">
              <Node ID="CDFast">
                <Node ID="DS" />
              </Node>
            </RegularDetection>
            <RegularDetection MonitorTypeStateID="WebsiteSlow">
              <Node ID="CDConsolidate">
                <Node ID="CDSlow">
                  <Node ID="DS" />
                </Node>
              </Node>
            </RegularDetection>
          </RegularDetections>
        </MonitorImplementation>
      </UnitMonitorType>
    </MonitorTypes>
  </TypeDefinitions>
  <Monitoring>
    <Discoveries>
      <Discovery ID="Custom.Example.ResourcePoolWebsiteWatcher.Discovery.DiscoverWebsites" Enabled="true" Target="Custom.Example.ResourcePoolWebsiteWatcher.Class.WebsiteWatcherPool" ConfirmDelivery="true" Remotable="true" Priority="Normal">
        <Category>Discovery</Category>
        <DiscoveryTypes>
          <DiscoveryClass TypeID="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website" />
        </DiscoveryTypes>
        <DataSource ID="DS" TypeID="Custom.Example.ResourcePoolWebsiteWatcher.DataSource.DiscoverWebsites">
          <IntervalSeconds>86400</IntervalSeconds>
          <UNCPathToCSVFile>\\scom2012r2.contoso.com\URL\URLMonitoringList.CSV</UNCPathToCSVFile>
        </DataSource>
      </Discovery>
    </Discoveries>
    <Monitors>
      <UnitMonitor ID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsiteAvailability" Accessibility="Public" Enabled="true" Target="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website" ParentMonitorID="Health!System.Health.AvailabilityState" Remotable="true" Priority="Normal" TypeID="Custom.Example.ResourcePoolWebsiteWatcher.MonitorType.WebsiteAvailability" ConfirmDelivery="true">
        <Category>Alert</Category>
        <AlertSettings AlertMessage="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsiteAvailability_AlertMessageResourceID">
          <AlertOnState>Error</AlertOnState>
          <AutoResolve>true</AutoResolve>
          <AlertPriority>Normal</AlertPriority>
          <AlertSeverity>Error</AlertSeverity>
          <AlertParameters>
            <AlertParameter1>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/URL$</AlertParameter1>
            <AlertParameter2>$Data/Context/Context/DataItem/RequestResults/RequestResult["1"]/BasePageData/ErrorCode$</AlertParameter2>
            <AlertParameter3>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/MonitoringIntervalInSeconds$</AlertParameter3>
            <AlertParameter4>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/TimeWindowInSeconds$</AlertParameter4>
            <AlertParameter5>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/AttemptsBeforeTurningRed$</AlertParameter5>
          </AlertParameters>
        </AlertSettings>
        <OperationalStates>
          <OperationalState ID="WebsiteUp" MonitorTypeStateID="WebsiteUp" HealthState="Success" />
          <OperationalState ID="WebsiteDown" MonitorTypeStateID="WebsiteDown" HealthState="Error" />
        </OperationalStates>
        <Configuration>
          <IntervalSeconds>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/MonitoringIntervalInSeconds$</IntervalSeconds>
          <ContentMatchString>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/ContentMatchString$</ContentMatchString>
          <URL>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/URL$</URL>
          <MaximumResponseTime>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/MaxResponseTime$</MaximumResponseTime>
          <AttemptsBeforeTurningRed>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/AttemptsBeforeTurningRed$</AttemptsBeforeTurningRed>
          <TimeWindowInSeconds>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/TimeWindowInSeconds$</TimeWindowInSeconds>
        </Configuration>
      </UnitMonitor>
      <UnitMonitor ID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsiteContent" Accessibility="Public" Enabled="true" Target="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website" ParentMonitorID="Health!System.Health.ConfigurationState" Remotable="true" Priority="Normal" TypeID="Custom.Example.ResourcePoolWebsiteWatcher.MonitorType.WebsiteContent" ConfirmDelivery="true">
        <Category>Alert</Category>
        <AlertSettings AlertMessage="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsiteContent_AlertMessageResourceID">
          <AlertOnState>Error</AlertOnState>
          <AutoResolve>true</AutoResolve>
          <AlertPriority>Normal</AlertPriority>
          <AlertSeverity>Error</AlertSeverity>
          <AlertParameters>
            <AlertParameter1>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/URL$</AlertParameter1>
            <AlertParameter2>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/ContentMatchString$</AlertParameter2>
            <AlertParameter3>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/MonitoringIntervalInSeconds$</AlertParameter3>
            <AlertParameter4>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/TimeWindowInSeconds$</AlertParameter4>
            <AlertParameter5>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/AttemptsBeforeTurningRed$</AlertParameter5>
          </AlertParameters>
        </AlertSettings>
        <OperationalStates>
          <OperationalState ID="ContentFound" MonitorTypeStateID="ContentFound" HealthState="Success" />
          <OperationalState ID="ContentNotFound" MonitorTypeStateID="ContentNotFound" HealthState="Error" />
        </OperationalStates>
        <Configuration>
          <IntervalSeconds>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/MonitoringIntervalInSeconds$</IntervalSeconds>
          <ContentMatchString>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/ContentMatchString$</ContentMatchString>
          <URL>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/URL$</URL>
          <MaximumResponseTime>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/MaxResponseTime$</MaximumResponseTime>
          <AttemptsBeforeTurningRed>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/AttemptsBeforeTurningRed$</AttemptsBeforeTurningRed>
          <TimeWindowInSeconds>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/TimeWindowInSeconds$</TimeWindowInSeconds>
        </Configuration>
      </UnitMonitor>
      <UnitMonitor ID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsitePerformance" Accessibility="Public" Enabled="true" Target="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website" ParentMonitorID="Health!System.Health.PerformanceState" Remotable="true" Priority="Normal" TypeID="Custom.Example.ResourcePoolWebsiteWatcher.MonitorType.WebsitePerformance" ConfirmDelivery="true">
        <Category>Alert</Category>
        <AlertSettings AlertMessage="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsitePerformance_AlertMessageResourceID">
          <AlertOnState>Error</AlertOnState>
          <AutoResolve>true</AutoResolve>
          <AlertPriority>Normal</AlertPriority>
          <AlertSeverity>Error</AlertSeverity>
          <AlertParameters>
            <AlertParameter1>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/URL$</AlertParameter1>
            <AlertParameter2>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/MaxResponseTime$</AlertParameter2>
            <AlertParameter3>$Data/Context/Context/DataItem/TransactionResponseTime$</AlertParameter3>
            <AlertParameter4>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/MonitoringIntervalInSeconds$</AlertParameter4>
            <AlertParameter5>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/TimeWindowInSeconds$</AlertParameter5>
            <AlertParameter6>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/AttemptsBeforeTurningRed$</AlertParameter6>
          </AlertParameters>
        </AlertSettings>
        <OperationalStates>
          <OperationalState ID="WebsiteFast" MonitorTypeStateID="WebsiteFast" HealthState="Success" />
          <OperationalState ID="WebsiteSlow" MonitorTypeStateID="WebsiteSlow" HealthState="Error" />
        </OperationalStates>
        <Configuration>
          <IntervalSeconds>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/MonitoringIntervalInSeconds$</IntervalSeconds>
          <ContentMatchString>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/ContentMatchString$</ContentMatchString>
          <URL>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/URL$</URL>
          <MaximumResponseTime>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/MaxResponseTime$</MaximumResponseTime>
          <AttemptsBeforeTurningRed>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/AttemptsBeforeTurningRed$</AttemptsBeforeTurningRed>
          <TimeWindowInSeconds>$Target/Property[Type="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website"]/TimeWindowInSeconds$</TimeWindowInSeconds>
        </Configuration>
      </UnitMonitor>
    </Monitors>
  </Monitoring>
  <Presentation>
    <StringResources>
      <StringResource ID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsiteAvailability_AlertMessageResourceID" />
      <StringResource ID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsiteContent_AlertMessageResourceID" />
      <StringResource ID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsitePerformance_AlertMessageResourceID" />
    </StringResources>
  </Presentation>
  <LanguagePacks>
    <LanguagePack ID="ENU" IsDefault="true">
      <DisplayStrings>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website">
          <Name>Website</Name>
          <Description>Websites monitored by OpsMgr</Description>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website" SubElementID="URL">
          <Name>URL</Name>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website" SubElementID="WatchedBy">
          <Name>Watched By</Name>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website" SubElementID="ContentMatchString">
          <Name>Content Match String</Name>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website" SubElementID="MaxResponseTime">
          <Name>Max Response Time</Name>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website" SubElementID="MonitoringIntervalInSeconds">
          <Name>Monitoring Interval In Seconds</Name>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website" SubElementID="TimeWindowInSeconds">
          <Name>Time Window In Seconds</Name>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website" SubElementID="AttemptsBeforeTurningRed">
          <Name>Attempts Before Turning Red</Name>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website" SubElementID="MonitorAvailability">
          <Name>Monitor Availability</Name>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website" SubElementID="MonitorPerformance">
          <Name>Monitor Performance</Name>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Class.Website" SubElementID="MonitorContent">
          <Name>Monitor Content</Name>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Class.WebsiteWatcherPool">
          <Name>Website Watcher Resource Pool</Name>
          <Description>Resource Pool used to monitor certain websites for availability and performance.</Description>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.DataSource.DiscoverWebsites">
          <Name>Discover Websites Data Source</Name>
          <Description>Contains the code required to read a CSV file and discover websites.</Description>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.DataSource.WebsiteContent">
          <Name>Website Content Data Source</Name>
          <Description>Checks for a phrase on a website.</Description>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Discovery.DiscoverWebsites">
          <Name>Discover Websites Discovery</Name>
          <Description>Discovers websites from CSV file.</Description>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher">
          <Name>Resource Pool Website Watcher</Name>
          <Description>Resource Pool Website Watcher Management Pack</Description>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsiteAvailability">
          <Name>Website Availability Monitor</Name>
          <Description>Monitors whether a website is up or down.</Description>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsiteAvailability" SubElementID="WebsiteDown">
          <Name>WebsiteDown</Name>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsiteAvailability" SubElementID="WebsiteUp">
          <Name>WebsiteUp</Name>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsiteAvailability_AlertMessageResourceID">
          <Name>Website Unavailable</Name>
          <Description>
            URL: {0}

            Error Code: {1}

            Monitoring Interval In Seconds: {2}

            Time Window In Seconds: {3}

            Attempts Before Turning Red: {4}
          </Description>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsiteContent">
          <Name>Website Content Monitor</Name>
          <Description>Checks for a string in the response from an http request.</Description>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsiteContent" SubElementID="ContentFound">
          <Name>ContentFound</Name>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsiteContent" SubElementID="ContentNotFound">
          <Name>ContentNotFound</Name>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsiteContent_AlertMessageResourceID">
          <Name>Website Content Not Found</Name>
          <Description>
            URL: {0}

            Content String: {1}

            Monitoring Interval: {2}

            Time Window: {3}

            Attempts Before Turning Red: {4}
          </Description>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsitePerformance">
          <Name>Website Performance Monitor</Name>
          <Description>Monitors the Performance of a Website.</Description>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsitePerformance" SubElementID="WebsiteFast">
          <Name>WebsiteFast</Name>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsitePerformance" SubElementID="WebsiteSlow">
          <Name>WebsiteSlow</Name>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.Monitor.WebsitePerformance_AlertMessageResourceID">
          <Name>Website Performance Slow</Name>
          <Description>
            URL: {0}

            MaxResponseTime: {1}

            Last Response Time: {2}

            Monitoring Interval In Seconds: {3}

            Time Window In Seconds: {4}

            Attempts Before Alerting: {5}
          </Description>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.MonitorType.WebsiteAvailability">
          <Name>Website Availability Monitor Type</Name>
          <Description>Monitors the availability of a website.</Description>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.MonitorType.WebsiteContent">
          <Name>Website Content Monitor Type</Name>
          <Description>Checks a website for specific content.</Description>
        </DisplayString>
        <DisplayString ElementID="Custom.Example.ResourcePoolWebsiteWatcher.MonitorType.WebsitePerformance">
          <Name>Website Performance Monitor Type</Name>
          <Description>Monitors the response time of a website.</Description>
        </DisplayString>
      </DisplayStrings>
      <KnowledgeArticles></KnowledgeArticles>
    </LanguagePack>
  </LanguagePacks>
</ManagementPack>
  • Open the Operations Manager console and import the Custom.Example.ResourcePoolWebsiteWatcher management pack

  • Go to “Administration\Resource Pools”

    • Modify the “Website Watcher Resource Pool” if you want. Simply change it to Manual Membership first.
  • Go to “Monitoring\Discovered Inventory” and change the target type to “Website”

  • View the discovered sites

image

Modifying the CSV file

  1. URL: (www.bing.com) Enter the name of the URL you want to monitor
  2. ResourcePoolName: (Website Watcher Resource Pool) This is for display purposes only and won’t change the pool that is used
  3. ContentMatchString: (search) This is the string that we validate exists on the page. If you don’t want to use this don’t leave it blank, put something common in like “href” that will always be found
  4. MaxResponseTime: (1) This is in seconds. If you don’t want to use this set it to something high, like the time window chosen, but don’t leave it blank
  5. MonitoringIntervalInSeconds: (150) This is in seconds, pick how often you want to check this site
  6. AttemptsBeforeTurningRed: (3) The times it can fail before turning red and alerting
  7. TimeWindowInSeconds: (450) You should be able to use the MonitoringIntervalInSeconds * AttemptsBeforeTurningRed
  8. MonitorAvailability: (True) For display only, just stating that we are monitoring for availability which should be true for everything
  9. MonitorPerformance: (True) For display only, just stating that we are monitoring for performance
  10. MonitorContent: (True) For display only, just stating that we are monitoring for availability which should be true for everything

image

URLMonitoring.zip

Comments

  • Anonymous
    August 20, 2014
    Hi Russ Many thanks for this update. Once again it is most welcome. One small point. The Custom.Example.WebsiteWatcher.xml in the zip download link is different from the one shown on this page (In the windows viewer). The downloaded version does not have the Resource Pool parts. The downloaded URLMonitoringList.csv is correct, as it has the new format. Thanks Mark

  • Anonymous
    August 20, 2014
    Thanks Mark! I uploaded the correct version in the zip.

  • Anonymous
    August 25, 2014
    Hi Russ This won't install in my SCOM 2012 SP1 environment. It is looking for newer versions of the system management packs than I have installed. What level of CU / UR is required? Thanks Mark

  • Anonymous
    August 25, 2014
    Hi, I don't think there is a requirement. The versions in the MPs are the versions I referenced when I wrote the MP and they were likely 2012 R2. If you want to use it in your environment you can edit the Manifest section of the MP to match the MP versions you have in your environment. Russ

  • Anonymous
    November 24, 2014
    Hello. Thank you for this MP. I was easily able to get this setup and working. However, when I edit the CSV file, the changes do not seem to be picked up. I changed the discovery from 86400 seconds to 300, and even several hours later, the new URLs are not picked up. Any suggestions?

  • Anonymous
    November 25, 2014
    There is a vbscript that runs the discovery. You can add logging to that script to understand why it might not be submitting discovery data.

  • Anonymous
    November 26, 2014
    Thank you for the response. I see the VBScript in the XML. You mean I should edit the script in the XML and reimport the MP? Sorry, but I never learned VBScript as when I got into IT PowerShell was already beginning to take over. I'm not seeing anything like a PowerShell Try/Catch block equivalent for VBScript. All I can really see for logging errors is to manually redirect the error stream (2>> log.txt) when running the script via cscript, but to me that doesn't sound like a viable option since I am not calling the script manually but SCOM is calling it instead. Can you elaborate on how I could add logging please?

  • Anonymous
    November 26, 2014
    You can add logging by directing errors/messages to a log file, reimport the MP, and the logging should appear the next time the discovery runs. Just make sure you test the script out on one of the management servers first to ensure it runs properly and outputs what you want.

  • Anonymous
    February 22, 2015
    Hello Russ, This is a great MP. How can we include, URLs which need credentials? thanks m

  • Anonymous
    March 30, 2015
    Excellent MP Russ. Thank you very much