Récemment (très récemment en fait … hier), j’ai subi quelques soucis avec un serveur mit hors-ligne par mon hébergeur sans me prévenir (ouh le méchant OVH). Le soucis le plus important, c’est que je m’en suis rendu compte un peu tard, à savoir, le lendemain (dur dur l’arrivée au bureau ce matin. Je n’ai même pas eu le temps de mettre en place mon intraveineuse de café). Il existe bien entendu beaucoup de systèmes automatique de monitoring sur le web mais quoi de mieux que de réinventer la roue et surtout, de savoir comment celle-ci fonctionne.

Le principe de notre système va donc être de regarder régulièrement, à l’aide d’une tâche CRON, si le serveur de votre site répond correctement et si celui-ci est bien le bon serveur (une guerre existe au sujet de la prononciation du mot « CRON », un camps prône la tâche « crone » et l’autre, la tâche « cron » . Je préfère pour ma part « cron », ça me permet d’insulter tout le monde de « tâche » automatique sans passer pour un … bref).

I/ Créer la base de donnée

La base de donnée n’a rien de compliqué en soit, il suffit de hiérarchiser toutes les données dont nous avons besoins, à savoir :

  • Le titre du site
  • Le nom de domaine du site
  • L’IP du serveur hébergent le site
  • L’indicateur d’état DNS
  • L’indicateur d’état HTTP
  • La date du dernier changement d’état

Soit en SQL :

CREATE TABLE IF NOT EXISTS `monitoring` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(64) NOT NULL,
`domain` varchar(64) NOT NULL,
`ip` varchar(64) NOT NULL,
`dns` tinyint(1) NOT NULL,
`http` tinyint(1) NOT NULL,
`update` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=58 ;

II/ Créer le script

Pour la création de ce script, je vais assumer le fait que vous soyez correctement connecté à votre base de donnée et que vous utilisez la bibliothèque PDO.

Récupéreration des données

Commençons ainsi par créer notre requête de récupération des données :

$sites = $pdo->query('SELECT * FROM monitoring');
foreach($sites->fetchAll() as $site):
    // Traitement du monitoring HTTP

    // Traitement du monitoring DNS
endforeach;

Tester l’accès HTTP

Ensuite, on va tester si l’accès au site est bien possible. Pour cela, il vous suffit de tenter d’ouvrir une connexion PHP entre votre script et votre serveur avec la fonction fopen pointant sur l’IP. Si la connexion s’effectue, la fonction va vous retourner le code brut de votre script, si votre serveur est indisponible, alors votre fonction retournera false.

$sites = $pdo->query('SELECT * FROM monitoring');
foreach($sites->fetchAll() as $site):
    // Traitement du monitoring HTTP
    $ping = (bool) @fopen('http://'.$site['ip'].'/', "r");

    // Traitement du monitoring DNS
endforeach;

En ajoutant un (bool) avant la fonction, on s’assure que celle-ci ne nous renvoit pas le code source du site, mais simplement la valeur true. de la même manière, en ajoutant un @ avant le nom de la fonction, je demande à PHP de ne pas renvoyer d’erreur mais simplement un false si quelque chose ne se passe pas bien (comme le fait que votre serveur ne réponde pas).

Tester le paramétrage DNS

Nous allons maintenant tester le paramétrage des DNS. Cette étape est assez important en fonction de votre configuration. En effet, nous allons vérifier que le serveur correspondant au nom de domaine est bien le bon. En effet, il existe de nombreux cas ou votre nom de domaine pourrait pointer vers un serveur, certe, fonctionnel, mais ne vous appartenant pas pour autant. (Cela m’arrive malheureusement régulièrement avec des clients qui pensent bien faire en modifiant eux-même leur nom de domaine et qui en fait, plombe totalement leur site internet sans même vous prévenir … Pour après vous en blâmer).

Pour cela, il existe une fonction toute faite ! gethostbyname qui prend comme paramètre le nom de domaine recherché et vous renvoi l’IP vers lequel celui-ci redirige. Il suffit alors de vérifier si l’IP répondu correspond bien à notre IP.

$sites = $pdo->query('SELECT * FROM monitoring');
foreach($sites->fetchAll() as $site):
    // Traitement du monitoring HTTP
    $http = (bool) @fopen('http://'.$site['ip'].'/', "r");

    // Traitement du monitoring DNS
    $dns = gethostbyname($site['domain']) == $site['ip'];
endforeach;

Vérification du monitoring

Il reste tout de même une dernière étape avant d’alerter quiconque en cas de problème. Car effectivement, si dès que vous détectez un soucis dans votre monitoring vous envoyez en e-mail, alors dites-vous que tant que votre problème n’est pas réglé, vous allez harcelé par votre propre serveur. Pour cela, il ne faut donc pas oublier de vérifier que l’état actuel des DNS ou du HTTP est différent du précédant état de votre site.

$sites = $pdo->query('SELECT * FROM monitoring');
foreach($sites->fetchAll() as $site):
    // Traitement du monitoring HTTP
    $http = (bool) @fopen('http://'.$site['ip'].'/', "r");

    // Traitement du monitoring DNS
    $dns = gethostbyname($site['domain']) == $site['ip'];

    if($dns != $site['dns'] || $http != $site['http']):
        // On met à jour le site dans la base de donnée
        $pdo->query('UPDATE monitoring SET http = '.$site['http'].', dns = '.$site['dns'].', time = '.time().' WHERE id = '.$site['id']);

        // On n'alerte qu'à cette condition
    endif;
endforeach;

Alerte

Pour les alertes, je vous laissez gérer comme vous le souhaitez. Vous pouvez vous envoyer un mail, un SMS, une notification push … Tout ce qui compte, c’est que vous ayez toutes les informations nécessaire pour traiter le problème le plus rapidement possible. Ainsi, avec ce script, vous saurez :

  • Depuis combien de temps l’alerte est en place (ou depuis combien de temps le site est en ligne)
  • Qu’est-ce qui empêche vos utilisateurs d’accéder à votre site :
    • Votre serveur ne répond plus ?
    • Vos DNS sont mal configurés ?

III/ Paramétrer la tâche CRON

Il vous manque maintenant le plus important, la mise en production de votre script. Ici, nous allons demander à votre serveur (ce sera un debian 6.0 pour ma part) de lancer votre tâche CRON toutes les 3 minutes. Vous pouvez faire varier cette intervale mais plus elle augmente, moins vous serez réactif, plus elle diminue, plus vos serveurs vont travailler.

Nous supposerons que le chemin d’accès à mon script de monitoring soit à l’adresse suivante : /var/www/monitoring/cron.php et que vous avez les droits d’administration de votre serveur (un petit sudo et hop !)

Nous allons éditer le cron général de votre serveur. Pour se faire, connectez vous à votre terminal puis tapez la commande suivante :

$ crontab -e

Votre fichier CRON va s’ouvrir avec votre éditeur de texte préféré. Il vous suffira alors d’ajouter la ligne suivante :

*/3 * * * * php -f /var/www/monitoring/cron.php

Et voila, votre service de monitoring est en place. C’est plutôt cool, et surtout indispensable de savoir, avant votre client, quand ça va chauffer pour vos oreilles.