Cachet est un système qui offre une page de statut de différents services web. Il permet de reporter rapidement et de centraliser l'état des services web d'une société / asbl / groupement…

Pour l'école, ça se trouve là: http://status.esi-bru.be

L'installation de cachet se fait en suivant la documentation officielle… à quelques changements près.

Pour le début, je suis simplement le tuto.

cd /var/www/html
git clone https://github.com/cachethq/Cachet.git
cd Cachet
git tag -l 
git checkout v2.3.13
cp .env.example .env
vim .env

Édition du fichier de configuration. Comme ce sera une BD postgresql, il faut — l'installer si ce n'est fait — créer la BD et créer un utilisateur dédié: cachet. Pour ce faire:

  1. création de la BD

    sudo -u postgres createdb cachet
    
  2. choisir un utilisateur

    sudo -u postges createuser --interactive
    
  3. lui attribuer un mot de passe — pwgen 10 -1 fait bien l'affaire — que je peux reporter dans le fichier de configuration

     psql (9.6.3)
     Saisissez « help » pour l'aide.
    
     postgres=# \password cachet
     Saisissez le nouveau mot de passe : 
     Saisissez-le à nouveau : 
     postgres=# \q
     

Pour l'installation de composer, je préfère faire confiance à mon gestionnaire de paquets et faire un apt install composer disponible depuis stretch sous debian. La génération de la clé nécessite que composer soit installé. Ensuite, l'installation de cachet se passe sans soucis.

composer install
php artisan key:generate
php artisan app:install

Il est temps d'ajouter le vhost apache2 — ou nginx — et d'activer mod rewrite.

a2enmod rewrite
<VirtualHost *:80>
    ServerName status.example.org
    ServerAlias www.status.example.org 
    ServerAdmin webmaster@example.org
    DocumentRoot /var/www/html/cachet/public

    <Directory "/var/www/html/cachet/public">
        Require all granted 
        # Used by Apache 2.4
        Options Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>


    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

À ce stade, cachet est installé… mais n'a que peu d'interêt. Il devient utile s'il est capable de se mettre à jour sans intervention humaine. Après lecture de la documentation, je comprends que cachet propose une API et que je peux le mettre à jour via… un script python par exemple.

#! /usr/bin/env python3
# -*- coding: utf-8 -*-
#
import requests
import json 

url= "http://status.example.org/api/v1/ping"

response = requests.request("GET", url)
parsed = json.loads(response.text)

print json.dumps(parsed)

Pour aider à écrire les requêtes, j'utilise la librairie python-cachetclient qui s'installe par une des deux commandes suivantes:

pip3 install python-cachetclient
pip3 install git+https://github.com/dmsimard/python-cachetclient

Les examples sont clairs et j'utilise — comme version 1 — le script à l'allure suivante:

#!/usr/bin/env python3
#
# Python script for status.example.org
#
# Author: Pierre BT
# Thanks to cahethq and python-cachetclient
#

import cachetclient.cachet as cachet
import json
import requests

ENDPOINT = 'http://status.example.org/api/v1'
API_TOKEN = '140if12345ABCDefghijkl'
SATUS_OK = 1
SATUS_PERF_ISSUES = 2
SATUS_PARTIAL_OUTAGE = 3
INCIDENT_INVESTIGATING = 1
INCIDENT_IDENTIFIED = 2
INCIDENT_WATCHING = 3
INCIDENT_FIXED = 4

SITEWEB = 'http://example.org'
SITEWEB_ID = 1

def ping_site_web(site, components_id, components, incidents):
    """ Ping site web and update status
    """
    try:
        request = requests.get(site)
        if request.status_code == 200:
            components.put(id=components_id, status=SATUS_OK) 
        else:
            components.put(id=components_id, status=SATUS_PERF_ISSUES)
            incidents.post(
                    name='Erreur ' + str(request.status_code)
                        + ' sur ' + site,
                    message=('Tout le monde est sur le pont pour régler ça…'
                        'et ce message est automatique.'),
                    status=INCIDENT_INVESTIGATING)
    except Exception as e:
        components.put(id=SITEWEB_ID, status=SATUS_PARTIAL_OUTAGE)
        incidents.post(
            name='Problème grave sur le ' + site,
            message=('Tout le monde est sur le pont pour régler ça… '
                'et ce message est automatique.'),
            status=INCIDENT_INVESTIGATING)
#
# main method
# 
components = cachet.Components(endpoint=ENDPOINT, api_token=API_TOKEN)
incidents = cachet.Incidents(endpoint=ENDPOINT, api_token=API_TOKEN)

ping_site_web(SITEWEB, SITEWEB_ID, components, incidents)

Il reste à ajouter ce script dans une tache cron et la première automatisation — certes assez basique — est en place.

Enjoy et merci aux devs !


Crédit photo chez Unsplashpar Jonathan Perez. Les grincheux·ses pourraient dire que c'est facile d'utiliser une photo d'un boite de cachets… mais ce sont des grincheux·ses non ?