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