Monitorer ses sites web…

Classé dans : Programmation | 0

Monitorer est ici un grand mot, l’idée c’est surtout de détecter si un site web ne répond plus et/ou n’est plus accessible en ligne.

Il est possible de vérifier si une requête get sur l’adresse de la home retourne 200 OK bien sûr. Mais cela ne suffit pas, car par exemple si vous avez une erreur qui est affichée (mysql connexion error par exemple) le serveur retourne bien un code 200 Ok, mais pour autant le site ne fonctionne pas.

Pour palier à cela l’idée c’est de charger une page du site, rechercher un ou plusieurs mots qui doivent s’y trouver. Si les mots sont trouvés on peut considérer que la page est OK et donc le site est OK.

Par contre si la recherche échoue c’est que la page affichée est différente de la page attendue, cela peut être une page d’erreur par exemple, et donc le site est peut être en panne.

Pour cela j’utilise un script PHP qui est exécuté plusieurs fois par jour (via une tâche cron) et envoie une notification par mail avec la liste des sites en erreur. A noter que pour être certain que le script c’est bien exécuté un mail est quand même envoyé si tous les sites sont OK.

Le script est commenté et ne devrait pas être difficile à adapter.

Init du script

#!/usr/bin/php
<?php

// timeout pour éviter que le script ne tourne trop longtemps
ini_set('default_socket_timeout', '05');
set_time_limit(5);

// liste des serveurs en erreur
$offLineServers = array();

// adresse mail pour les notifications
$mailAlerte = "xxxx@xxxx.xx";

// Liste des urls/site a checker 
$servers = array(
 "https://www.monsite1.fr/index.php", 
 "http://www.monsite2.com/homepage.html"
);

// texte à rechercher pour chaque site dans le meme ordre que $servers
$controlStr = array(
  'bienvenue sur mon site', // expression à recherche sur site 1 
  'homepage site 2' //  sur site 2 
);

Fonction de contrôle

function checkPage( $content, $str ) {
  // $content = page HTML retournée par le serveur 
  // $str = portion de texte à rechercher
  if( $content != "" AND $str != "") {
    $p = strpos($content,$str);
    if($p!==false) return true; // site OK
  }
  return false; // Site en erreur
}

Boucle principale

$nb = count($servers);
for( $i=0; $i<$nb ; $i++ ) {
  $server = $servers[$i];
  $f = @fopen($server, 'r');
  $ok = false;
  if ($f) {
    $r = fread($f,3000);
    // control si la page retournée contient l'expression recherchée
    $ok = checkPage($r,$controlStr[$i]); 
    fclose($f);
  }
  if(!$ok) {  // expression non trouvée, le site est offline
   $offLineServers[] = $server;  // on memorise le nom du serveur offline
  }
}

Envoi du mail

$body = "";
if( count($offLineServers) > 0 ) {
  foreach( $offLineServers as $one) {
    $body .= "[ $one ] ";
 }
  mail($mailAlerte,"Site(s) offline","$body\n");
} else {
  // envoi d'un mail pour dire que tout est ok
  mail($mailAlerte,"Pas de site offline","---");
}

Programmation du script

Méthode 1 : si vous disposez de PHP en mode console, il suffit de créer une tache cron sur votre serveur avec la commande : php  /PATH/siteOnline.php.

Méthode 2 : appel du script via une url depuis une autre machine (cron également), dans ce cas il suffit d’utiliser la comamnde : wget ‘URLdeSiteOnline.php’.
Pour cette méthode il faut supprimer la première ligne du script (#!/usr/bin/php), cette dernière n’est nécessaire que pour l’exécution en mode CLI .

Le script en entier

#!/usr/bin/php
<?php

// timeout pour éviter que le script ne tourne trop longtemps
ini_set('default_socket_timeout', '05');
set_time_limit(5);

// liste des serveurs en erreur
$offLineServers = array();

// adresse mail pour les notifications
$mailAlerte = "xxxx@xxxx.xx";

// Liste des urls a checker 
$servers = array(
 "https://www.monsite1.fr/index.php", 
 "http://www.monsite2.com/homepage.html"
);

// texte à rechercher pour chaque site dans le meme ordre que $servers
$controlStr = array(
  'bienvenue sur mon site', // expression à recherche sur site 1 
  'homepage site 2' //  sur site 2 
);

// fonction de controle
function checkPage( $content, $str ) {
  // $content = page HTML retournée par le serveur 
  // $str = portion de texte à rechercher
  if( $content != "" AND $str != "") {
    $p = strpos($content,$str);
    if($p!==false) return true; // site OK
  }
  return false; // Site en erreur
}

// boucle principale
$nb = count($servers);
for( $i=0; $i<$nb ; $i++ ) {
  $server = $servers[$i];
  $f = @fopen($server, 'r');
  $ok = false;
  if ($f) {
    $r = fread($f,3000);
    // control si la page retournée contient l'expression recherchée
    $ok = checkPage($r,$controlStr[$i]); 
    fclose($f);
  }
  if(!$ok) {  // expression non trouvée, le site est offline
   $offLineServers[] = $server;  // on memorise le nom du serveur offline
  }
}

// envoie du mail 
$body = "";
if( count($offLineServers) > 0 ) {
  foreach( $offLineServers as $one) {
    $body .= "[ $one ] ";
 }
  mail($mailAlerte,"Site(s) offline","$body\n");
} else {
  // envoi d'un mail pour dire que tout est ok
  mail($mailAlerte,"Pas de site offline","---");
}