PRTG - HTTP Push-Sensoren

Diese Seite beschreibt die Möglichkeit, beliebige numerische Werte von eigenen Sensoren, IoT-Geräten, Skripten etc. per HTTP GET/POST-Request an eine PRTG-Probe zur visualisierung

Ein PRTG-Server nutzt lokale und verteilte Probes, um mit diesen lokale und entfernte Systeme zu überwachen. Die Probes können verteilt werden, holen ihre Konfiguration vom PRTG-Server, arbeiten die Jobs an und melden an den Server. So kann ein skalierbares und performantes System aufgebaut werden. Es bleibt aber ein "Polling" durch die Probes mit ein eingebauten Sensoren oder Custom Sensoren. Diese Seite beschreibt die HTTP-Push-Sensoren.

Die Sensoren habe ich erstmals in der Version 15.2.16.2229 als Beta gesehen. Angeblich gibt es den aber seit 14.2.9 den Advanced Sensor und seit 13.4.7 den einfachen HTTP Push Count. Man sollte doch häufiger mal die Release Notes lesen.

Hinweis
Wenn Sie einen neuen Sensor anlegen, dann kann das einige Sekunden dauern, bis die Probe diese Konfiguration übernommen hat. Bitte etwas Geduld, wenn der Sensor nicht sofort mit Daten gefüllt wird.

IoT Push
Für IoT-Projekte können Sie sich alternativ den "HTTP IoT Push Data Advanced"_Sensor anschauen. https://www.paessler.com/manuals/prtg/http_iot_push_data_advanced

HTTP-Push in der PRTG Plattform

Auf der Seite PRTG Plattform haben Sie einen schönen Überblick der Komponenten in einem PRTG-Umfeld. Eine PRTG-Probe ermittelt Informationen von sich oder einem abgefragten System und meldet diese an den Core zur Speicher und anzeigt. Doe Probe ist hier der aktive Part und muss bei entfernten Systemen diese auch erreichen können.

Beim HTTP-Push-Sensor ist die Probe die passive Komponenten und nimmt nur die Daten an, die vom einem anderen Code gemeldet werden.

Ein Sender kann also alles sein, was einen HTTP´/HTTPS-GET oder POST absenden kann, d.h. auch ein IoT-Device, PHP-Code in einem Skripte oder Webseite, PowerShell-Skripte u.a. So könnte ein Exchange Auswerteskript die Ergebnisse direkt an PRTG senden und beim Ausbleiben könnte PRTG sogar direkt einen Alarm generieren.

Einschränkungen des direkten Monitoring durch PRTG-Probes

Zur besseren Abgrenzung beschreibe ich hier die Einschränkungen des klassischen Ansatzes, die per HTTP-Push-Probe besser gelöst werden können:

  • Überwachbarkeit
    Zuerst muss das zu überwachende Objekt auch per PRTG-Sensor "überwachbar" sein, sei es dass ein Dienst per LAN angesprochen werden kann, ein Performance Counter ausgelesen oder ein anderes Kriterium nutzbar ist.
    Mit der HTTP Push-API kann aber ein Skript oder Prozess auch selbst aktiv Meldungen senden ohne auf eine Probe zu warten. Das ist für Alarme o.ä. besonders interessant oder Skripte, die einen eigenen Scheduler haben und das Ergebnis dann ohne Verzug melden können.
  • Stichproben/Intervall
    Eine PRTG-Probe kann nicht permanent überwachen sondern führt den Check regelmäßig in voreingestellten Intervallen aus. Hier ist ein Kompromiss zwischen Aktualität und Belastung zu finden. Viele Checks laufen daher einmal pro Minute, alle 5 Minuten oder noch seltener ab.
    Ein HTTP Push-Sensor ist hier für die PRTG-Plattform viel schonender, insbesondere wenn die Werte aufwändig per Custom Sensor (PowerShell o.ä.) ermittelt werden müssen
  • Zeitverzug
    Durch das Intervall werden natürlich Werte nicht ein "Realtime" übermittelt, sondern immer etwas verzögert. Das ist natürlich schlecht wenn Grenzwerte überschritten werden.
    Ein HTTP Push-Sensor kann alleine z.B. bei bestimmten Bedingungen "schnell" senden.
  • Skalierbarkeit der Probe
    Je mehr aktive Tests eine PRTG Probe gegen den lokalen Server oder remote Systeme unternehmen muss, desto mehr Leistung muss bereit gestellt werden. Gewisse Aufrufe (WMI, PowerShell etc.) sind sogar sehr kostspielig und können eine zeitnahe Überwachung erschweren oder gar unmöglich machen.
    Ein HTTP Sensor verteilt die Last weg von der Probe auf den Server oder Service.
  • Feste IP-Adresse oder DNS-Name und NAT
    Wenn ein Server "aus der Ferne" überwacht wird, dann muss er von der Probe erreichbar sein. Das ist knifflig, wenn das System keine feste IP-Adresse hat oder hinter einem NAT-Router steht. Denkbar schlechte Aussichten für IoT-Geräte, die gegen ein PRTG in der Cloud laufen
  • Energiesparen
    Immer mehr Geräte sind Batteriebetrieben oder schalten sich nur sehr kurz ein (Solarbetrieb, Piezo). Sie sind kurz wach, können ein paar Pakete senden und legen sich dann wieder tief schlafen. So ein Gerät können Sie schlecht aus der Ferne abfragen aber es kann Daten an eine Stelle melden. Denken Sie an Wasserstandsmelder, Feuchtigkeitssensoren in Pflanzkübeln etc.
  • Berechtigungen
    Wenn PRTG aus der Ferne einen Server überwachen soll, dann muss er sich an dem Server authentifizieren, oft sogar als Administrator. Damit ist so ein "Monitoring-Programm" am Ende mächtiger als Der "Domänen-Administrator". Da ist es schon eleganter, wenn der PRTG-Server einfach Daten annimmt, erfasst und deren Ausbleiben ermittelt aber der Dienstadministrator die Überwachung vor Ort kontrolliert.
  • Erreichbarkeit des Systems und Sicherheit
    Alle Prüfungen, die von einer Probe gegen ein Device ausgeführt werden, bedingen die Erreichbarkeit des Device für die Probe. Firewalls oder gar NAT sind dabei natürlich hinderlich. Jedes Device muss auch über einen "Port" erreichbar sein und je "einfacher" ein Device ist, desto rudimentärer sind hierbei die Möglichkeiten zur Absicherung (Source-IP-Filter, Kennwort-Verschlüsselung).
  • Entlastung der PRTG Probe
    Klassisch startet die PRTG-Probe die aktiven Check und greift ggfls. remote per WMI, SNMP o.ä. auf Systeme zu. Das kostet Zeit uns insbesondere wenn z:B. eine PowerShell noch weitere Addins (Exchange) nachladen muss
  • Andere Sicherheit
    Mit einem PRTG Push-Sensor erspart man sich, dass die PRTG-Probe mit Berechtigungen auf das Zielsystem zugreifen muss. Allerdings ist die HTTP-Push-Authentifizierung ohne Verschlüsselung nicht sehr sicher. Aber die Credentials können für sonst nichts missbraucht werden, was ein Gewinn darstellt.
  • 64Bit statt 32bit
    Aktuell ist PRTG immer noch ein 32bit Programm und damit startet auch die Probe alle Programme und insbesondere die PowerShell als 32bit Version, was durchaus zu Einschränkungen führen kann.
  • Single Sensor mit mehreren Antworten.
    Daten, die so ein eigener Sensor ermittelt, kann er immer nur an den einzelnen Sensor zurückgeben. Manchmal kann ein Skript aber verschiedene Daten ermitteln, die aber in unterschiedlichen Sensoren eingespeist werden sollen. Das geht mit dem klassischen Sensor erst mal nicht.

Allerdings bedeutet der Einsatz der "HTTP Push"-Funktion natürlich, dass die Probe von dem Endpunkt aus erreichbar ist und auf dem zu überwachenden System entsprechender Code addiert wird.

Sie können diese Technik wunderbar nutzen, um auch einfach den Status von beliebigen Skripten auf verschiedenen Servern an PRTG als zentrale Überwachungsinstanz zu melden.

HTTP-Push mit MSTask

Es gibt viele schöne Auswertungen, die am Ende einen Status oder numerische Antworten liefern. Das Problem dabei ist aber, dass diese Auswertungen manchmal bestimmte Laufzeitumgebungen benötigen oder an sich relativ lange dauern. Bei PRTG wird normal immer nur die PRTG-Probe aktiv und damit liegt auch die Last auf der Probe. Wenn dann die Abfrage der Daten von der Probe auf dem Zielsystem noch viel Netzwerklast produziert oder eine langsamere WAN-Verbindung dazwischen ist, dann kann man nur eine Probe auf dem Zielserver installieren. Das ist nicht sonderlich schwer, aber in der Hierarchie ist eine Probe natürlich weiter oben angesiedelt als ein Device unter einen Probe.

WMI-Abfrage, Exchange Messagetracking-Auswertungen und andere Dinge kosten Zeit, CPU und Speicher. Interessant ist hier, dieses Skript direkt auf dem Server selbst ausführen zu lassen. für die Meldung an PRTG gibt es nun drei Wege:

  1. Ablegen als Datei und der "PRTG File Content Sensor" liest ein
    So ein Skript könnte das Ergebnis einfach als Datei ablegen, die dann vom "PRTG File Content Sensor" eingelesen und auf einen String überprüft wird.
  2. Ablegen als Datei und ein "PRTG Custom Sensor" liest ein
    Pfiffiger sehe ich ein Skript, welches als Ausgabe das gleiche Format nutzt, wie ein Custom Sensor das direkt zurück geben würde. Dann kann ein Custom Sensor in PRTG die Datei sehr einfach "einlesen". Quasi eine CMD-Box mit einem einfachen "type <datename>". So könnte man auch mehrere Kanäle erlauben. Leider macht das PRTG noch nicht alleine
  3. HTTP-Push
    Mit dem HTTP-Push-Sensor und insbesondere dem "HTTPS- Push Advanced Server" kann das analysierende Skript aber auch direkt die Daten zum PRTG melden. Dann kostet es fast keine Last auf der PRTG-Probe

Hier ist die letzte Option besonders interessant, um die Daten per HTTP an PRTG zu senden.

HTTP-Push Data und Push Data Advanced

PRTG enthält genau genommen drei dieser "Push"-Sensoren, bei denen per HTTP-GET oder HTTP-POST Daten an eine Probe zur Ablage in PRTG gesendet werden können.

  • HTTP Push Count sensor
    Dieser einfache Sensor "zählt" einfach nur jede empfangene Information. Wer also ein Skript gebaut hat, welches eine gewissen Event "zählen" will, dann ist dieser einfache Sensor passend.
  • HTTP Push Data Sensor
    Der Data Sensor übernimmt die Zahl, die mit dem Request übermittelt wird. Wenn also nur ein einziger Wert zu senden ist, ist dieser Sensor der Richtige
  • HTTP Push Data Advanced Sensor
    Zuletzt gibt es noch die Möglichkeit mehrere Werte als XML-Struktur an PRTG zu übergeben (Siehe auch PRTG:Custom Sensor)

Insofern haben wir mit dem Push-Sensor eine Möglichkeit aktiv vom überwachten System Daten in PRTG einzustellen, ohne das PRTG selbst aktiv werden müsste.

Leider hat PRTG bislang nicht vorgesehen, dass z.B. beim "Advanced Sensor" auch ein Zeitstempel mitgeliefert wird. Das wäre aus meiner Sicht sehr wünschenswert um gepufferte Daten zeitgenau zugeordnet werden können. Nebenbei könnte man so auch alte Daten importieren.

Der Sensor wird wie alle Sensoren einfach an ein Gerät addiert:

Sie können ein oder mehrere HTTP-Push-Sensoren pro Gerät anlegen. Wer ein Gerät abbilden will, welche keine IP-Adresse hat, kann z-B 0.0.0.0 als IP-Adresse eintragen und darunter dann ein oder mehrere HTTP-Push-Sensoren konfigurieren. Es ist dabei kein Problem, wenn alle Push-Sensoren den gleichen Port (Default 5050) nutzen, da das sendende Gerät eine eindeutige Kennung mit senden muss. "Sicher" ist das aber nur bedingt. Wer auf dem LAN so einen Push mitschneiden kann, kennt zumindest eine Geräteidentifikation und kann falsche Daten einschleusen. Es gibt hier kein Handshake, USN o.ä. oder gar SSL-Verschlüsselung. Das könnte man sicher besser machen aber dann wird der Aufwand beim Sender wieder größer.

Da fehlt dann ja nur noch, dass man auch per UDP einfach Daten an PRTG senden kann. für viele ganz kleine Gerät (PIC, Arduino etc.) sind TCP-Verbindungen schon viel aufwändiger als ein UDP-Paket. Aber das ist so kein Problem, denn diese Lücke kann man einfach selbst schließen.

Ein einfacher Test können Sie mit jedem Browser machen. Ich habe mir dazu einfach einmal einen "Count" und einmal einen "Data"-Sensor angelegt. Eine XML-Datei sende ich später per PowerShell. Im Browser reicht dann die Eingabe einer URL

GET http://<probe_ip>:<port_number>/<token>?value=<integer_or_float>&text= <text message>

# Advanced Sensor mit GET
GET http://<probe_ip>:<port_number>/<token>?content=<valid XML_or_JSON>

Als Antwort bekommt man eine JSON-Meldung. Hier ein Beispiel mit einem ungültigen Token.

Achtung: Das Token ist "Case sensibel"

Solange die Sensoren noch nichts bekommen haben, ist der Status nur beim "Counter" auf Grün mit 0 und die beiden anderen auf "Unknown"

Sobald Daten gesendet werden, sind diese auch alle in PRTG zu sehen:

Wer hier also im Sekundentakt Daten sendet, kann sehr fein auflösen aber füllt auch sehr schnell die PRTG-Datenbank. Obwohl es ein "Push-Sensor" ist, kann man ein "Scanning-Intervall" angeben. Ich habe testweise die 60 Sek stehen lassen. Sendet der Sensor mehrere Werte pro Minute wird anscheinend ein Mittelwert erstellt und nur dieser aufgetragen.

Andererseits werden aber ausbleibende Werte innerhalb des Intervalls nicht als "Downtime" gewertet oder als Fehler geliefert. Dies ist der Default. Wenn Sie ausbleibende Werte als Fehler haben wollen, dann sollten Sie dies in den Einstellungen ändern.

Dann aber sieht man auch in der PRTG-Übersicht sofort, welche Push-Sensoren gerade nicht senden:

Auch wenn noch nicht alles perfekt ist, ist der Push-Sensor ein wichtiger Weg neue Werte in PRTG zu integrieren.

Der HTTP-Push-Sensor ist schon ein sehr interessanter Sensor für die aktive Meldung von Systeme an PRTG. Allerdings sollte vielleicht der Defaults Status bei fehlenden Daten auf "Unknown" gehen und Value-Typ neben Integer und Float auch noch die Unterscheidung nach Absolut und Differenziell erlauben. Auch wäre die Auswahl  von "Mittelwert/Min/Max/Extremwert" wünschenswert. So könnten Geräte sofort einen "Ausschlag" senden, der dann nicht im Mittelwert untergeht.

HTTP-Push und Sicherheit

Eine Verbindung per HTTPS finde ich wichtig, damit nicht nur die Daten selbst verschlüsselt und vor allem gegen Veränderungen geschützt sind. Fast wichtiger ist hier, dass das TOKEN als Teil des Requests nicht mehr in Klartext übertragen wird. Ansonsten kann ein "bösartiger" Request einfach falsche Daten einmischen.

Seit der Version Version 17.2.32 (Juni 2017) unterstützt der HTTP-Push-Sensor HTTPS auf Basis von TLS 1.2. Ältere Verfahren werden nicht unterstützt

Es gibt viele kleine Geräte, die gerade kein SSL können. Teilweise weil es einfach keine Libraries gibt oder die CPU oder Speicher das nicht hergeben (z.B. Arduino oder ESP8266 SoC). Oft ist hier aber sogar HTTP schon zu "schwer". Sie können HTTP nutzen aber sollten dann sicherstellen, dass niemand das LAN" mitlauscht" und so an das Token kommt und ihnen die Daten "stört"

Interessant ist aber schon die Verschlüsselung der Daten selbst z.B. nach Diffie-Hellmann.

Diese relativ einfachen Operationen sollten auch mit Mini-Rechnern möglich sein.

Wenn das schon nicht geht, dann wäre ein "Rolling Code"-Mechanismus durchaus auch interessant. Als eine mit jeder Verbindung zu ändernden Nummer, ähnlich den RSA-Tokens. Man müsste nur einen Startwert oder einen Device-spezifischen Code hinterlegen und beide rechnen für sich die gleiche Nummer. Da Datagramme ja verloren gehen können, muss der Empfänger im schlimmsten Fall einen zweiten Code abwarten, um wieder InSync zu sein.

HTTP-Push und Performance

Selbst PRTG führt den HTTP-Push-Sensor als "Niedrig" im Hinblick auf die Ressourcen ein. Das stimmt so natürlich nicht, wenn der Aufruf des entsprechenden Skripts auf dem PRTG-Server erfolgt. Aber der Vorteil des HTTP-Push-Sensors ist ja gerade, dass er überall laufen und damit dezentral verteilt werden kann.

PRTG sammelt einfach die Ergebnisse ein und stellt diese entsprechend dar. Das "kostet" nicht viel und damit kann PRTG aus meiner Sicht sehr gut skaliert werden. Insbesondere für Systeme, auf denen Sie keine PRTG-Probe installieren können um selbst lokale Tests auszuführen.

Lieber auf dem System lokal die Daten sammeln und ggfls. sogar häufiger melden als von einer Probe aus "remote" das System überwachen. Das geht zwar auch aber bringt mehr Last für die überwachende Probe mit.

HTTP-Push mit Powershell

Um zu sehen, dass ich nichts grundlegend falsch mache, habe ich einfach einen HTTP-PushSensor angelegt, der auf Port 5050 lauscht und dessen GUID ein "test" ist.

Das ist mit Powershell besonders einfach, wie folgende Beispiel dokumentiert:

$prtgresult = '<?xml version="1.0" encoding="UTF-8" ?>
<prtg>
   <result>
      <channel>Demo Minimum Example</channel>
      <value>3.2</value>
      <float>1</float>
   </result>
</prtg>'

Add-Type -AssemblyName system.web

$Answer=Invoke-Webrequest `
   -method "GET" `
   -URI ("http://192.168.178.11:5050/test?content=$(([System.Web.HttpUtility]::UrlEncode($prtgresult)))") `
   -usebasicparsing
if ($answer.Statuscode -ne 200) {
   write-warning "Request to PRTG failed"
   exit 1
}

Und kurz darauf ist der Status in PRTG zu sehen.

Damit ist die Tür offen, um mit beliebigen Skripten, die z.B. durch den Taskplaner direkt auf den Server ausgeführt werden, Daten zu sammeln und an PRTG zu übergeben.

POST statt GET

Die Einlieferung von Daten an den HTTP-PushSensor kann sowohl per GET als auch per POST erfolgen. Ich habe sehr oft immer die GET-Variante genutzt, wobei umfangreichere XML-Strukturen damit natürlich immer kniffliger zu lesen sind. Auch gibt es durchaus Proxy-Server, Firewalls, IDS-Systeme, die die Länge einer URL kritisch betrachten.

Auch wenn 2 Kilobyte recht groß ist, kann ein POST vielleicht "schicker" aussehen, speziell wenn Sie die Anfrage mit Wireshark u.a. nachverfolgen. In dem Fall bietet es sich dann an, die Ergebnisse per "POST" zu senden. Ein paar Dinge sind dabei zu beachten:

  • ContentType auf application/xml oder application/json
    Wenn man das als form-encoded sendet, dann werden die Werte nicht übernommen
  • Body muss HTML-Encoded sein
    Das gilt besonders, da wir ja gerne Zeichen wie <,>,% etc. verwenden

Das ganze sieht dann so aus:

$prtgresult = '<?xml version="1.0" encoding="UTF-8" ?>
<prtg>
   <result>
      <channel>Demo Minimum Example</channel>
      <value>3.3</value>
      <float>1</float>
   </result>
</prtg>'

Add-Type -AssemblyName system.web

$Answer=Invoke-Webrequest `
   -method "POST" `
   -URI ("http://192.168.178.11:5050/test") `
   -ContentType "application/xml" `
   -Body ([System.Web.HttpUtility]::UrlEncode($prtgresult)) `
   -usebasicparsing
if ($answer.Statuscode -ne 200) {
   write-warning "Request to PRTG failed"
   exit 1
}
else{
   $answer.content
}

Laut Paessler muss man als Encoding "application/x-www-form-urlencoded" nutzen. Wenn Sie nichts angeben, dann übernimmt PRTG aber einfach das Encoding an. Allerdings müssen Sie dann natürlich den String auch "URLEncoded" senden.

Ich habe mehrfach aber das Problem gehabt, dass alle OK ausgesehen hat aber die Probe die Daten immer noch nicht geliefert hat.

HTTP-Push Debugging und Rückgabe-Code

Wenn Sie sich die beiden Beispiele anschauen, dann sehen Sie, dass ich die Antwort des Invoke-Webrequest auswerte. Ein 200OK sagt schon mal, dass der Request beim Server angekommen ist und verarbeitet werden konnte. Aber das bedeutet nicht, dass es auch einen passenden Sensor gibt und schon gar nicht, dass der Sensor die Nutzdaten auch verarbeiten konnte. Wenn der PRTG-Server erreicht werden konnte, dann liefert die Antwort eine JSON-Struktur zurück, die z.B. wie folgt ausgewertet werden kann:

if ($answer.Statuscode -ne 200) {
   write-warning "Request to PRTG failed"
   exit 1
}			
elseif (($answer.content | convertfrom-json)."Matching Sensors" -eq "0") {
   write-warning " No matching sensor found for $($prtgpushurl+$sensorname)"
   exit 2
}
else {
   write-verbose "Sending Data OK"
   $result=$answer.content | convertfrom-json | select url,status,"Matching Sensors" 
   $result.url = $prtgurl
   $result
}

Der EXIT-Code hier muss aber von ihnen lokal ausgewertet werden. Der PRTG-Server sieht diese Codes nicht, wenn das Skript selbst nicht von einer PRTG-Probe aufgerufen wurde. Genau genommen gibt es sogar mehrere Situationen, mit denen ihre Skript umgehen muss.

  • TCP-Verbindung zu PRTG nicht möglich
    In dem fall ist aber der Statuscode nicht gesetzt sondern die Klasse wirft eine Exception, die sie abfangen müssen
  • HTTP-Request <> 200
    Den Fall habe ich selbst noch nie gehabt. Wen mein HTTP-Push-Sensor an die PRTG Probe kommt, dann kam bislang auch immer ein 200 OK
  • HTTP Code 200 UND SensorGUID NICHT gefunden
    Im Content der Antwort findet sich folgende JSON-Struktur. Der Eintrag bei "Matching Sensors" sagt dies deutlich.
{ "status": "Ok", "Matching Sensors": "0" }
  • HTTP Code 200 UND SensorGUID gefunden
    Im Content der Antwort findet sich folgende JSON-Struktur. Leider ist das keine Garantie, dass die Daten auch verarbeitet wurden. Eine "falsche" XML-Datei wird auch mit einem OK quittiert. Ich habe hier noch nie einen anderen Status gesehen.
{ "status": "Ok", "Matching Sensors": "1" }
  • Ungültige XML-Struktur
    Wenn die XML-Struktur angekommen aber nicht lesbar ist, dann zeigt PRTG das auch im Sensor an

Wenn Sie auf dem Sensor ein "Debugging" aktiviert haben, dann landen die gesendeten XML-Daten ebenfalls in "C:\ProgramData\Paessler\PRTG Network Monitor\Logs (Sensors)". Allerdings ist der Dateiname nicht "Result of..." sondern "Request for Sensor ..". Hier ein Beispiel:

HTTP-Push und Überwachung

Wenn nun nicht die PRTG-Probe den Sensor regelmäßig startet sondern ihr eigener Prozess den Check aufruft, dann stellt sich die Frage wie "Aussetzer" erkannt werden. Auch hier hilft der empfangende PRTG-Service mit. Sie können pro Sensor einstellen, wie PRTG auf das Ausbleiben von Daten reagieren soll:

So können Sie aktiv erkennen, ob ein losgelöster HTTP-Push-Sensor noch regelmäßig gestartet wird oder nicht. Wenn Sie den HTTP-Push Sensor als "Advanced Sensor" anlegen, dann muss er eine XML/JSON-Struktur liefern. Der Vorteil hierbei ist, dass Sie auch einen "Text" mitliefern können, der im Statusfenster von PRTG erscheint. So sind sogar textuelle Rückmeldungen möglich.

HTTP-Push mit Exchange

Um die Leistungsfähigkeit von HTTP-Push exemplarisch zu zeigen, habe ich hier ein ganz triviales Skript, welches aus dem Messagetracking ein paar Statistiken ermittelt und per HTTP-Push an einen Server sendet:

write-host "PRTG Exchange Messagetracking"
 
[long]$ndrcount=0
[long]$incount =0
[long]$insize =0
[long]$outcount =0
[long]$outsize =0
 
 
set-psdebug -strict
 
write-host " Loading Messagetracking files"
get-messagetrackinglog `
   -resultsize unlimited `
   -start (get-date).addminutes(-5) `
| % {
   if ($_.sender -eq "") {
      write-host "NDR Found"
      $ndrcount++
   }
   if ($_.source -eq "Storedriver" -and $_.eventid -eq "deliver") {
      write-host "IN Mail"
      $incount++
      $insize += $_.totalbytes
   }
   elseif ($_.source -eq "SMTP" -and $_.eventid -eq "SEND" -and $_.connectorid -ne "Intra-Organization SMTP Send Connector") {
      write-host "OutMail"
      $outcount++
      $outsize += $_.totalbytes
   }
}
 
$prtgresult = '<?xml version="1.0" encoding="UTF-8" ?>
<prtg>
   <result>
      <channel>NDR Count</channel>
      <value>'+$ndrcount+'</value>
      <float>0</float>
   </result>
   <result>
      <channel>Anzahl eingehende Mail</channel>
      <value>'+$incount+'</value>
      <float>0</float>
   </result>
   <result>
      <channel>KBytes eingehend</channel>
      <value>' + [math]::round($insize/1024) + '</value>
      <float>0</float>
   </result>
   <result>
      <channel>Anzahl ausgehende Mail</channel>
      <value>'+$outcount+'</value>
      <float>0</float>
   </result>
   <result>
      <channel>KBytes ausgehend</channel>
      <value>' + [math]::round($outsize/1024) + '</value>
      <float>0</float>
   </result>
</prtg>'


#$prtgresult 

write-host "Sending Data"
$Answer=Invoke-Webrequest `
   -method "GET" `
   -URI ("http://prtg.msxfaq.net:5050/12345678?content=$prtgresult")
if ($answer.Statuscode -ne 200) {
   write-warning "Request to PRTG failed"
   exit 1
}
write-host "done"

Das Skript muss natürlich in Exchange PowerShell gestartet werden und enthält kein Logging, kein Alerting und auch keinen Taskplaner. Es soll als Muster aber zeigen, wie einfach per Skript ein paar Statistiken (Anzahl NDRs, eingehende und ausgehende Mails mit Anzahl und Größe) erfasst und an PRTG gemeldet werden können.

HTTP-Push mit IoT und CURL

Kennen Sie NodeMCU und die Programmierung mit LUA?. Wenn nein, dann sollten sie mal einen Blick auf NodeMCU und andere "IoT-Devices" richten. Diese Geräte nutzen natürlich kein Windows, so dass die Installation einer PRTG-Probe nicht möglich ist. Aber die Geräte sind auch nicht immer "wach" und mit einer festen IP-Adresse versehen, sondern haben eine dynamische IP-Adresse, verbergen sich hinter einem NAT-Router und wachen nur alle paar Minuten auf um ihren Status zu melden. Damit scheidet auch die aktive Abfrage durch eine Probe auf einem anderen System aus. Für diese Fälle ist ein HTTP-Push-Sensor einfach genial.

Eine entsprechende Seite auf Basis von NodeMCU und PRTG ist in Vorbereitung.

HTTP-Push mit Unix (CURL und CronTab)

Viele IoT Systeme nutzen im Innersten ein UNIX-Derivat und meist ist CURL verfügbar, ein Kommandozeilen-Tools zum Abfragen von URL. Wie ich auf SSH-Sensor ist ein HTTP-Push-Sensor auch eine Option für Systeme, die kein SSH können oder dürfen. Hier ein Beispiel eines Aufrufs um einen Wert per sysctl zu lesen und per curl an PRTG zu senden.

Beachten Sie, dass ein "?" ein Platzhalter ist und ein & als Verkettung von Befehlen gilt. Sie müssen diese Zeichen in der URL entsprechend ein "\" voranstellen. Der unter Windows liebgewonnene Backslash "\" muss aber zu einem "/" werden. Für einen Start mit CURL als Task sollten sie die Pfade absolut angegeben.

Ein Beispielskript könnte wie folgt aussehen:

#!/bin/sh
 
wert=$(sysctl -n dev.amdtemp.0.core0.sensor0``| tr -d C)
/usr/local/bin/curl http://prtg.example.com:5050/temp-pfsense\?value=$wert\&text=OK

Das Skript müssen Sie nur noch per CRON regelmäßig starten. Folgender Eintrag startet einen Echo alle 5 Minuten

*/5 * * * * /home/prtg/push.sh

Eventuell müssen Sie nach Änderungen den Crontab neu starten.

/etc/init.d/crond restart

Sie müssen dann nur ein paar Durchläufe abwarten, bis PRTG die Daten nach und nach als Grafik aufbauen kann:

Was mir fehlt

Damit die Story aber perfekt wird, sollte Paessler möglichst schnell noch ein paar Dinge nachrüsten:

  • Zeitpunkt der Messung.
    Es wäre es aus meiner Sicht sehr nützlich, wenn man PRTG über die XML-Datei nicht nur die Werte übergeben könnte, sondern auch den Zeitpunkt der Messung. So könnte ein Gerät auch nach einer Verbindungsunterbrechung die zwischengespeicherte Daten nachreichen. Aktuell protokolliert PRTG die erhaltenen Daten immer als "Echtzeit", d.h. der Zeitpunkt des Empfangs ist auch der Zeitpunkt im Diagramm. Damit scheidet jede Möglichkeit aus, Daten von früher nachträglich einzuspeisen. für den Client ist es beim HTTP-Request kein Problem zu erkennen, dass die Versendung nicht erfolgreich war. Es kommt dann einfach kein "200 OK" von PRTG zurück. für jeden etwas pfiffigen Programmierer sollte es aber kein Problem sein, die zu meldenden Werte irgendwo temporär zu speichern und einfach beim nächsten Versuch den Request zu wiederholen.
    Dazu müsste aber PRTG den Zeitstempel nicht anhand des aktuellen Empfangszeitpunkts festmachen, sondern eben aus den Nutzdaten extrahieren.
  • Meldung und Addieren neuer Sensoren
    Ich fände es auch interessant, wenn ein Device per HTTP-Push Daten liefert aber in PRTG kein passender Sensor vorhanden ist. Dieser Event sollte in PRTG sichtbar werden, so dass ein Administrator sehr schnell fehlende Sensoren addieren kann. Das würde auch etwas Plug&Play erlauben.
  • Bessere Rückmeldungen
    Es ist in Ordnung, wenn die JSON-Antwort die Anzahl der Sensoren liefert und man so prüfen kann, dass es einen "Match" gibt. Wenn die Nutzdaten aber nicht zu verarbeiten sin, sollte bitte kein "OK" drin stehen sondern eine aussagekräftige Fehlermeldung.

Vielleicht baue ich mir selbst dazu einen HTTPS-Listener, der die Daten dann 1:1 per HTTP an PRTG weiter gibt. Der könnte dann auch gleich den "Ungültige Token"-Meldung abfangen und melden.

Weitere Links