PRTG und MQTT

Ich hoffe ja noch, dass diese Seite bald überflüssig wird, wenn Paessler einen MQTT-Support direkt als Client oder Server einbaut. Aber solange in PRTG solche Funktionen fehlen und eigene Sensoren per MQTT kommunizieren, baut man sich halt selbst eine Brücke.

PRTG Node-RED-Connector
https://www.paessler.com/tools/prtg-node-red-connector
Sendet Daten aus NodeRED per HTTP Push an PRTG

Auf der Roadmap von PRTG gibt es schon was zu MQTT

https://www.paessler.com/prtg/roadmap

Das Problem mit MQTT und PRTG

Bei Einsatz von MQTT und PRTG gibt es besondere Herausforderungen, warum auch meine Lösung die ein oder andere Einschränkungen hat

  • MQTT ist Realtime
    d.h. ein MQTT-Client sendet Daten an den MQTT-Broker, welcher diese in der Regel sofort an einen "Subscriber" weiterleitet. Es gibt normal keinen Status oder Puffer. Wenn ein Subscriber nicht da ist, dann übersieht er etwas. Ja, man kann Werte als Client auch so senden, dass diese beim Broker vorgehalten werden und dann ein Subscriber auch nachträglich den letzten Werte bekommt. Das muss aber der Client beim Absendern schon vorgeben und der Broker muss den Speicher vorhalten.
  • MQTT sind Einzelmeldungen
    Solange ein MQTT Wert auch genau zu einem PRTG-Sensor passt, könnte man das einfach machen. Aber wenn der PRTG-Sensor mehrere Kanäle hat, dann wäre ein Check oder ein Push für jeden einzelnen Kanal kontraproduktiv. Hier müsste man also etwas Daten "sammeln", damit PRTG dann einen kompletten Datensatz bekommt. Das kann natürlich auch ein Problem für PRTG selbst werden, da ein Sensor die Daten nicht immer vom MQT Broker als Gruppe "Abfragen" kann.
  • Es kann nur einen MQTT-Broker geben
    Natürlich können Sie mehrere MQTT-Broker in ihrem Netzwerk installieren aber die meisten Sensoren und Aktoren können nur einen Broker ansteuern. Daher ist es unwahrscheinlich, dass Sie PRTG als Broker aufsetzen. PRTG oder ein Helper muss also als Subscriber arbeiten. Meist hat ein System aus Broker und Service auch aktive Funktionen, z.B. auf bestimmte Eingabedaten wieder Aktionen zu triggern. Da will ich gar nicht eingreifen.

Mit diesen Vorüberlegungen haben ich mir dann verschiedene Ansätze überlegt und einen davon implementiert.

Im unteren Teil gibt es zwei PowerShell-Skripte, die als MQTT-Subscriber Daten von einem MQTT Broker lesen und per HTTP Push-Sensoren an PRTG senden.

MQTT Ecosystem

MQTT besteht aus Komponenten, die Daten erfassen und senden und mindestens einer zentralen Stelle, die diese Meldungen annimmt und verarbeitet. Zudem gibt es Teile, die solche Daten wieder auslesen und z.B. anzeigen oder anders reagieren.

Bei MQTT haben sich folgende Begriffe dafür etabliert.

  • Publisher
    Ein klassischer Publisher erfasst Temperatur, Wind, Energie, Licht, Präsenz, Durchfluss u.a. Werte, die es an einen zentrale Stelle sendet
  • Broker
    Der Broker sammelt all diese Daten ein und kann basierend darauf auch Aktionen auslösen. Der Broker kann auch "befragt" werden
  • Subscriber
    Dieser Prozess liest Daten aus, um diese z. B. anzuzeigen

Natürlich kann ein Publisher auch zugleich Subscriber sein, d.h. er kann Daten senden (z.B. Temperatur, Stromverbrauch, Präsenz), aber auch zugleich Befehle (Schalten, Dimmen) annehmen.

PRTG macht noch kein MQTT

Natürlich könnte PRTG selbst ein Broker sein und per MQTT direkt Meldungen annehmen und in seine Datenbank übernehmen. Das klingt erst mal nicht schlecht und würde zusätzliche Dienste ersparen Aber wer es sich genau überlegt wird diesen Weg gar nicht gehen wollen, da der Broker ja durchaus auch andere Dinge übernehmen kann und vielleicht auch soll. Es gibt viele gute Broker und es wäre vermessen von Paessler zu erwarten, dass Sie einen MQTT-Broker in ihr Produkt einbauen. Da viele MQTT-Clients auch nur genau einen Broker unterstützen, wäre auch eine Integration in andere Dienste unmöglich.

Insofern bin ich Paessler nicht böse, dass Sie kein MQTT Broker sind. Aber da mein MQTT-Server durchaus "Messwerte" verarbeitet, die ich nicht nur mit NodeRed und anderen Tools aufzeichnen möchte, wünsche ich mir einen MQTT-Subscriber. Also mache ich ihn mir selbst.

PRTG als Subscriber

PRTG als Monitoring-Lösung ist bislang keine aktive Komponente in einem Prozess sondern steht quasi "daneben" und schaut zu. Für MQTT bedeutet das, dass PRTG einfach einen bestehenden Broker nutzt und die Daten anzapft.

Ich sehe PRTG hier eher in der Rolle des Subscribers, um sich Werte, die von einem Publisher im Broker hinterlegt werden, wieder auszulesen. Das klassische MQTT-Modell nutzt eigentlich kein "Polling", sondern der Subscriber hält die Verbindung offen, so dass der Broker auch eine Meldung zurück senden kann. Aber da Smartphones u.a. Geräte natürlich auch immer mal wieder "Strom sparen" ist es möglich, auch Daten immer wieder abzufragen. Ein passender Sensor in PRTG könnte die Daten also auch abfragen. Würde die MQTT-Funktion aber in der permanent aktiven Probe implementiert sein, dann könnte diese auch neue Werte direkt bekommen und in die PRTG-Datenbank einbauen. Quasi so, wie HTTP Push-Sensoren dies tun. Wenn es nur um die Erfassung von Daten gibt, könnte PRTG natürlich irgendwann auch selbst auf Port 1883/TCP oder 8883/TLS lauschen und einfach die "Publish"-Befehle annehmen und weiter leiten.

Da es beide Funktionen noch nicht gibt, wäre also wieder ein selbst entwickelter Sensor als Skript zu überlegen. Damit die PRTG-Probe nun nicht so viel durch den dauernden Aufruf von PowerShell-Skripten belastet wird, und ein Debugging in einer Konsole deutlich einfacher ist, bin ich erst mal den Weg über ein "Dauerskript" gegangen, welches die Werte selbst holt und per HTTPPush an PRTG meldet. Dieses Verfahren skaliert auch besser für viele MQTT Sensoren.

Allerdings müssen Sie beachten, dass MQTT-Broker die Daten nur dann speichern, wenn der Publisher dies auch wünscht. Auch das Wegbrechen eines Publishers wird vom Broker nur dann an die Subscriber gemeldet, wenn der Publisher einen "LastWill" hinterlegt hat.

Für meinen eigene Überlegungen bedeutet das gleich mehrere Besonderheiten.

  • Nach dem Start kann ich keine Daten abfragen.
    Wenn der Publisher keine "Retained Message" verwendet, dann muss ich auf neue Meldungen warten
  • Kein Zeitstempel
    Selbst wenn der Publisher eine "Retained Message" verwendet, so gibt es keinen Zeitstempel. Ich hätte dann zwar einen Messwert aber keine Information, wie akkurat er ist. Dann lasse ich lieber den Wert direkt zu PRTG senden und vertraue PRTG drauf, dass er ausbleibende Meldungen als Fehler meldet.
  • Nur ein Messwerte pro Push
    PRTG-Sensoren können mehrere Kanäle haben. Eine MQTT-Message liefert in der Regel erst mal nur ein Wert, auch wenn natürlich die Payload alles mögliche sein kann. Die meisten Publisher nutzen bei mehreren Werten aber lieber mehrere Chanels. In der ersten Version würde ich eine 1:1 Zuordnung annehmen. Später könnte ich ja mehrere Werte des gleichen Baums" in einem Sensor zusammen fassen. Man müsste dann nur Werte sammeln und nach einiger Zeit oder der Ankunft des letzten Werts senden. Das würde natürlich etwas Sensoren sparen.
  • LastWill würde ich vernachlässigen
    Wenn ein Publisher "offline" geht und einen LastWill hinterlegt hat, dann bekommen dies die Subscriber mit wie eine normale Message mit. Wenn Sie verarbeitet werden kann, dann wird sie wie eine normale Message behandelt und ausbleibende Werte werden von PRTG dann festgestellt und ggfls. alarmiert.
  • Content Conversion
    Nicht jeder wert, der von MQTT-Server kommt, kann von PRTG so 1:1 übernommen werden. Eine gewisse "Konvertierungsfunktion müsste in dem Skript enthalten sein.

Die Anforderungen sind also schon nicht gerade in einem PowerShell-Einzeiler zu schaffen.

PRTG als Publisher

Aber auch umgekehrt ist eine Anbindung denkbar. Wie wäre es, wenn PRTG seinen globalen Status oder den ausgewählter Sensoren per MQTT an einen Broker meldet? Es sind ja "auch nur Werte". So könnte ein Verbindung von unterschiedlichen Systemen auch in die Gegenrichtung erfolgen. Es gibt ja durchaus Informationen in PRTG wie z.B. der Status von Geräten, die sich ändern. So eine Änderung könne ja direkt an einen MQTT-Broker gesendet werden, so dass andere Subscriber diese Daten auswerten können.

Auch diese Anbindung ist natürlich auch ohne direkte Unterstützung on PRTG auch heute schon möglich. Über die PRTG-API kann ein regelmäßig gestartetes Skript die gewünschten Daten aus PRTG auslesen und überall hin senden. Dieses Skript könnte selbst als "PRTG-Sensor" laufen, welcher als Rückgabe eben nur einen Status meldet. So können Sie die Funktion dieses Exports direkt in PRTG selbst überwachen und PRTG quasi als "Scheduler" nutzen.

MQTT2PRTG-Simple

Was es nicht gibt, kann man auch selbst machen. Da ich auf der Seite Powershell und MQTT schon ein paar Vorarbeiten für die Nutzung von MQTT per PowerShell gemacht habe, ist es auch nicht sonderlich schwer, einen passenden Sensor oder ein passendes Skript zu erstellen. Ich habe dort aber auch beschrieben, dass man Werte von einem Broker nur erhält, wenn der Publisher diese dann gerade sendet oder die vorige Meldung als "Retained Message" gekennzeichnet hat.

Hinweis: Mit einem regelmäßig gestarteten Skript als Sensor können Sie nur MQTT-Daten abrufen, die vom Publisher als "Retained Message" gesendet wurden. Ansonsten müsste das Skript auf neue Daten "warten". Wir brauchen also einen dauernd laufenden Prozess um die Werte per MQTT zu sammeln. Das PowerShell-Script sollten Sie also als ""geplanten Task" einfach starten.

Diese Script ist sehr einfach aufgebaut und benötigt nur den PRTG-Server und MQTT-Server als Parameter. Es macht dann einen "SUBSCRIBE" auf alle Kanäle des MQTT-Servers  ("#") und leitet jede Meldung 1:1 unverändert an PRTG weiter.

Das bedeutet

  • Der MQTT-Kanalname ist zugleich die PRTG Push GUID
  • Der MQTT Value ist zugleich der Wert für PRTG
    d.h. es gibt keinen Sensor mit mehreren Kanälen und es gibt keine Wert-Konvertierung oder Umrechnung
  • Skaliert nur bedingt
    Sie sollten dieses Script nur in Verbindung mit einem "mäßig belasteten MQTT-Broker" einsetzen, da wirklich jede Meldung zu PRTG geht. PRTG verwirft diese natürlich aber mehrere unwichtige Messages pro Sekunde müssen nicht wirklich sein.

Dafür ist natürlich der Einsatz und die Konfiguration trivial.

Das Skript nutzt die Library "M2Mqtt.Net.dll", die ist per PowerShell und NUGET einfach installieren können
Install-Package M2Mqtt
Siehe dazu auch Powershell und MQTT

Achtung: Das Skript macht einen Subscribe "#" auf alle Kanäle und sendet diese auch alle an PRTG. Es ist also eher ein Proof of Concept für eine kleine Umgebung mit wenigen MQTT-Topics und bei dem jeder Topic auch ein Sensor in PRTG ist.

Sie müssen das Skript nur über einen Taskplaner automatisch aufrufen.

mqtt2prtg-simple.20181003.ps1

Da alle MQTT-Kanäle umgesetzt werden, müssen Sie keine Konfiguration anpassen, wenn der MQTT-Broker weitere Werte liefert, z.B. weil Sie ihr IoT-Projekt erweitert haben. Wenn Sie aber etwas mehr filtern und Zusammenfassen wollen, dann ist das nächste Skript vielleicht den Aufwand wert.

MQTT-Brücke für PRTG

Ich nehme hier schon mal vorweg, dass mir die "Simple" Anbindung natürlich nicht gefällt und ich an einer erweiterten Funktion arbeite.

PRTG und MQTT in Zukunft?

Sie haben sicher gemerkt, dass viele Dinge, die PRTG heute tut und MQTT sich überlappen. PRTG hat natürlich einige Komponenten, die in MQTT so nicht definiert sind. MQTT ist ja auch "nur" ein Übertragungsprotokoll zwischen zwei Endpunkten während PRTG eine komplette leistungsfähig Lösung ist. Aktuell nutzt die Probe ihren eigenen Kanal, um mit dem PRTG-Core zu kommunizieren. Über diesen Kanal werden gemessene Daten und Konfigurationseinstellungen übertragen. Genau das könnte aber auch per MQTT erfolgen. Das bedeutet nicht, dass PRTG das machen müsste. Der vorhandene Weg funktioniert ja.

Weitere Links