7 – Module 4 – Ping de serveur

Si vous avez des serveurs, des NAS, ou n’importe quel autre type de machine dont vous souhaitez connaitre l’état (allumé/éteint, ou disponible/indisponible), ce type de module, encore une fois très simple, vous sera d’une grande utilité 🙂

jarvis_screenshot_pingL’idée est d’afficher en vert les serveurs qui répondent correctement aux solicitations du module, et en rouge ceux qui ne répondent pas. Pour accentuer le caractère alarmant d’une machine qui ne répond pas, nous ajouterons une animation pour optenir ce résultat :

ping

index.php

Comme pour les autres modules, une seule <div> suffit.

 <div id="ping"></div>

La balise reste vide, et sera « remplie » par la fonction JavaScript.

style.css

Pour ce module, la feuille de style est à peine plus longue :

/* ping */

div#ping
{
  left              : 0px;
  bottom            : 0px;
  position          : absolute;
  overflow          : hidden;
  background-color  : rgba(0, 0, 0, 1);
}

td.ping
{
  font-size         : 30px;
  text-align        : left;
  border-radius     : 10px;
  padding           : 5px 10px;
  font-weight       : bold;
}

td.ping_up
{
  color             : #00DD00;
}

td.ping_down
{
  background-image  : url('pict/warning.gif');
  color             : #DD0000;;
}

Les noms des machines sont affichés dans un tableau <table> dont chaque case <td> peut soit utiliser le style « ping_up« , si la machine répond, soit « ping_down«  si la machine ne répond pas. Dans ce dernier cas, nous utiliserons une image, un gif animé, pour faire « clignoter » la case en rouge, du mois, en donner l’impression 🙂

javascript.js

La fonction javascript de ce module ne fait qu’une requête AJAX, et affiche le résultat dans la div de la page index.php :

/* PING */

var ping_timeout;

function ping ()
{
  $.ajax({
    async : false,
    type: "GET",
    url: "./ajax.php",
    data: "block=ping",
    success: function(html){
      $("#ping").html(html);
    }
  });

  ping_timeout = setTimeout("ping()", 30000);
}

Il est important d’avoir une vision temps réel de l’état de ses machines, nous fixons donc le délai de rafraichissement à 30 secondes. Vous pouvez réduire ce délai selon vos besoins, mais veillez à ce qu’il reste supérieur au temps que met la fonction PHP pour tester toutes vos machines. Dans mon cas, je surveille six machines dont trois à travers internet. En moyenne, il faut 4 à 5 secondes pour tester toutes les machines. Toutefois, il n’est pas rare que cela prenne 20 secondes ! J’ai donc fixer à 30 secondes le temps à attendre entre chaque rafraichissement du module.

ajax.php

Il suffit de rajouter ces quelques lignes au fichier ajax.php pour que la bonne fonction soit appelée :

/////////////////////////////////////////////////
  //  PING
  /////////////////////////////////////////////////

  if($block == 'ping'){
    echo ping();
  }

inc.php

Dans ce fichier nous allons déclarer la fonction ping() qui est chargée de lancer les requêtes sur les différents serveurs, puis de construire le tableau HTML qui sera affiché.

En général, pour surveiller l’état d’un serveur, on utilise la commande ping qui permet simplement de savoir si la machine ciblée répond aux requêtes ICMP. Cela pose plusieurs problèmes. En effet, il est fort probable que le trafic ICMP soit bloqué par un firewall en amont du serveur visé ce qui faussera le résultat. De plus, si vous souhaiter surveiller un serveur web par exemple, il se peut très bien que la machine réponde bien aux pings, mais que le service web soit indisponible. Les pings n’ont donc que peu d’intéret…

L’idée, est plutôt de verier si les services qui tournent sur nos machines sont bien disponibles. Pour cela, nous allons simplement ouvrir une socket grâce à la fonction PHP fsockopen(). Si l’ouverture de la socket échoue c’est que le service n’est pas disponible 🙂

/////////////////////////////////////////////////
  //  PING
  /////////////////////////////////////////////////

  function ping () {
    $hosts    = array();
    // Définition des machines à tester
    $hosts_ip = array(
                    'Oberon'    => array('10.0.0.1',  '22'),    // SSH
                    'Triton'    => array('10.0.0.2',  '15915'), // TeamSpeak
                    'Ananke'    => array('10.0.0.3',  '2049'),  // NFS
                    'ds110j'    => array('10.0.0.4',  '2049'),  // NFS
                    'ds210j'    => array('10.0.0.5',  '2049'),  // NFS
                    'ds212j'    => array('10.0.0.6',  '2048')   // NFS
                );

    // pour chaque machine on test l'ouverture d'une socket sur le port spécifié
    // on stock le résultat 'up' ou 'down' dans la variable $hosts
    foreach($hosts_ip as $hostname => $host_data){
      $host_ip    = $host_data[0];
      $host_port  = $host_data[1];
      $socket     = 0;
      $socket     = @fsockopen($host_ip, $host_port, $errno, $errstr, 3);
      if($socket && !$errno){$hosts[$hostname] = 'up';}
      else{$hosts[$hostname] = 'down';}
    }

    // construction du tableau HTML
    // pour chaque machine testée, on affiche son nom et on fixe le style 'ping_up' ou 'ping_down' à la balise td
    $html  = '';
    $html .= '<table cellspacing="10px">';
    $c=0;
    foreach($hosts as $hostname => $host_status){
      if($c == 0){$html .= '<tr>';}
      $html .= '<td class="ping ping_'.$host_status.'">'.$hostname.'</td>';
      $c++;
      if($c == 2){$c = 0; $html .= '</tr>';}
    }
    if($c != 0){$html .= '</tr>';}
    $html .= '</table>';

    return $html;
  }

La variable $hosts_ip contient la liste des machines à tester et afficher. Le nom à affiché, l’adresse IP, et le port TCP du service à tester y sont stocké. Vous devez adapter les noms, adresses IP et numéro de port à vos besoins.

Comme vous pouvez le voir dans les commentaires du code, selon la machine à tester, j’ouvre une socket sur des services tels que SSH, TeamSpeak et NFS.  Cela fonctionne également très bien sur des serveurs FTP, HTTP, POP3, etc,… Tant que le service à tester écoute sur un port TCP, cela fonctionnera 🙂

Note : Il est possible d’optimiser cette fonction PHP en parallèlisant l’ouverture des sockets sur chaque machine. En effet, cette fonction teste les machines une par une ce qui peut être long… En « forkant » cette tâche grâce à la fonction PHP pcntl_fork(), il est possible de lancer toutes les requêtes d’un seul coup et ainsi diminuer le temps total que met la fonction pour renvoyer le tableau HTML à afficher. N’hésitez pas à laisser un commentaire si vous souhaitez plus de détails sur cette manière de procéder 🙂

Optimisation en utilisant le fork

Suite à la demande de lepopeye en commentaire de cet article, je vais expliquer comment paralléliser l’ouverture des sockets et ainsi gagner un temps précieux à chaque exécution de la fonction.

Le principe est simple : Pour chaque machine à tester, nous allons créer un processus fils grâce à la fonction PHP fork_pcntl() qui lancera la fonction fsockopen(). Comme les processus fils et le processus père ne peuvent pas partager de variables (à moins de faire appel à des techniques de mémoire partagée…), il convient de stocker les résultats dans une petite base de données SQlite 🙂 Le processus père attend que tous les processus fils soient terminés pour aller lire le contenu de la base de données SQlite (qui contient l’état de chaque machine). Le reste est inchangé, nous construisons le tableau HTML à afficher comme dans la fonction ping() initiale 🙂 A savoir que le fork n’est possible qu’en ligne de commande, il faudra donc adapter le fichier ajax.php de cette manière :

  /////////////////////////////////////////////////
  //  PING
  /////////////////////////////////////////////////

  if($block == 'ping'){
    echo shell_exec('php5 fork.php'); // fork.php étant le fichier dans lequel se trouve la fonction ping_fork();
  }

Voici la version « forkée » de la fonction ping(), que vous pouvez utiliser directement en la copiant dans un fichier fork.php :

function ping_fork() {

  $hosts_ip = array(
                    'Oberon'    => array('10.0.0.1',  '22'),    // SSH
                    'Triton'    => array('10.0.0.2',  '15915'), // TeamSpeak
                    'Ananke'    => array('10.0.0.3',  '2049'),  // NFS
                    'ds110j'    => array('10.0.0.4',  '2049'),  // NFS
                    'ds210j'    => array('10.0.0.5',  '2049'),  // NFS
                    'ds212j'    => array('10.0.0.6',  '2048')   // NFS
                );

  $pids  = array();

  // Connexion à la base de données sqlite et création de la table hosts_status si elle n'existe pas encore
  $db = new SQLite3('ifstat/hosts.sqlite');
  $db->exec('CREATE TABLE IF NOT EXISTS hosts_status (host_name VARCHAR(10), host_status VARCHAR(5));');

  // pour chaque machine, on créé un processus fils
  foreach($hosts_ip as $host_name => $host){
    $pids[$host_name] = pcntl_fork();
    if(!$pids[$host_name]) {
      $socket = @fsockopen($host[0], $host[1], $errno, $errstr, 3);
      if($socket && !$errno){$status = 'up';}else{$status = 'down';}
      // on attend que la table hosts_status ne soit plus verrouillée par un éventuel accès concurrent
      if($db->busyTimeout(5000)){
        $db->exec("INSERT INTO hosts_status VALUES ('$host_name', '$status');");
      }
      exit();
    }
  }

  // le processus père doit attendre que tous les processus fils soient terminés
  foreach($pids as $host_name => $pid){
    pcntl_waitpid($pid, $status, WUNTRACED);
  }

  $results = $db->query('select * from hosts_status;');

  $html  = '';
  $html .= '<table cellspacing="10px">';
  $c=0;
  while($host = $results->fetchArray(SQLITE3_ASSOC)){
    if($c == 0){$html .= '<tr>';}
    $html .= '<td class="ping ping_'.$host['host_status'].'">'.$host['host_name'].'</td>';
    $c++;
    if($c == 2){$c = 0; $html .= '</tr>';}
  }
  if($c != 0){$html .= '</tr>';}
  $html .= '</table>';

  $db->exec("DELETE FROM hosts_status;");

  return $html;
}

echo ping_fork();

Le timeout de la fonction fsockopen() est ici fixé à 3 secondes, ce qui veut dire que l’on doit attendre au moins 3 secondes avant de déclarer la machine cible comme « down » (non disponible). Dans la version non forkée de la fonction ping() si une machine ne répondait pas, il fallait attendre 3 secondes avant de tester la machine suivante, et ainsi de suite. Avec mes 6 machines, si aucune ne répond, il aurait fallu attendre 6×3 = 18 secondes avant d’avoir le résultat final. Avec la version forkée, les 6 requêtes sont envoyées en même temps. Quelque soit le nombre de machines à tester, nous aurons donc une réponse au bout de 3 secondes maximum 🙂

J’utilise à présent cette version forkée sur mon dashscreen 🙂 Merci à lepopeye de m’avoir forcé un peu la main 😉

58 réflexions au sujet de « 7 – Module 4 – Ping de serveur »

  1. lepopeye

    Déjà merci pour la suite des tutos ! j’apprends plein de choses ! je vais faire me lourd :

    « N’hésitez pas à laisser un commentaire si vous souhaitez pour de détails sur cette manière de procéder 🙂 »

    je pense qu’il manque un mot, mais c’est surtout sur l’utilisation de la fonction fork qui m’intéresse alors je le demande haut et fort ! bon, je peux trouver sur la doc de php mais je pense que ça serai vraiment top que ça soit dans le tuto. Surtout que cela peu apporter pas mal de réactivité au script en cas de déconnexion d’une ip.

    merci en tout cas pour le boulot et le partage.

    Répondre
    1. Olivier Auteur de l’article

      Salut lepopeye,

      Merci d’avoir remonté la faute de frappe 🙂

      L’utilisation du fork est effectivement une excellente idée pour ce type de fonction qui envoie plusieurs requêtes sans rapports entre elles. On gagne un temps précieux à les exécuter en même temps 🙂 J’ai donc ajouter une version « forkée » de la fonction ping() en fin d’article, avec les explications qui vont bien 🙂

      Répondre
  2. LePoPeye

    Merci pour cet ajout qui va bien me servir !

    Juste au passage au début de ton rajout : ralléliser -> réaliser histoire de chipoter 🙂

    encore merci pour ton ajout suite à ma demande et le travail de recherche associé.

    Répondre
  3. LePoPeye

    alors … le petit ajout provoque un manque sur le reste du tuto, installation de sqlite3 (sudo apt-get install sqlite3) bon ça c’est simple à trouver. Par contre je n’arrive pas à passer l’étape de création de la table.

    J’ai bien créé un fichier avec le même nom dans le bon répertoire, j’ai changé les droits (root puis www-data) mais rien, le script ne veut pas créer le table et je ne sais même pas si le script trouve mon fichier de la base sqlite. bref je but … si quelqu’un a une idée ?

    merci.

    Répondre
      1. Olivier Auteur de l’article

        Oui tout à fait, il faut installer la lib php5-sqlite pour que cela fonctionne 🙂

        Ensuite $db = new SQLite3(‘ifstat/hosts.sqlite’); permet de créer le fichier s’il n’existe pas 🙂

        Répondre
        1. lepopeye

          Je sais pas si c’est un problème de droit ou autre, mais impossible de trouver le pourquoi tu comment. Comme l’impression que le script ne fait rien à partir de $db = new SQLite3 …
          Déjà le fichier n’est pas créé automatiquement ! je continue de chercher.

          Répondre
        2. MarkS

          Désolé pour la question très basique et mon mauvais français, je me sers de Google Translate. Je ne peux pas obtenir la fonction de ping à afficher. Je l’ai installé ‘sqlite3’ et fait chmod et chown. Comment pouvez-vous créer la base de données vide que tout ce que je reçois est ‘$’ est pas une commande reconnue.

          Répondre
    1. Olivier Auteur de l’article

      Hello mika,
      Tu peux tester en affichant directement la sortie du ping. Si cela fonctionne tu peux creuser du coté de sqlite. Dans tous les cas, si problème il y a, tu devrais avoir des erreurs dans les logs de PHP.
      Pour sqlite, souvent c’est un problème de droit sur le fichier qui contient la bdd, à vérifier en premier donc 🙂

      Répondre
  4. David

    Hello,

    est-il possible d’utiliser ce/ces script sur un serveur apache/php windows ?

    J’aimerai récupérer juste le script de PING / PORT, mais je n’y arrive pas. j’ai une page vierge sur l’index.php, on dirais que le javascript n’est pas executé.

    Je n’ai pas de tableau en sortie 🙁 puis-je avoir de l’aide svp ?)

    Génial tuto sinon 😉

    Répondre
    1. David

      oops en fait je n’ai pas « RIEN » j’ai une erreur (blanc sur blanc j’avais pas vu) :

      Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING, expecting ‘)’ in D:\Apache2.2\htdocs\site\inc.php on line 19

      ma ligne 19 du fichier inc.php est

      $hosts_ip = array(
      ‘Oberon’ => array(‘10.0.0.1′, ’22’),
      ‘Triton’ => array(‘10.0.0.2’, ‘15915’)
      ); <——————————————- CETTE LIGNE

      Répondre
      1. Olivier Auteur de l’article

        Hello,
        A priori, il n’y a pas d’erreur de syntaxe. Peux tu copier/coller toute la fonction en utilisant la balise « code » ?

        Répondre
        1. David

          Hello,
          Merci pour la réponse. J’ai remarqué que j’ai une erreur ligne19 peu importe ce que je met a la ligne 19. meme si je met des lignes vides.

          Pour la partie SQL Lite je voulais remplacer par MYSQL mais pour l’instant je n’arrive pas meme sans la version forké 🙁

          Je vais essayer la fonction code pour mon fichier inc.php ^^ :

          [code]
          $val) {
          $array[$key] = (is_array($val)) ? htmlspecialchars_array($val) : htmlspecialchars($val);
          }
          return $array;
          }

          /////////////////////////////////////////////////
          // PING
          /////////////////////////////////////////////////

          function ping () {
          $hosts = array();
          $hosts_ip = array(
          'machine1' => array('10.1.1.1', '80'),
          'machine2' => array('10.2.2.2', '81')
          );

          foreach($hosts_ip as $hostname => $host_data){
          $host_ip = $host_data[0];
          $host_port = $host_data[1];
          $socket = 0;
          $socket = @fsockopen($host_ip, $host_port, $errno, $errstr, 3);
          if($socket && !$errno){$hosts[$hostname] = 'up';}
          else{$hosts[$hostname] = 'down';}
          }

          $html = '';
          $html .= '';
          $c=0;
          foreach($hosts as $hostname => $host_status){
          if($c == 0){$html .= '';}
          $html .= ''.$hostname.'';
          $c++;
          if($c == 2){$c = 0; $html .= '';}
          }
          if($c != 0){$html .= '';}
          $html .= '';

          return $html;
          }

          ?>


          [/code]

          Répondre
          1. David

            j’ai du mal, ca n’a pas coller le debut de mon fichier inc.php …
            je crois que j’ai raté la fonction code. Pourais-je vous envoyer mes sources et mes pages php par mail peut-etre ?

            merci.
            je reesaye le code :


            $val) {
            $array[$key] = (is_array($val)) ? htmlspecialchars_array($val) : htmlspecialchars($val);
            }
            return $array;
            }

            /////////////////////////////////////////////////
            // PING
            /////////////////////////////////////////////////

            function ping () {
            $hosts = array();
            $hosts_ip = array(
            'machine1' => array('10.1.1.1', '80'),
            'machine2' => array('10.2.2.2', '81')
            );

            foreach($hosts_ip as $hostname => $host_data){
            $host_ip = $host_data[0];
            $host_port = $host_data[1];
            $socket = 0;
            $socket = @fsockopen($host_ip, $host_port, $errno, $errstr, 3);
            if($socket && !$errno){$hosts[$hostname] = 'up';}
            else{$hosts[$hostname] = 'down';}
            }

            $html = '';
            $html .= '';
            $c=0;
            foreach($hosts as $hostname => $host_status){
            if($c == 0){$html .= '';}
            $html .= ''.$hostname.'';
            $c++;
            if($c == 2){$c = 0; $html .= '';}
            }
            if($c != 0){$html .= '';}
            $html .= '';

            return $html;
            }

            ?>

          2. Olivier Auteur de l’article

            Hello,
            Au niveau de la variable $val, il semble y avoir une parenthèse ou un crochet en trop 🙂

    2. Olivier Auteur de l’article

      Hello,
      Il faudra sans doute adapter certaines parties, notamment autour de l’utilisation de sqlite.

      Répondre
  5. David

    Désolé, en fait je n’ai pas « rien d’affiché », je choppe une erreur (blanc sur blanc j’avais pas vu) :

    Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING, expecting ‘)’ in D:\Apache2.2\htdocs\site\inc.php on line 19

    et ma ligne 19 c’est la ligne qui contient la fermeture de l’array $host_ip.
    La ligne ou il y a juste );

    Répondre
    1. Olivier Auteur de l’article

      Bonjour Franck,
      L’intégralité du code source de ce module est disponible dans l’article. Le code est entièrement fonctionnel 🙂

      Répondre
  6. Blanquet Franck

    Re bonjour,

    Merci Olivier de ta réponse rapide, mais par exemple le php index.php doit certainement inclure les .css, .js etc. Il ne doit pas contenir l’unique ligne , je ne suis pas un pro, mais ça me parait un peu court. Ou alors il y a 1 lien que je ne vois pas vers l’ensemble des fichiers source ( ce que je cherche justement ).

    Merci

    Franck

    Répondre
    1. Olivier Auteur de l’article

      Tout est là 🙂 La partie CSS est en début d’article, de même que la partie JavaScript. Puis la partie PHP pour l’appel Ajax, et enfin deux versions du script « ping » dont une version forkée 🙂

      Répondre
  7. Franck Blanquet

    Bonsoir,

    Je suis toujours sur ce programme depuis ce midi, et chez moi, ça ne fonctionne pas, aucun résultat, des erreurs au niveau ajax qui ne connait pas ajax.php?block=ping.
    Il me manque des ligne de code, exemple l’ajout de jquery n’est pas mentionné dans le fichier index.php,
    Si quelqu’un pouvait me passer les sources complets et je dis bien complet pour pouvoir faire tourner ce programme et comprendre le fonctionnement, ça serai cool.
    Pour un débutant, dès qu’il manque une ligne de code, il est perdu et c’est mon ce soir

    Merci à vous

    Franck

    Répondre
  8. Jordan

    Bonjour,
    Excellent site et dashboard, j’adore ! Je suis d’ailleurs en train d’essayer de le mettre en fond d’écran de ma Debian 😀

    Par contre, petite question/remarque : alors que ma Livebox répond au ping, la requête via le fork.php ne marche pas et la box est indiquée comme ne répondant pas au ping. Une idée ?

    Répondre
    1. Jordan

      Autre petite remarque, les machines ajoutées « bougent » de temps à autre sur le dashboard. Une idée la aussi ?

      Répondre
  9. Jerome

    Bonjour,

    j’ai essayé d’implementer ce code sur mon serveur web qui est un nas synology.
    Est ce que ceci expliquerai que ça ne fonctionne pas chez moi?
    Je ne suis pas expert php et javascript (débutant meme)…

    Merci pour l’aide

    Répondre
    1. Olivier Auteur de l’article

      Bonjour Jérôme,
      Il faut t’assurer que tous les modules php nécessaires sont bien installés. En théorie, seule la version « fork » peut ne pas fonctionner de base sur un Synology.

      Répondre
      1. Jerome

        j’ai volontairement remis le ping standard, me disant qu’il etait plus simple de commencer par la.
        je vais continuer à investiguer ce soir…

        Répondre
  10. Ludo

    Pour les pcs j’ai réussi à utiliser un port de communication (Port 139 si vous avez un autre plus basique ?)
    Cependant pour les téléphones portable je n’arrive pas à les faire apparaitre si vous avez une piste pour les ports svp ?
    Merci 🙂

    Répondre
    1. Olivier Auteur de l’article

      Hum… Très bonne question pour les téléphones portables… Un petit scan de port avec nmap devrait vous aider 🙂

      Répondre
  11. Ludo

    Je vais regarder pour les portables, si je trouve une info valable je ferait un retour, par contre sur les Pc je ne parviens pas à trouver un port valable pour tout les Pc même au reboot.
    Actuellement le pc de ma femme est bien vu comme connecté alors que pas le mien pourtant il est en ligne aussi je pense que le port n’est pas bon.

    Répondre
    1. Olivier Auteur de l’article

      Ca depend des services qui tournent sur tes PC et des règles firewall. Si aucun port n’est ouvert tu peux essayer de lancer un ping à la place d’ouvrir une socket

      Répondre
  12. Loic

    Je n’arrive pas à faire afficher le resultat des ping sur la page.
    Il n’y as rien qui apparait , exemple avec un hote : ‘Katyusha’ => array(‘192.168.1.76’),

    Ma syntaxe est elle bonne?

    Répondre
    1. Olivier Auteur de l’article

      Il manque le port sur lequel ouvrir la socket pour tester si l’hôte est vivant ou non…

      Répondre
  13. John

    Bonjour et merci pour votre travail.

    Je suis bloqué sur une chose et je ne vois pas d’ou ça vient.

    J’utilise le fork pour tester mes machines au nombre de 9.
    Le soucis c’est que le tableau renvoyé contient un nombre aléatoire de serveurs: tantôt ça m’en affiche 5, tantôt 9, tantôt 7 etc.
    J’ai remarqué que ceux qui sont en ligne s’affichent forcément, mais que ceux qui sont hors ligne sont parfois oubliés dans le tableau récap.

    Ce n’est pas le cas avec la fonction ping non forkée.

    Avez-vous une piste sur le problème que je rencontre?

    Répondre
    1. Olivier Auteur de l’article

      Bonjour,
      C’est étrange en effet. Essayez de lancer le script depuis un terminal en dégageant tout ce qui concerne SQLite et en affichant directement les résultats de ping.
      A vue de nez, c’est un pb de timeout soit php5-cli qui n’est pas installé et qui empêche donc de « forker » le processus.
      Bon courage 🙂

      Répondre
      1. John

        Concernant php5-cli j’ai le message suivant:
        Lecture des listes de paquets… Fait
        Construction de l’arbre des dépendances
        Lecture des informations d’état… Fait
        php5-cli est déjà la plus récente version disponible.
        php5-cli passé en « installé manuellement ».
        0 mis à jour, 0 nouvellement installés, 0 à enlever et 0 non mis à jour.

        Donc je suppose que ça ne vient pas de là?

        Pour le reste je suis bloqué je ne sais pas programmer la fonction sans utiliser le code original.
        Auriez-vous un exemple de script à lancer à me donner pour que je puisse tester?

        Merci,
        John

        Répondre
        1. John

          J’ai fait le bash suivant:
          #!/bin/bash
          ips= »192.168.1.14 192.168.1.15 192.168.1.10 192.168.1.8 192.168.1.4 192.168.1.5 192.168.1.75 192.168.1.85″
          for i in $ips; do
          echo `date`
          if ping -c 1 $i > /dev/null; then
          echo « $i : Success »
          else
          echo « $i : Failed »
          fi
          done
          echo « fin »
          exit 0

          ça me donne le résultat:
          + bash ping3.sh
          mardi 1 septembre 2015, 14:25:40 (UTC+0200)
          192.168.1.14 : Success
          mardi 1 septembre 2015, 14:25:40 (UTC+0200)
          192.168.1.15 : Failed
          mardi 1 septembre 2015, 14:25:43 (UTC+0200)
          192.168.1.10 : Success
          mardi 1 septembre 2015, 14:25:43 (UTC+0200)
          192.168.1.8 : Success
          mardi 1 septembre 2015, 14:25:43 (UTC+0200)
          192.168.1.4 : Failed
          mardi 1 septembre 2015, 14:25:46 (UTC+0200)
          192.168.1.5 : Failed
          mardi 1 septembre 2015, 14:25:49 (UTC+0200)
          192.168.1.75 : Failed
          mardi 1 septembre 2015, 14:25:52 (UTC+0200)
          192.168.1.85 : Failed
          fin

          Qu’en pensez-vous?

          Répondre
          1. Olivier Auteur de l’article

            Et bien cela me paraît clair, la plupart de vos machines ne répondent pas aux ping :/

  14. John

    Mon but est de savoir si la machine est allumée ou pas.

    Votre fonction n’a rien a voir avec ça?

    Je ne comprend plus? Faut-il distinguer « réponse au ping » de « ouverture de socket » ?

    Une non réponse au ping devrait renvoyer « down » et dans ma liste html toutes les machines down devraient s’afficher. Or ce n’est pas le cas puisque seulement certaines s’affichent.

    Je ne sais toujours pas comment résoudre ce problème?

    Répondre
    1. John

      Je pense qu’il s’agit d’un problème lié à l’utilisation de la base de données SQLITE3 mais je n’arrive pas à entrer dans la base en ligne de commande pour l’explorer et voir ce qui est inscrit dedans après l’execution de la fonction ping_fork()
      bien sur j’ai commenté le « exec delete ».

      Toute idée est la bienvenue

      Répondre
      1. Olivier Auteur de l’article

        D’après les résultats de votre script bash, ce sont bien vos machines qui ne répondent pas aux pings…
        Pour répondre à votre question, l’objectif de la fonction est de déterminer si une machine est joignable sur le réseau ou non. Ce qui est différent de « est ce que la machine est allumée ou pas ».
        Entre la machine qui envoi les ping ou ouvre les sockets et les machines à tester, il peut y avoir une multitude de chose qui peuvent les rendre injoignables (latence réseau, filtrage IP, réponse au ping désactivée, port fermé,…).
        Le ping est une simple requête qui, si réponse il y a, permet de dire si une machine est joignable ou non. Mais cette fonctionnalité peut très bien être désactivé.
        C’est pourquoi dans ma fonction j’ai préféré faire un test sur l’ouverture d’une socket sur un service particulier de chaque machine cible que je suis certain de pouvoir joindre si tout va bien.
        On peut dire que le test par ouverture de socket est plus ciblé et plus « fiable ». Cela n’empêche évidement pas les autres problèmes liés au réseau…
        Au pire, faites manuellement un ping directement depuis votre Pi vers vos autre machines. Vous verrez celles qui répondent et celles qui ne répondent pas.
        Ensuite, si toutes les machines répondent correctement, alors vous pourrez creuser du côté de SQLite, mais je doute que le problème vienne de là 🙂
        Bonne continuation,

        Répondre
        1. John

          Je suis d’accord avec la démarche.
          Mais alors pourquoi une machine non « pinguée » donc considérée hors ligne n’apparait pas dans le tableau récap html?

          Ce serait équivalent à une machine non « socketée » qui n’est pas en ligne.

          Le ping sans fork fait bien apparaitre toutes les machines, sans exception.

          Je ne comprend pas pourquoi en utilisant le fork cela doit etre différent?

          Répondre
          1. Olivier Auteur de l’article

            Effectivement, les machines down devraient apparaître dans le tableau. Essayez de rajouter des echo dans la première boucle foreach afin de voir à l’écran ce que fait le programme lors de son exécution

  15. john

    Bonjour Olivier,

    Alors j’ai fait des tests à n’en plus finir hier soir et je crois que ça vient de l’interrogation de la BDD SQLite.
    Soit la requete n’est pas bonne, soit c’est le fetchArray qui déconne, je ne sais pas d’ou ça vient mais quand on affiche les infos, il manque des valeurs.
    Ou alors c’est le exec(« INSERT INTO qui ne fonctionne pas correctement?

    Si j’ai le temps je vais essayer de tester avec une base MySQL voir si ça change quelque chose.

    Répondre
    1. Olivier Auteur de l’article

      Hello,
      Ok, merci pour le retour. N’hésites pas à venir poster ta découverte si tu trouve ce qui déconne 🙂

      Répondre
      1. John

        Salut Olivier,
        J’ai trouvé une solution qui me donne satisfaction.
        Je n’ai pas trouvé ce qui ne va pas dans ta fonction d’origine mais je sais que la mienne fonctionne à merveille: j’ai tout passé en MySQL et j’ai revu la fonction de fork.

        Comment je fais pour t’envoyer mon fichier?

        Répondre
  16. Feanand

    Salut Olivier,
    Récemment équipé d’un raspberry pi3, donc grand débutant j’apprends ! J’ai commencé à réalisé ton Daschscreen et après quelques heures.. la météo, xplanet,le ping et le diaporama sont opérationnels. J’ai un soucis sur le ping, les machines connectées par rj45 sont visibles et vu en vert, mais j’ai une tablette Androïd et un portable Windows qui reste en rouge. Quelles réglages faire pour les postes en wifi ? Je câle. J’utilise la méthode Fork après avoir commencé par le ping normal. Merci pour le site, super bien et content de trouver de l’aide pour le Raspberry, c’est passionnant.
    ps : bonjour d’Altviller en Moselle

    Répondre
    1. Sigri44

      Bon finalement je suis repassé sur la commande ping sans le fork et ça fonctionne. Souçis auprès de SQLite donc j’abandonne et je reste en ping

      Répondre
  17. bast

    super simpat le dash board, mais j ai le meme proble que beaucoup de gens sur le fork.php

    PHP Fatal error: Uncaught Exception: Unable to open database: unable to open database file in /var/www/html/fork.php:13
    Stack trace:
    #0 /var/www/html/fork.php(13): SQLite3->__construct(‘./ifstat/hosts….’)
    #1 /var/www/html/fork.php(52): ping_fork()
    #2 {main}
    thrown in /var/www/html/fork.php on line 13

    dommage qu’il n’y a pas de suivi …

    Répondre

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.