New Question
 
 
PRTG Network Monitor

Intuitive to Use.
Easy to manage.

200.000 administrators have chosen PRTG to monitor their network. Find out how you can reduce cost, increase QoS and ease planning, as well.

Free PRTG
Download >>

 

What is this?

This knowledgebase contains questions and answers about PRTG Network Monitor and network monitoring in general. You are invited to get involved by asking and answering questions!

Learn more

 

Top Tags


View all Tags


On monitoring HTTP status of multiple service instances of load balanced websites

Votes:

0

Your Vote:

Up

Down

I did see another similar question but I decided to start a new thread any way.

We use DNS Round Robin (multiple IP A records for the same host name). Every time a client does a DNS lookup they get multiple IP addresses returned in random order (this is a feature of DNS). The client (e.g. Chrome, Firefox, Safari, etc) will try the first IP in the order they were provided when it makes its HTTP request; most popular web clients will fail over (even in subsequent requests) to the other IP addresses DNS gave it if it doesn't get a response.

This is not dissimilar to many load balancing scenarios. DNS may only give you one IP, but a front end service often proxy's or tunnels the connection to one of many possible back ends. Although there are other sensor types monitoring as many CIs on all devices as we can, it would be nice to get an HTTP 200 from each web server that hosts a copy of the website.

Story: As a System Administrator using PRTG to monitor my hosting infrastructure, I want to have one or many sensors tell me the status of each instance of my load balanced websites, so I can easily see the health of that one endpoint and can address accordingly.

cUrl and even Powershell/C# should have ways to do this, basically we are either wanting to bypass DNS (specify IP address to send the HTTP GET request) and hopfully (even if later) in the case of DNS Round Robin, use it more effectively and check all IPs returned.

If it gets in your backlog, I would be happy to provide as much input as you like.

ha http http-advanced load-balancing ssl

Created on Feb 3, 2016 3:58:08 AM by  Curtis Kayfish (70) 2 1



Best Answer

Accepted Answer

Votes:

0

Your Vote:

Up

Down

I had a some time today, and this is what I came up with for a v0.1 (Alpha) Advanced custom sensor in PowerShell

Basically, supply it the host name, an optional CSV of IP addresses, a specific page to get, and whether it should use SSL. It will check each IP address, setting the host name as an HTTP header, and get the HTTP status for each address. Intended to work when a host name has multiple IP addresses defined to allow for DNS Round Robin HA/LB, as well as traditional load balancing where you need to identify specific back-end IP addresses that DNS does not resolve to for that host name.

www.paesller.com for example resolves from a CNAME into 8 IP addresses (today). This sensor will show the HTTP status code of each host.

 ##########################################################################
 # PRTG Custom Advanced EXE/XML Sensor v0.2
 #
 # Get HTTP Status of all A/CNAME DNS records, or specified list of IPs, given a specific host name
 #
 # Parameters: -h <hostname> [-ips <csv of IPs to check>] [-page <path/file to get>] [-ssl (Use httpS)]
 # Example: -h my.website.com -ips 10.10.10.1,10.10.10.2,10.10.10.3 -page testpage.htm -ssl
 #
 # TODO: How to identify error when cant connect to port (currently NULL value)
 # TODO: Include other details from IWR
 # TODO: Make hostname required?
 # TODO: Set warning and/or errors 
 # 
 ##########################################################################
 
 param (
   [string]$h = "www.paessler.com",
   [string]$ips = $null,
   [string]$page = $null,
   [switch]$ssl = $false
 )
 $ipa =@()
if ($ips) {
   # Split CSV parameter into array of strings
   $ipa = $ips.Split(",")
}
else {
   # Get all A and CNAME records for host $h into array of strings
   $d=Resolve-DnsName -Name $h -DnsOnly -TcpOnly -Type A
    foreach($i in $d) {
       if ($i.Address) {
          $ipa += $i.Address
        }
    }
   $d=Resolve-DnsName -Name $h -DnsOnly -TcpOnly -Type CNAME
    foreach($i in $d) {
       if ($i.Address) {
          $ipa += $i.Address
        }
    }
}

Write-Host "<?xml version=`"1.0`" encoding="UTF-8"?>"
Write-Host "<prtg>"
Write-Host " <Text>$($h)</Text>"

# For each IP address found or specified, get HTTP status code for using host header
foreach($i in $ipa) {
   # If -ssl parameter set use HTTPS, otherwise use HTTP as default
   if ($ssl) { $req="https://$($i)/$($page)"}
     else {$req="http://$($i)/$($page)"}
  # Get HTTP status
  [int]$rc=$null
  try { $r = Invoke-WebRequest $($req) -headers @{host=$($h)} -UseBasicParsing -UseDefaultCredentials
        # Do best we can to ensure status value meets type constraint
          $z=[int]::TryParse($r.StatusCode , [ref]$rc )
        } catch {
          $z=[int]::TryParse($_.Exception.Response.StatusCode.Value__ , [ref]$rc )
        }
   # Create result record
   Write-Host " <result>"
   Write-Host "  <channel>$($req)</channel>"
   Write-Host "  <value>$($r.StatusCode)</value>"
   Write-Host "  <float>0</float>"
   Write-Host " </result>"
}
Write-Host "</prtg>"

Created on Feb 4, 2016 8:51:50 AM by  Curtis Kayfish (70) 2 1

Last change on Feb 5, 2016 7:00:15 PM by  Curtis Kayfish (70) 2 1



5 Replies

Votes:

0

Your Vote:

Up

Down

Since posting I got excitedly hopful that we could use the custom HTTP headers optional field to meet this precise need. Unfortunately, HOST is one of three specifically excluded HTTP headers we can define. Arrg!

I then realized that I can meet my need to with a custom sensor that either A) Parses the IP addresses in a DNS Lookup or B) Take an IP address & hostname as parameters, then using Powershell & Invoke-WebRequest (iwr) with the IP address in the URL and defining the HOST HTTP header such as: iwr https://127.0.0.1 -headers @{Host='my.website.com'}

Still, add my name to the list of people that would appreciate being able to use the existing sensors to accomplish this :)

Created on Feb 3, 2016 8:28:54 AM by  Curtis Kayfish (70) 2 1



Accepted Answer

Votes:

0

Your Vote:

Up

Down

I had a some time today, and this is what I came up with for a v0.1 (Alpha) Advanced custom sensor in PowerShell

Basically, supply it the host name, an optional CSV of IP addresses, a specific page to get, and whether it should use SSL. It will check each IP address, setting the host name as an HTTP header, and get the HTTP status for each address. Intended to work when a host name has multiple IP addresses defined to allow for DNS Round Robin HA/LB, as well as traditional load balancing where you need to identify specific back-end IP addresses that DNS does not resolve to for that host name.

www.paesller.com for example resolves from a CNAME into 8 IP addresses (today). This sensor will show the HTTP status code of each host.

 ##########################################################################
 # PRTG Custom Advanced EXE/XML Sensor v0.2
 #
 # Get HTTP Status of all A/CNAME DNS records, or specified list of IPs, given a specific host name
 #
 # Parameters: -h <hostname> [-ips <csv of IPs to check>] [-page <path/file to get>] [-ssl (Use httpS)]
 # Example: -h my.website.com -ips 10.10.10.1,10.10.10.2,10.10.10.3 -page testpage.htm -ssl
 #
 # TODO: How to identify error when cant connect to port (currently NULL value)
 # TODO: Include other details from IWR
 # TODO: Make hostname required?
 # TODO: Set warning and/or errors 
 # 
 ##########################################################################
 
 param (
   [string]$h = "www.paessler.com",
   [string]$ips = $null,
   [string]$page = $null,
   [switch]$ssl = $false
 )
 $ipa =@()
if ($ips) {
   # Split CSV parameter into array of strings
   $ipa = $ips.Split(",")
}
else {
   # Get all A and CNAME records for host $h into array of strings
   $d=Resolve-DnsName -Name $h -DnsOnly -TcpOnly -Type A
    foreach($i in $d) {
       if ($i.Address) {
          $ipa += $i.Address
        }
    }
   $d=Resolve-DnsName -Name $h -DnsOnly -TcpOnly -Type CNAME
    foreach($i in $d) {
       if ($i.Address) {
          $ipa += $i.Address
        }
    }
}

Write-Host "<?xml version=`"1.0`" encoding="UTF-8"?>"
Write-Host "<prtg>"
Write-Host " <Text>$($h)</Text>"

# For each IP address found or specified, get HTTP status code for using host header
foreach($i in $ipa) {
   # If -ssl parameter set use HTTPS, otherwise use HTTP as default
   if ($ssl) { $req="https://$($i)/$($page)"}
     else {$req="http://$($i)/$($page)"}
  # Get HTTP status
  [int]$rc=$null
  try { $r = Invoke-WebRequest $($req) -headers @{host=$($h)} -UseBasicParsing -UseDefaultCredentials
        # Do best we can to ensure status value meets type constraint
          $z=[int]::TryParse($r.StatusCode , [ref]$rc )
        } catch {
          $z=[int]::TryParse($_.Exception.Response.StatusCode.Value__ , [ref]$rc )
        }
   # Create result record
   Write-Host " <result>"
   Write-Host "  <channel>$($req)</channel>"
   Write-Host "  <value>$($r.StatusCode)</value>"
   Write-Host "  <float>0</float>"
   Write-Host " </result>"
}
Write-Host "</prtg>"

Created on Feb 4, 2016 8:51:50 AM by  Curtis Kayfish (70) 2 1

Last change on Feb 5, 2016 7:00:15 PM by  Curtis Kayfish (70) 2 1



Votes:

0

Your Vote:

Up

Down

Looks good, thanks for sharing your work! You can also get rid of the IP splitting if you pass the parameters like this: @(10.10.10.1,10.10.10.2,10.10.10.3) They will be automatically be usable in a foreach then :)

Created on Feb 4, 2016 1:21:25 PM by  Stephan Linke [Paessler Support]



Votes:

0

Your Vote:

Up

Down

Fixed 2 bugs in above code. Changed version to 0.2.

FIXED: Declare variable $rc before setting value using [ref] FIXED: Added -UseBasicParsing to Involke-WebRequest since IE engine likely not initiated for PRTG service account

I've edited it a few time trying to place in the v0.2 of the code, but i keep seeing only the original text. Im guessing that the change needs to be approved by a moderator so will just leave it for now.

Created on Feb 5, 2016 7:04:01 PM by  Curtis Kayfish (70) 2 1



Votes:

0

Your Vote:

Up

Down

Fixed the version number for you :) Thanks for the contributions!

Created on Feb 8, 2016 9:33:21 AM by  Stephan Linke [Paessler Support]

Last change on Feb 8, 2016 9:33:29 AM by  Stephan Linke [Paessler Support]



Please log in or register to enter your reply.


Disclaimer: The information in the Paessler Knowledge Base comes without warranty of any kind. Use at your own risk. Before applying any instructions please exercise proper system administrator housekeeping. You must make sure that a proper backup of all your data is available.