Hardware Monitoring im lokalen Netz

Hallo zusammen,

neben dem schönen HostMonitor Modul würde ich gerne den Hardware-Status (CPU Temperaturen, Auslastung, Plattenplatzbelegung, Netzwerklast etc.) verschiedener Geräte (im Wesentlichen Windows PCs) mit IPS überwachen.

Gibt es einen Ansatz, den ich verfolgen könnte? Bin hier nur auf ältere Versuche gestoßen, die ein externes SNMP Tool unter Windows verwenden, mein IPS läuft aber unter Ubuntu.

Finde den Gedanken ganz reizvoll, und es wäre mir lieber als zu Third Party Tools (z.B. check_mk) zu greifen.

Danke und Gruß
micheljarre

Moin!

Krasse Lösung > Nagios

SNMP funktioniert auch (sogar noch besser) unter Linux (Ubuntu).

Für Windows Maschinen gäbe es noch WMI.

Also ich würde SNMP vorschlagen, das ist schnell und problemlos zu verwenden und belastet das Netzwerk nicht, selbst bei einer hohen/schnellen Abfragerate :cool:

Grüße,
Chris

Hallo,

kommt drauf an, ob die Windows Maschinen 24/7 laufen. Ich hab Icinga2 laufen ( Nagios Fork ) , macht aber nur Sinn für 24/7 Maschinen, sonst bekommt man in der Downzeit jede Menge Fehler. SNMP und Co geht damit aber wie Chris schon sagt, krasse Lösung die nicht mal eben in 2h konfiguriert ist. Ich übergebe die Daten per API dann ins IPS. Werte aber z.b. nur Updatestatus, Dienststatus , Festplatten - „Füllstand“ und paar Temperaturen aus. Cool ist aber z.b. das man sich so push Nachrichten schicken kann, wenn Alarm anliegt ( sollte man nur nicht übertreiben ).

Thomas

Für Win 24/7 gibt es da auch PRTG.
Kann so ziemlich alles und jedes abfragen/über wachen und mit 100 Sensoren kostenfrei sollte man auskommen.
Dank des ‚Guru‘ ist ein Großteil in ein paar Minuten eingerichtet.
Michael

PRTG taugt auch zur Überwachung von sporadisch eingeschalteten Geräten, sofern IPS am Ein-/Asuschalten beteiligt ist. Sensoren lassen sich einfach per http Request pausieren…

Ja die API ist wirklich brauchbar. Sogar mit Graphen :smiley:
Allerdings habe ich das nie zur ‚Serienreife‘ gebracht. Naja vielleicht das nächste Herbst-PHP-Modul :wink:


Michael

Wenn du die OIDs der gewünschten Parameter kennst bzw. suchst, dann kannst du auf der *nix Maschine auch folgendes Script nutzen. Stammt aus dem Forum, ich habe es „nur“ rudimentär für die Nutzung auf meinem PI angepasst.

Im IPS eine Kategorie anlegen, darunter das Script, parallel zum Script werden die Variablen erzeugt. DIe Grafiken kannst du dann auch im IPS erzeugen ;).

Aber die gewünschten OIDs musst du anpassen, dieses Beispiel fragt mein QNAP Storage ab.


<?
// *****************************************************************************
// ** Script zum Auslesen der MIB von SNMP Server
// ** Die Idee stammt von hardlog aus dem Symcon Forum (https://www.symcon.de/forum/threads/26977-Status-der-Synology-DS-per-Script-auslesen?p=247930#post247930)
// ** läuft so nur unter Windows, da das Komandozeilenprogramm "ssmnpq.exe"
// ** benötig: genanntes Programm hier http://www.digigrupp.com/ssnmpq/ downloaden
// ** in einen beliebigen Ornder entpacken und den Ornder in diesem Script
// ** entsprechend anpassen
// ** Bei NAS-Servern wie Synology / QNAP muss der SNMP-Dienst aktiviert werden.
// ** Den Standardport am SNMP Server bitte nicht ändern.
// **
// ** Dieses Skript funktioniert folgendermaßen:
// ** Du konfigurierst, welche Werte deines SNMP Servers du gerne auslesen,
// ** möchtest (siehe "registerSNMPObj" weiter unten).
// ** Das Skript wird den Datentyp der SNMP Daten ermitteln und als IPS-Variablen
// ** unterhalb des Skriptes anlegen (sofern diese nicht bereits existieren.)
// ** Der Name der Variable entspricht der von dir benannten "Beschreibung" für
// ** den SNMP-Wert.
// ** Die Werte der Variablen werden mit jeder Ausführung des Skripts aktualisiert.
// **
// ** Das Skript legt benötigte Variablenprofile an. Diese sind mit einem Präfix
// ** "SNMP_" versehen. Beispielsweise "SNMP_CapacityMB".
// *****************************************************************************

/**
KONFIGURATION der SNMP Verbindung
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**/
$host          = "172.16.xxx.xxx"; 	// IP Adresse deines SNMP Servers (QNAP, Synology, etc.)
$community     = "yyy";				// SNMP Community
$binary        = "snmpget";			// Pfad zum SNMP Binary
$debug         = false;					// Bei true werden Debuginformationen (echo) ausgegeben

$snmp = new SNMP($host, $community, $binary, $debug);          //DIESE ZEILE NICHT VERÄNDERN!

/**
KONFIGURATION abzurufender Werte
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

mit $snmp->registerSNMPObj($oid, $desc, $convertType) kannst du angeben,
welche Daten per SNMP abgerufen werden sollen.
Die Funktion benötigt drei Parameter:

Parameter1 ($oid):
------------------
die ID des Wertes am SNMP Server (Mit dem iReasoning MIB Browser kannst du mit
einem Windowsprogramm angenehm nach gültigen ID's in deinem System suchen.
http://www.ireasoning.com

Die vorbelegten OIDs basieren auf den Werten meiner QNAP und müssen evtl.
angepasst werden.

Parameter2 ($desc):
-------------------
Die Bezeichnung legt fest, wie die IPS-Variable genannt werden soll.

Bitte berücksichtige, dass jede OID und jede Bezeichnung eindeutig sein müssen
(keine doppelten Einträge). Ausserdem löscht das Skript keine einmal erstellten
Variablen. D.h. wenn du eine Bezeichnung umbenennst, denn musst du die "alte"
Variable manuell löschen.

Parameter 3 (convertType)
-------------------------
dieser Parameter ist optional. Wird er nicht gesetzt oder als "none" übergeben,
werden die Daten "wie empfangen" in der zugehörigen IPS-Variable gespeichert.

In einigen Fällen ist dies jedoch nicht erwünscht. Beispielsweise liefert eine
QNAP als freie Festplattenkapazität den Wert inkl. der Mengeneinheit als Text:
3.96 TB. Damit ist eine geeignete Weiterverarbeitung in IPS sowie ein Logging
der Variable ausgeschlossen.

Um das zu ändern beinhaltet das Skript einige "Converter". In diesem Fall auf
die Rohdaten der QNAP abgestimmt. Der Converter "Capacity" wandelt MB/GB/TB
(Megabyte, Gigabyte, Terrabyte)-Strings in Megabyte Zahlen um.
Aus "3.96 TB" werden "3960000".

Derzeit verfügbare Converter:
CapacityMB (Speichergrößen in Megabyte als Float)
CapacityGB(Speichergrößen in Megabyte als Float)
CapacityTB (Speichergrößen in Megabyte als Float)
Temperature (Celsius Temperatur als Integer)
FanSpeed (RPM als Integer)
SmartStatus (S.M.A.R.T Informationen der HDD, Ergebnis ist Boolean => gut / schlecht)

**/

$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.12.0", "ModelName");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.2.0", "SystemTotalMem", "CapacityMB");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.3.0", "SystemFreeMem", "CapacityMB");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.17.1.4.1", "SysVolumeTotalSize", "CapacityGB");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.17.1.5.1", "SysVolumeFreeSize", "CapacityGB");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.4.0", "SystemUptime");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.5.0", "CPU-Temperature", "Temperature");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.6.0", "System-Temperature", "Temperature");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.15.1.3.1", "System-FanSpeed", "FanSpeed");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.11.1.3.1", "HDTemperature1", "Temperature");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.11.1.3.2", "HDTemperature2", "Temperature");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.11.1.3.3", "HDTemperature3", "Temperature");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.11.1.3.4", "HDTemperature4", "Temperature");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.11.1.7.1", "HDSmartInfo1", "SmartStatus");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.11.1.7.2", "HDSmartInfo2", "SmartStatus");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.11.1.7.3", "HDSmartInfo3", "SmartStatus");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.11.1.7.4", "HDSmartInfo4", "SmartStatus");
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.1.0", "CPU usage", "Percent");

// ***** ab hier nichts mehr ändern
$snmp->update();

class SNMP
{
    //Objekteigenschaften
    protected $host;                   //SNMP Serveradresse
    protected $community;              //SNMP Community
    protected $binary;                 //Dateipfad zur ssnmpq.exe
    public	  $debug = false;          //Bei true werden Debuginformationen ausgegeben
    protected $snmpobj=array();        //array registrierter snmp objekte welche beim server abgefragt werden

    //IPS Datentypen
    const tBOOL     = 0;
    const tINT      = 1;
    const tFLOAT    = 2;
    const tSTRING   = 3;

    public function __construct($host, $community, $binary, $debug) {
        $this->host         = $host;
        $this->community    = $community;
        $this->binary       = $binary;
        $this->debug        = $debug;


        //Prüfe ob Variablenprofile existieren und erstelle diese wenn nötig
        $this->createVariableProfile("SNMP_Percent", self::tFLOAT, "", " %", 2);
        $this->createVariableProfile("SNMP_CapacityMB", self::tFLOAT, "", " MB", 0);
        $this->createVariableProfile("SNMP_CapacityGB", self::tFLOAT, "", " GB", 0);
        $this->createVariableProfile("SNMP_CapacityTB", self::tFLOAT, "", " TB", 0);
        $this->createVariableProfile("SNMP_Temperature", self::tINT, "", " °C", 0);
        $this->createVariableProfile("SNMP_FanSpeed", self::tINT, "", " RPM", 0);
        if (!IPS_VariableProfileExists("SNMP_SmartStatus")) {
            $this->createVariableProfile("SNMP_SmartStatus", self::tBOOL, "", "", 0);
            IPS_SetVariableProfileAssociation("SNMP_SmartStatus", 1, "Gut", "", 0x00FF04);
            IPS_SetVariableProfileAssociation("SNMP_SmartStatus", 0, "Defekt", "", 0xFF0000);
        }
    }

    private function createVariableProfile($name, $type, $pre, $suff, $digits) {
        if (!IPS_VariableProfileExists($name)) {
            if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "INFO - VariablenProfil ".$name." existiert nicht und wird angelegt.");
            IPS_CreateVariableProfile($name, $type);
            IPS_SetVariableProfileDigits($name, $digits);
            IPS_SetVariableProfileText($name, $pre, $suff);
        }
    }

    public function registerSNMPObj($oid, $desc, $convertType = "none") {

        //prüfe auf doppelte Einträge beim Registrieren neuer SNMP Objekte
        foreach($this->snmpobj as $obj) {
            if ($desc==$obj->desc) {
                if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "ERROR - registerSNMPObj: Variable description ".$desc." already exists, it must be unique!");
                exit;
            }
            if ($oid==$obj->OID) {
                if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "ERROR - registerSNMPObj: Variable OID ".$oid." already exists, it must be unique!");
                exit;
            }
        }

        //prüfe ob IPS Variablen für SNMP Objekt existiert (Variablenname entspricht description)
		$parentID = IPS_GetParent($_IPS['SELF']); // übergeordnete Kategorie als Basis
//        $parentID = $_IPS['SELF'];
        $ips_var = @IPS_GetVariableIDByName($desc, $parentID);
        if ($ips_var == false) {
            if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "Variable ".$desc." not found - create IPSVariable");

            if ($convertType == "none")
	            $type = $this->getSNMPType($oid);
            if ($convertType == "CapacityMB" || $convertType == "CapacityGB" || $convertType == "CapacityTB" || $convertType == "Percent")
   	         $type = self::tFLOAT;
            if ($convertType == "Temperature")
      	      $type = self::tINT;
            if ($convertType == "FanSpeed")
         	   $type = self::tINT;
            if ($convertType == "SmartStatus")
            	$type = self::tBOOL;
            if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "Type of OID ".$oid." is ".$type);

            $ips_var = IPS_CreateVariable($type);
            IPS_SetName($ips_var, $desc);
            IPS_SetParent($ips_var, $parentID);

            //Verknüpfe Variablenprofil mit neu erstellter Variable
            if ($convertType == "CapacityMB")
   	         IPS_SetVariableCustomProfile($ips_var, "SNMP_CapacityMB");
            if ($convertType == "CapacityGB")
	            IPS_SetVariableCustomProfile($ips_var, "SNMP_CapacityGB");
            if ($convertType == "CapacityTB")
            	IPS_SetVariableCustomProfile($ips_var, "SNMP_CapacityTB");
            if ($convertType == "Temperature")
         	   IPS_SetVariableCustomProfile($ips_var, "SNMP_Temperature");
            if ($convertType == "FanSpeed")
      	      IPS_SetVariableCustomProfile($ips_var, "SNMP_FanSpeed");
            if ($convertType == "SmartStatus")
   	         IPS_SetVariableCustomProfile($ips_var, "SNMP_SmartStatus");
            if ($convertType == "Percent")
	            IPS_SetVariableCustomProfile($ips_var, "SNMP_Percent");
        }

        $count = count($this->snmpobj);
        array_push($this->snmpobj, new SNMPObj($oid, $desc, $convertType, $ips_var));
        $count = count($this->snmpobj);
        if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "New SNMPObj registered, now monitoring ".$count." snmp variables");
    }

    //startet eine Abfrage am SNMP Server und aktualisiert die IPS-Variablen der registrierten
    //SNMP Objekte
    public function update() {
        if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "Updating ".count($this->snmpobj)." variable(s)");

        foreach ($this->snmpobj as $obj) {
//            $oid = ltrim($obj->OID,".");
            $oid = $obj->OID;
            $exec_param =" -v1 -O vq -c ".$this->community." ".$this->host." ". $oid ."";
            if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "Execute SNMP-Query: ".$this->binary.$exec_param);
            $obj->value = str_replace('"', '', trim(system($this->binary.$exec_param)));

            if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "Result of ".$obj->desc.": ".$obj->value);

            if ($obj->convertType == "Percent") $obj->value = $this->convertPercent($obj->value, "%");
            if ($obj->convertType == "CapacityMB") $obj->value = $this->convertCapacity($obj->value, "MB");
            if ($obj->convertType == "CapacityGB") $obj->value = $this->convertCapacity($obj->value, "GB");
            if ($obj->convertType == "CapacityTB") $obj->value = $this->convertCapacity($obj->value, "TB");
            if ($obj->convertType == "Temperature") $obj->value = $this->convertTemperature($obj->value);
            if ($obj->convertType == "FanSpeed") $obj->value = $this->convertFanSpeed($obj->value);
            if ($obj->convertType == "SmartStatus") $obj->value = $this->convertSmartStatus($obj->value);

            SetValue($obj->ips_var, $obj->value);
        }
    }

    //prüfe um welchen SNMP Rückgabetyp es sich handelt
    //returns 3 => String / 1 => Integer / 2 => Float
    private function getSNMPType($oid) {
        $oid = ltrim($oid,".");
        $exec_param =" -v1 -O v -c ".$this->community." ".$this->host." ". $oid;
        $result = system($this->binary.$exec_param);
        $pos_start = stripos ($result, " = ");
        $pos_end = stripos ($result, ': "');
        $type = substr($result, $pos_start, $pos_end - $pos_start);
        switch($type) {
            case "STRING":
            	return self::tSTRING;
            case "Integer":
            	return self::tINT;
            case "Timeticks":
            	return self::tFLOAT;
            default:
            	return self::tSTRING;
        }
    }

    //returns -1 on error
    private function convertCapacity($input, $unit) {
        $pos = stripos($input, "MB");
        if ($pos === false) {
            $pos = stripos($input, "GB");
            if ($pos === false) {
                $pos = stripos($input, "TB");
                if ($pos === false) {
                    return -1;
                } else {
                    $funit = "TB";
                }
            } else {
                $funit = "GB";
            }
        } else {
            $funit = "MB";
        }

        $result = substr($input, 0, $pos);
        $result = trim($result);

        switch ($funit) {
            case "GB":
            $result = $result*1000;
            break;
            case "TB":
            $result = $result*1000*1000;
            break;
        }

        switch($unit) {
            case "MB":
            return round($result);
            case "GB":
            return round($result / 1000);
            case "TB";
            return round($result / 1000000);
        }
    }

    //returns -1 on error
    private function convertTemperature($input) {
        $pos = stripos($input, "C");
        if ($pos === false) {
            $result = -1;
        } else {
            $result = substr($input, 0, $pos);
            $result = round(trim($result));
        }
        return $result;
    }

    private function convertPercent($input) {
        $pos = stripos($input, "%");
        if ($pos === false) {
            $result = -1;
        } else {
            $result = substr($input, 0, $pos);
            $result = trim($result);
        }
        return $result;
    }

    //returns -1 on error
    private function convertFanSpeed($input) {
        $pos = stripos($input, "RPM");
        if ($pos === false) {
            $result = -1;
        } else {
            $result = substr($input, 0, $pos);
            $result = round(trim($result));
        }
        return $result;
    }

    private function convertSmartStatus($input) {
        $pos = stripos($input, "GOOD") + stripos($input, "Normal");
        if ($pos === false) {
            return false;
        } else {
            return true;
        }
    }

}

class SNMPObj
{
    //Objekteigenschaften
    public $OID;                   //SNMP Message ID
    public $desc;                  //Beschreibung
    public $value;                 //Wert
    public $convertType;           //Typ-Converter
    public $ips_var;               //ID der IPS-Variable welche den SNMP Wert speichert

    public function __construct($OID, $desc, $convertType, $ips_var) {
        $this->OID            = $OID;
        $this->desc           = $desc;
        $this->convertType    = $convertType;
        $this->ips_var        = $ips_var;
    }
}
?>

Hallo,

Läuft das Script bei dir schon unter IPS 4.0 ?

Mein altes Script bockt nur noch rum.

Danke für die ganzen Hinweise. Momentan schaue ich mir alles mal an. smnp ist im Grunde genommen ja recht einfach zu holen, allerdings interessieren mich besonders Temperaturinformationen, wie sie beispielsweise von CPUID HWMonitor angezeigt werden. Sowas scheint aber über snmp und Standard Windows Boardmittel nicht zur Verfügung zu stehen.

Ich bleibe am Thema dran…

Mein angepasstes Beispiel ja, PI ist zwangsläufig V4 ;). Es muss auf OS Ebene über apt-get die snmpget Funktionalität installiert werden.

Musste gerade schmunzeln…
Da werden doch glatt meine beiden beruflichen Begleiter als erstes genannt…
PRTG und Nagios (in meinem Fall CHECK_MK) :slight_smile:

Da ich den Vergleich habe/hatte, würde ich ebenfalls PRTG vorschlagen. Für das Heimnetz vollkommen ausreichend.
Der Suchassistent und die sonstigen Assistenten sind umfangreich und sehr einfach zu handhaben.
Man erhält auch durch die erste Netzwerksuche sehr schnell super Ergebnisse.
PRTG stösst nur bei ganz speziellen Dingen an Grenzen, die man zuhause aber nicht hat.

Nagios dagegen und die ganzen Nachkommen (Icinga, Check_MK,…) sind natürlich die 100% Lösungen - benötigen aber viel Zeit!.

P.S. auch in Nagios (Check_MK) kann man selten genutzte Geräte überwachen. (Dafür gibt’s ja die Maintenance)
Die Maintenance kann man in Nagios oder durch das Endgerät selbst Ein/Ausschalten -> Das wäre dann was für IPS.

Hallo mastermind,

habe beruflich auch mit check_mk zu tun. Meine ersten Erkenntnisse zum Thema Hardwaremonitoring im privaten Netz sind aber trotzdem eher „geteilt“.

Zum einen bieten sich zahlreiche Tools an, die mehr oder weniger alle Informationen liefern, die sicherlich auch mit IPS geholt werden könnten. Aber zum anderen ist es so, dass alle diese Tools wieder eine eigene Installation mit entsprechendem Aufwand darstellen (obwohl ich in IPS ja nur einige, wenige Informationen benötige und diese dort archivieren und visualisieren möchte).

Außerdem scheint es auf Grund von Protokoll- und Prozessorspezifika schwierig zu sein, gerade so etwas wie CPU Temperaturen über eine Standard-API anzubieten. Gerade das interessiert mich, weil ich ein lüfterloses System habe und wissen möchte, ob die Temperaturen „im grünen Bereich“ sind.

Gruß
micheljarre

Hallo,

Nö, meiner eher unter Win.

Da läuft das script schon garnicht.
Fängt schon mit solchen Fehlern an

Parse error: syntax error, unexpected ‚alte‘ (T_STRING) in [Hardware\Server / NAS\THNAS-NAS\THNAS_snmp2] on line 59
Abort Processing during Fatal-Error: syntax error, unexpected ‚alte‘ (T_STRING)
Error in Script D:\IP-Symcon\scripts\54825.ips.php on Line 59

Ich muss das mal auf meiner Test-Installation probieren

Deine Frage war, ob es unter 4.0 läuft, mein Hinweis war (PI stand im Beitrag) das es wegen PI zwangsläufig 4.0 sein muss.

Aber PI bedeutet auch Unix, somit also hier speziell angepasst auf die snmpget Version unter Unix.

Das Originalscript sollte doch eigentlich unter Windows laufen, ging doch vorher auch. Dann zeig doch mal dein Script, aber ich kann die 4.0 unter Windows nicht testen.

Jede einzelne Hardware Komponente möchte gerne mit individuellen Tools angesprochen werden. Man hat nun die Wahl, genau diese Tools zu nutzen und für jede Komponente die Auswertung individuell zu programmieren. Das ist der schlankeste Weg, aber auch programmiertechnisch der Aufwendigste. Oder nimmt eine vorhandene universelle Monitoringlösung parallel zu IPS, welche (übrigens ähnlich wie IPS) die Abfragen auf die Hardware hinter einer einheitlichen API verbirgt. Dafür hat man dann alle am Monitoring hängene Komponenten auf einmal im Griff. Icinga zum Beispiel hat im Gegensatz zu Nagios auch eine JSON-API, die man von IPS aus ansprechen kann. Andere Lösungen lesen die Monitoring Ergebnisse aus deren Datenbank.

Tommi

Hallo,

Es läuft !

Frag mich nicht, warum jetzt auf einmal.

Ich habe gerade noch eine IPS-Update durchgeführt und wollte mich dann mal ans Script machen und habs einfach mal gestartet - geht.

Ich habe im Grund nichts viel dran geändert:

  • IP-Adresse
  • community
  • Pfad zum snmpget.exe
  • das Startkommando für die unterschiedlichen Parameter von snmpget.exe angepasst.

oid`s hab ich erst mal gelassen, da ich auch eine QNAP habe, die muss ich jetzt noch erweitern, da meine ein grösseres Modell ist.
Deine liefern bei mir teilweise keine oder unsinnige Werte, das passe ich noch an, hab mir mal eine Liste eine interessanten oid’s der QNAP, meiens Druckers, der Switche, des Servers usw. ausgelesen.

Super Sache, aber ich habe keine Ahnung, was das Problem war :slight_smile:

EDIT: erste Einschränkungen habe ich schon mit meiner QNAP, ich kann die Festplatten nicht einzeln auf SMART-Status oder Temperatur abfragen, sondern nur im Block über alle 8 gleichzeitigt. Da muss ich mir was basteln mit einem Array oder wie auch immer.

Hi Tuxtom007,

Kannst du bitte mal das komplette Script posten?
Ich habe es auch soeben bei meinem QNAP versucht und bekomme mit diesem Skript:

<? 
// ***************************************************************************** 
// ** Script zum Auslesen der MIB von SNMP Server 
// ** Die Idee stammt von hardlog aus dem Symcon Forum (https://www.symcon.de/forum/threads/26977-Status-der-Synology-DS-per-Script-auslesen?p=247930#post247930) 
// ** läuft so nur unter Windows, da das Komandozeilenprogramm "ssmnpq.exe" 
// ** benötig: genanntes Programm hier http://www.digigrupp.com/ssnmpq/ downloaden 
// ** in einen beliebigen Ornder entpacken und den Ornder in diesem Script 
// ** entsprechend anpassen 
// ** Bei NAS-Servern wie Synology / QNAP muss der SNMP-Dienst aktiviert werden. 
// ** Den Standardport am SNMP Server bitte nicht ändern. 
// ** 
// ** Dieses Skript funktioniert folgendermaßen: 
// ** Du konfigurierst, welche Werte deines SNMP Servers du gerne auslesen, 
// ** möchtest (siehe "registerSNMPObj" weiter unten). 
// ** Das Skript wird den Datentyp der SNMP Daten ermitteln und als IPS-Variablen 
// ** unterhalb des Skriptes anlegen (sofern diese nicht bereits existieren.) 
// ** Der Name der Variable entspricht der von dir benannten "Beschreibung" für 
// ** den SNMP-Wert. 
// ** Die Werte der Variablen werden mit jeder Ausführung des Skripts aktualisiert. 
// ** 
// ** Das Skript legt benötigte Variablenprofile an. Diese sind mit einem Präfix 
// ** "SNMP_" versehen. Beispielsweise "SNMP_CapacityMB". 
// ***************************************************************************** 

/** 
KONFIGURATION der SNMP Verbindung 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
**/ 
$host          = "172.168.3.34";     // IP Adresse deines SNMP Servers (QNAP, Synology, etc.) 
$community     = "public";                // SNMP Community 
$binary        = "C:\IP-Symcon\automatic\SnmpGet\SnmpGet.exe";            // Pfad zum SNMP Binary 
$debug         = false;                    // Bei true werden Debuginformationen (echo) ausgegeben 

$snmp = new SNMP($host, $community, $binary, $debug);          //DIESE ZEILE NICHT VERÄNDERN! 

/** 
KONFIGURATION abzurufender Werte 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

mit $snmp->registerSNMPObj($oid, $desc, $convertType) kannst du angeben, 
welche Daten per SNMP abgerufen werden sollen. 
Die Funktion benötigt drei Parameter: 

Parameter1 ($oid): 
------------------ 
die ID des Wertes am SNMP Server (Mit dem iReasoning MIB Browser kannst du mit 
einem Windowsprogramm angenehm nach gültigen ID's in deinem System suchen. 
http://www.ireasoning.com 

Die vorbelegten OIDs basieren auf den Werten meiner QNAP und müssen evtl. 
angepasst werden. 

Parameter2 ($desc): 
------------------- 
Die Bezeichnung legt fest, wie die IPS-Variable genannt werden soll. 

Bitte berücksichtige, dass jede OID und jede Bezeichnung eindeutig sein müssen 
(keine doppelten Einträge). Ausserdem löscht das Skript keine einmal erstellten 
Variablen. D.h. wenn du eine Bezeichnung umbenennst, denn musst du die "alte" 
Variable manuell löschen. 

Parameter 3 (convertType) 
------------------------- 
dieser Parameter ist optional. Wird er nicht gesetzt oder als "none" übergeben, 
werden die Daten "wie empfangen" in der zugehörigen IPS-Variable gespeichert. 

In einigen Fällen ist dies jedoch nicht erwünscht. Beispielsweise liefert eine 
QNAP als freie Festplattenkapazität den Wert inkl. der Mengeneinheit als Text: 
3.96 TB. Damit ist eine geeignete Weiterverarbeitung in IPS sowie ein Logging 
der Variable ausgeschlossen. 

Um das zu ändern beinhaltet das Skript einige "Converter". In diesem Fall auf 
die Rohdaten der QNAP abgestimmt. Der Converter "Capacity" wandelt MB/GB/TB 
(Megabyte, Gigabyte, Terrabyte)-Strings in Megabyte Zahlen um. 
Aus "3.96 TB" werden "3960000". 

Derzeit verfügbare Converter: 
CapacityMB (Speichergrößen in Megabyte als Float) 
CapacityGB(Speichergrößen in Megabyte als Float) 
CapacityTB (Speichergrößen in Megabyte als Float) 
Temperature (Celsius Temperatur als Integer) 
FanSpeed (RPM als Integer) 
SmartStatus (S.M.A.R.T Informationen der HDD, Ergebnis ist Boolean => gut / schlecht) 

**/ 


$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.12.0", "ModelName"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.2.0", "SystemTotalMem", "CapacityMB"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.3.0", "SystemFreeMem", "CapacityMB"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.17.1.4.1", "SysVolumeTotalSize", "CapacityGB"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.17.1.5.1", "SysVolumeFreeSize", "CapacityGB"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.4.0", "SystemUptime"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.5.0", "CPU-Temperature", "Temperature"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.6.0", "System-Temperature", "Temperature"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.15.1.3.1", "System-FanSpeed", "FanSpeed"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.11.1.3.1", "HDTemperature1", "Temperature"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.11.1.3.2", "HDTemperature2", "Temperature"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.11.1.3.3", "HDTemperature3", "Temperature"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.11.1.3.4", "HDTemperature4", "Temperature"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.11.1.7.1", "HDSmartInfo1", "SmartStatus"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.11.1.7.2", "HDSmartInfo2", "SmartStatus"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.11.1.7.3", "HDSmartInfo3", "SmartStatus"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.11.1.7.4", "HDSmartInfo4", "SmartStatus"); 
$snmp->registerSNMPObj(".1.3.6.1.4.1.24681.1.2.1.0", "CPU usage", "Percent"); 

// ***** ab hier nichts mehr ändern 
$snmp->update(); 

class SNMP 
{ 
    //Objekteigenschaften 
    protected $host;                   //SNMP Serveradresse 
    protected $community;              //SNMP Community 
    protected $binary;                 //Dateipfad zur ssnmpq.exe 
    public      $debug = false;          //Bei true werden Debuginformationen ausgegeben 
    protected $snmpobj=array();        //array registrierter snmp objekte welche beim server abgefragt werden 

    //IPS Datentypen 
    const tBOOL     = 0; 
    const tINT      = 1; 
    const tFLOAT    = 2; 
    const tSTRING   = 3; 

    public function __construct($host, $community, $binary, $debug) { 
        $this->host         = $host; 
        $this->community    = $community; 
        $this->binary       = $binary; 
        $this->debug        = $debug; 


        //Prüfe ob Variablenprofile existieren und erstelle diese wenn nötig 
        $this->createVariableProfile("SNMP_Percent", self::tFLOAT, "", " %", 2); 
        $this->createVariableProfile("SNMP_CapacityMB", self::tFLOAT, "", " MB", 0); 
        $this->createVariableProfile("SNMP_CapacityGB", self::tFLOAT, "", " GB", 0); 
        $this->createVariableProfile("SNMP_CapacityTB", self::tFLOAT, "", " TB", 0); 
        $this->createVariableProfile("SNMP_Temperature", self::tINT, "", " °C", 0); 
        $this->createVariableProfile("SNMP_FanSpeed", self::tINT, "", " RPM", 0); 
        if (!IPS_VariableProfileExists("SNMP_SmartStatus")) { 
            $this->createVariableProfile("SNMP_SmartStatus", self::tBOOL, "", "", 0); 
            IPS_SetVariableProfileAssociation("SNMP_SmartStatus", 1, "Gut", "", 0x00FF04); 
            IPS_SetVariableProfileAssociation("SNMP_SmartStatus", 0, "Defekt", "", 0xFF0000); 
        } 
    } 

    private function createVariableProfile($name, $type, $pre, $suff, $digits) { 
        if (!IPS_VariableProfileExists($name)) { 
            if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "INFO - VariablenProfil ".$name." existiert nicht und wird angelegt."); 
            IPS_CreateVariableProfile($name, $type); 
            IPS_SetVariableProfileDigits($name, $digits); 
            IPS_SetVariableProfileText($name, $pre, $suff); 
        } 
    } 

    public function registerSNMPObj($oid, $desc, $convertType = "none") { 

        //prüfe auf doppelte Einträge beim Registrieren neuer SNMP Objekte 
        foreach($this->snmpobj as $obj) { 
            if ($desc==$obj->desc) { 
                if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "ERROR - registerSNMPObj: Variable description ".$desc." already exists, it must be unique!"); 
                exit; 
            } 
            if ($oid==$obj->OID) { 
                if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "ERROR - registerSNMPObj: Variable OID ".$oid." already exists, it must be unique!"); 
                exit; 
            } 
        } 

        //prüfe ob IPS Variablen für SNMP Objekt existiert (Variablenname entspricht description) 
        $parentID = IPS_GetParent($_IPS['SELF']); // übergeordnete Kategorie als Basis 
//        $parentID = $_IPS['SELF']; 
        $ips_var = @IPS_GetVariableIDByName($desc, $parentID); 
        if ($ips_var == false) { 
            if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "Variable ".$desc." not found - create IPSVariable"); 

            if ($convertType == "none") 
                $type = $this->getSNMPType($oid); 
            if ($convertType == "CapacityMB" || $convertType == "CapacityGB" || $convertType == "CapacityTB" || $convertType == "Percent") 
                $type = self::tFLOAT; 
            if ($convertType == "Temperature") 
                $type = self::tINT; 
            if ($convertType == "FanSpeed") 
                $type = self::tINT; 
            if ($convertType == "SmartStatus") 
                $type = self::tBOOL; 
            if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "Type of OID ".$oid." is ".$type); 

            $ips_var = IPS_CreateVariable($type); 
            IPS_SetName($ips_var, $desc); 
            IPS_SetParent($ips_var, $parentID); 

            //Verknüpfe Variablenprofil mit neu erstellter Variable 
            if ($convertType == "CapacityMB") 
                IPS_SetVariableCustomProfile($ips_var, "SNMP_CapacityMB"); 
            if ($convertType == "CapacityGB") 
                IPS_SetVariableCustomProfile($ips_var, "SNMP_CapacityGB"); 
            if ($convertType == "CapacityTB") 
                IPS_SetVariableCustomProfile($ips_var, "SNMP_CapacityTB"); 
            if ($convertType == "Temperature") 
                IPS_SetVariableCustomProfile($ips_var, "SNMP_Temperature"); 
            if ($convertType == "FanSpeed") 
                IPS_SetVariableCustomProfile($ips_var, "SNMP_FanSpeed"); 
            if ($convertType == "SmartStatus") 
                IPS_SetVariableCustomProfile($ips_var, "SNMP_SmartStatus"); 
            if ($convertType == "Percent") 
                IPS_SetVariableCustomProfile($ips_var, "SNMP_Percent"); 
        } 

        $count = count($this->snmpobj); 
        array_push($this->snmpobj, new SNMPObj($oid, $desc, $convertType, $ips_var)); 
        $count = count($this->snmpobj); 
        if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "New SNMPObj registered, now monitoring ".$count." snmp variables"); 
    } 

    //startet eine Abfrage am SNMP Server und aktualisiert die IPS-Variablen der registrierten 
    //SNMP Objekte 
    public function update() { 
        if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "Updating ".count($this->snmpobj)." variable(s)"); 

        foreach ($this->snmpobj as $obj) { 
//            $oid = ltrim($obj->OID,"."); 
            $oid = $obj->OID; 
            $exec_param =" -v1 -O vq -c ".$this->community." ".$this->host." ". $oid .""; 
            if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "Execute SNMP-Query: ".$this->binary.$exec_param); 
            $obj->value = str_replace('"', '', trim(system($this->binary.$exec_param))); 

            if ($this->debug) IPS_LogMessage(IPS_GetName($_IPS['SELF']), "Result of ".$obj->desc.": ".$obj->value); 

            if ($obj->convertType == "Percent") $obj->value = $this->convertPercent($obj->value, "%"); 
            if ($obj->convertType == "CapacityMB") $obj->value = $this->convertCapacity($obj->value, "MB"); 
            if ($obj->convertType == "CapacityGB") $obj->value = $this->convertCapacity($obj->value, "GB"); 
            if ($obj->convertType == "CapacityTB") $obj->value = $this->convertCapacity($obj->value, "TB"); 
            if ($obj->convertType == "Temperature") $obj->value = $this->convertTemperature($obj->value); 
            if ($obj->convertType == "FanSpeed") $obj->value = $this->convertFanSpeed($obj->value); 
            if ($obj->convertType == "SmartStatus") $obj->value = $this->convertSmartStatus($obj->value); 

            SetValue($obj->ips_var, $obj->value); 
        } 
    } 

    //prüfe um welchen SNMP Rückgabetyp es sich handelt 
    //returns 3 => String / 1 => Integer / 2 => Float 
    private function getSNMPType($oid) { 
        $oid = ltrim($oid,"."); 
        $exec_param =" -v1 -O v -c ".$this->community." ".$this->host." ". $oid; 
        $result = system($this->binary.$exec_param); 
        $pos_start = stripos ($result, " = "); 
        $pos_end = stripos ($result, ': "'); 
        $type = substr($result, $pos_start, $pos_end - $pos_start); 
        switch($type) { 
            case "STRING": 
                return self::tSTRING; 
            case "Integer": 
                return self::tINT; 
            case "Timeticks": 
                return self::tFLOAT; 
            default: 
                return self::tSTRING; 
        } 
    } 

    //returns -1 on error 
    private function convertCapacity($input, $unit) { 
        $pos = stripos($input, "MB"); 
        if ($pos === false) { 
            $pos = stripos($input, "GB"); 
            if ($pos === false) { 
                $pos = stripos($input, "TB"); 
                if ($pos === false) { 
                    return -1; 
                } else { 
                    $funit = "TB"; 
                } 
            } else { 
                $funit = "GB"; 
            } 
        } else { 
            $funit = "MB"; 
        } 

        $result = substr($input, 0, $pos); 
        $result = trim($result); 

        switch ($funit) { 
            case "GB": 
            $result = $result*1000; 
            break; 
            case "TB": 
            $result = $result*1000*1000; 
            break; 
        } 

        switch($unit) { 
            case "MB": 
            return round($result); 
            case "GB": 
            return round($result / 1000); 
            case "TB"; 
            return round($result / 1000000); 
        } 
    } 

    //returns -1 on error 
    private function convertTemperature($input) { 
        $pos = stripos($input, "C"); 
        if ($pos === false) { 
            $result = -1; 
        } else { 
            $result = substr($input, 0, $pos); 
            $result = round(trim($result)); 
        } 
        return $result; 
    } 

    private function convertPercent($input) { 
        $pos = stripos($input, "%"); 
        if ($pos === false) { 
            $result = -1; 
        } else { 
            $result = substr($input, 0, $pos); 
            $result = trim($result); 
        } 
        return $result; 
    } 

    //returns -1 on error 
    private function convertFanSpeed($input) { 
        $pos = stripos($input, "RPM"); 
        if ($pos === false) { 
            $result = -1; 
        } else { 
            $result = substr($input, 0, $pos); 
            $result = round(trim($result)); 
        } 
        return $result; 
    } 

    private function convertSmartStatus($input) { 
        $pos = stripos($input, "GOOD") + stripos($input, "Normal"); 
        if ($pos === false) { 
            return false; 
        } else { 
            return true; 
        } 
    } 

} 

class SNMPObj 
{ 
    //Objekteigenschaften 
    public $OID;                   //SNMP Message ID 
    public $desc;                  //Beschreibung 
    public $value;                 //Wert 
    public $convertType;           //Typ-Converter 
    public $ips_var;               //ID der IPS-Variable welche den SNMP Wert speichert 

    public function __construct($OID, $desc, $convertType, $ips_var) { 
        $this->OID            = $OID; 
        $this->desc           = $desc; 
        $this->convertType    = $convertType; 
        $this->ips_var        = $ips_var; 
    } 
} 
?>

… folgende Fehlermeldung:

Notice:  A non well formed numeric value encountered in C:\IP-Symcon\scripts\57473.ips.php on line 34

Fatal error:  Uncaught exception 'Exception' with message 'Unknown SNMP protocol version' in C:\IP-Symcon\scripts\57473.ips.php:34
Stack trace:
#0 C:\IP-Symcon\scripts\57473.ips.php(34): SNMP->__construct('172.168.3.34', 'public', 'C:\\IP-Symcon\\au...', 0)
#1 {main}
  thrown in C:\IP-Symcon\scripts\57473.ips.php on line 34
Abort Processing during Fatal-Error: Uncaught exception 'Exception' with message 'Unknown SNMP protocol version' in C:\IP-Symcon\scripts\57473.ips.php:34
Stack trace:
#0 C:\IP-Symcon\scripts\57473.ips.php(34): SNMP->__construct('172.168.3.34', 'public', 'C:\\IP-Symcon\\au...', 0)
#1 {main}
  thrown
   Error in Script C:\IP-Symcon\scripts\57473.ips.php on Line 34

Die SnmpGet.exe habe ich von https://www.snmpsoft.com/cmd-tools/snmp-get/

Hi,

Äh, nee, kann ich nicht.

Zum einen hat das Script nicht richtig funktioniert, wie schon oben man beschrieben. Die QNAP liefert die Daten z.b. der Festplatten nicht einzeln sondern nur im Block ab, dafür müsste man die in eine Array schreiben - davon habe ich bisher keine Ahnung und es deswegen nicht mehr weiter verfolgt.
Das gleiche gilt für Temperaturen und Festplattenstatus und einige andere Wert auch. Zudem werden für alle anderen Werte viele Mülldaten anlegen, von daher hab ich das Script längt gelöscht.

Zum anderen, IP-S läuft bei mir derzeit nicht mehr „produktiv“, Der Rechner ist war online, IPS auch aktivi, aber ich greife nicht mehr drauf zurück.

Also das Skript funktioniert bei mir weiterhin einwandfrei.

Häufig ist das Problem, dass viele andere SNMPGET Clients nutzen. Da gibt’s dann Abweichungen zur Syntax.
Da ich auf Linux / Ubuntu gewechselt bin hab ich das Ursprungsskript mal angepasst.

SNMP Client - Geräte-Status von NAS (QNAP, Synology) oder SNMP Servern allg. auslesen

Bin dafür! :slight_smile:

Kann mir fürs erste bitte jemand nen Schubs geben, wie ich von PRTG einen Sensor über die API in IPS bekomme?

Ich gehe davon aus, dass ich nicht über die HTTP API gehen muss, sondern über Live Data. Dort verliere ich mich aber zwischen „XML“ und „JSON“… :confused:

Dank und Grüße
galleto