Ad Widget

Collapse

superviser les processus via snmp

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • jarod
    Member
    • Nov 2013
    • 46

    #1

    superviser les processus via snmp

    Bonjour tout le monde
    Alors j'aimerai, si quelqu'un a une idée, superviser un programme bien spécifique via le snmp ... savoir si il est up ou down
    Je supervise tous les processus d'un serveur windows en snmp mais j'aimerai faire mon choix .
    Car le problème que je rencontre c'est que quand je crée un déclencheur pour "firefox.exe" par exemple, le problème c'est que l'ID du dit processus change qd il redémarre. Donc le déclencheur n'est plus valable quand il est relancé.
    j'ai mm essayé de créer des prototypes snmp lié à mes prototypes de découverte du genre ... hrSWRunStatus[firefox.exe] ... mais cela ne fonctionne pas

    donc si quelqu'un a une astuce ... une idée... venez je suis preneur
  • Murmelantes
    Junior Member
    • Feb 2015
    • 6

    #2
    Bonjour!
    J'ai eu à résoudre le même genre de soucis à résoudre sous linux.
    Pas certain que cela puisse être applicable à windows, mais cela peut-être te donner des idées...

    Avec Net-Snmp, il est possible d'ajouter une supervision basique des processes en précisant les applications à superviser dans la configuration:
    http://www.net-snmp.org/docs/man/snm...ples.html#lbAP

    Le soucis est que c'est limité à une vérification du nombre d'instance en cours de fonctionnement:
    pour résumer, on indique le nombre minimum d'instances du programmes qui devraient tourner, et si on sort des bornes, une alarme est déclenchée.
    De plus, pas possible de spécifier les paramètres, donc si il s'agit de superviser un script perl spécifique, impossible: ils sont tous regroupés dans les instances du programme perl...

    Pour vérifier la conso CPU et RAM, je me suis donc retrouvé confronté au même soucis: il faut effectivement le PID, et celui ci change.

    J'ai donc utilisé un script de découverte bas niveau personalisé:
    En gros, au lieu de laisser zabbix interroger le serveur par SNMP, celui-ci lance le script avec comme paramètre le processus à superviser.
    C'est celui ci qui récupère la liste des processus en récupérant la table idoine:
    snmptable -v2c -c $snmpcommunity -Cf +++ -CH $hostname HOST-RESOURCES-MIB::hrSWRunTable
    Ensuite, je traite cette table, pour au final renvoyer au format json les PIDs qui correspondent aux processus.
    Je peux donc ensuite utiliser ces PIDs pour créer dans zabbix les items qui vont bien...

    J'ai un peu honte de montrer mon code, vu que je ne suis absolument pas un programmeur et que ça doit être rempli d'erreurs, mais voilà l'idée:

    Dans les règles de découvertes, je déclare comme type "external script" et comme clé mon script et ses paramètres:
    process.discovery["{$SNMP_COMMUNITY}","{HOST.IP}","firefox","1"]

    J'ai ajouté un filtre pour les processus indiqués comme surnuméraires par mon script (voir commentaires dans le script):
    {#SWRUNERROR} = [01]

    Ce script est placé dans le dossier qui va bien:

    /usr/lib/zabbix/externalscripts/process.discovery

    Code:
    #!/usr/bin/perl
    use strict;
    use Storable;
    use Digest::MD5 qw(md5_hex);
    
    # process.discovery is a custom LLD filter for zabbix.
    # It performs an snmptable (to get data by bulk) to get running processes on a remote host.
    # Each process matching the pattern given in parameter is given an instance number, to keep trace
    # of eventual restarting processes.
    # The json output gives zabbix 4 new macro to use:
    # #SWRUNPID: the process PID number
    # #SWRUNNUMBER: the instance number
    # #SWRUNNAME: the full path used to launch the process
    # #SWRUNERROR: an error code (0 if ok, 1 if process dead, 2 if too many processes running)
    
    # default parameters
    my $snmpcommunity = $ARGV[0] // "public";
    my $hostname = $ARGV[1] // "127.0.0.1";
    my $process = $ARGV[2] // "";
    my $processnumber = $ARGV[3] // 1;
    
    
    # temp folder creation
    my $tmpdirectory = "/tmp/process.discovery/";
    unless(-e $tmpdirectory or mkdir $tmpdirectory) {
      die "Unable to create $tmpdirectory";
    }
    
    
    # tmpfile name: one per host/process tuple
    my $processhash = md5_hex($hostname).md5_hex($process).$processnumber;
    my $tmpfile = $tmpdirectory.$processhash;
    
    
    # retrieve last values in file if it exists
    my %hash = ();
    %hash = %{retrieve ($tmpfile)} if (-e $tmpfile);
    
    # initialise counter to the number of processes found, to be able to add values with a correct instance number.
    my $number = keys %hash;
    
    
    # Check the last update of the file and only do a snmpwalk and comparison if > 1 min.
    # If not, just skip the processing and output the same json as the last time.
    my $epoc = time();
    my $last_update_time = (stat($tmpfile))[9];
    
    if (($epoc - $last_update_time) > 60) {
        my $hrSWRunTable = `snmptable -v2c -c $snmpcommunity -Cf +++ -CH $hostname HOST-RESOURCES-MIB::hrSWRunTable`;
        my $rc = $? >> 8;
    
    if ($rc == 0) {
    
        my %hash2 = ();
    
    # Split the snmpwalk results and generate a hashtable with them.
    # The index is the PID, and content is the instance number and error code.
        my $instance = "0";
        for (split /^/, $hrSWRunTable) {
            (my $hrSWRunPID, my $hrSWRunPath, my $hrSWRunParameters) = m/(.*)\+\+\+.*\+\+\+.*\+\+\+"(.*)"\+\+\+"(.*)"\+\+\+.*\+\+\+.*/;
            if ($hrSWRunParameters ne "") {
                $hrSWRunParameters = ' '.$hrSWRunParameters
            }
            my $hrSWRunFullPath = $hrSWRunPath.$hrSWRunParameters;
    
            if ($hrSWRunFullPath =~ m/^\Q$process/) {
                $hash2{++$instance} = { "hrSWRunPID" => $hrSWRunPID, "hrSWRunError"=> "1" };
            }
        }
    
    # Check in the previous hashtable saved (empty if first use) if every process is still running.
    # Error code set to 1 if not.
    
        foreach my $oldinstance (keys(%hash)) {
            $hash{$oldinstance}{hrSWRunError} = "1";
            foreach my $newinstance (keys(%hash2)) {
                if ($hash{$oldinstance}{hrSWRunPID} == $hash2{$newinstance}{hrSWRunPID}) {
                    $hash{$oldinstance}{hrSWRunError} = "0";
                    delete ($hash2{$newinstance});
                    last;
                }
            }
            if ($hash{$oldinstance}{hrSWRunError} == "1") {
                $hash{$oldinstance}{hrSWRunPID} = "0"
            }
        }
    
    # inserting the new found instances:
    # replacing stopped instances with error code 1
    
        foreach my $newinstance (keys(%hash2)) {
            my $done = "0";
            foreach my $oldinstance (keys(%hash)) {
                if ( $hash{$oldinstance}{hrSWRunError} == "1" ) {
                    $hash{$oldinstance}{hrSWRunPID} = $hash2{$newinstance}{hrSWRunPID};
                    $hash{$oldinstance}{hrSWRunError} = "0";
                    $done = "1";
                    last;
                }
            }
    
    # adding them is all previous instances are still running, with error code 2 if too many instances
    
            if ($done == "0")  {
                $hash{++$number} = $hash2{$newinstance};
                if ( $number > $processnumber) {
                    $hash{$number}{hrSWRunError} = "2";
                }
                else {
                    $hash{$number}{hrSWRunError} = "0";
                }
            }
        }
    
        # Store the updated hashtable for future comparison.
    
        store \%hash, $tmpfile;
    }
    }
    
    # Output the json data
    
    print "{\n";
    print "\t\"data\":[\n\n";
    
    my $first = 1;
    foreach my $k (keys(%hash)) {
        print ",\n" if not $first;
        $first = 0;
        print "\t{\n";
          print "\t\t\"{#SWRUNNUMBER}\":\"$k\",\n";
          print "\t\t\"{#SWRUNPID}\":\"$hash{$k}{hrSWRunPID}\",\n";
          print "\t\t\"{#SWRUNNAME}\":\"$process\",\n";
          print "\t\t\"{#SWRUNERROR}\":\"$hash{$k}{hrSWRunError}\"\n";
        print "\t}";
    }
    
    print "\n\n\t]\n";
    print "}\n";
    Et je peux ainsi créer les items prototypes à partir du PID:
    Name: CPU Usage Firefox {#SWRUNNUMBER}
    Key: CPU.Firefox.[{#SWRUNNUMBER}]
    OID: HOST-RESOURCES-MIB::hrSWRunPerfCPU.{#SWRUNPID}

    Voilà voilà...

    En espérant que cela te donne quelques idées.
    N'hésite pas à me demander si besoin de plus de renseignements, et à corriger mon script, je suis preneur de tout conseil!

    PS: {#SWRUNNUMBER} sert à conserver un index constant malgré le changement de PID, comme ça après un redémarrage de l'appli, même si le PID change, le numéro d'instance et donc la clé restent à la même valeur.
    Last edited by Murmelantes; 02-02-2015, 17:43. Reason: ajout d'une explication sur le numéro d'instance...

    Comment

    • jarod
      Member
      • Nov 2013
      • 46

      #3
      Merci pour l'info Murmelantes
      pour le moment je suis occupé sur une autre tâche mais je verrai ça de plus près qd j'aurais un moment .
      Mais tout ceci me parait pas mal du tout

      Merci pour la réponse et pour l'idée (judicieuse)

      Comment

      Working...