Rapport automatisé par mail avec GoAccess

  • bash
  • goaccess

Published at 2020-03-02

Chez iSignif, j'ai récemment décidé de remplacer Google Analytics par GoAccess. Là ou Google Analytics envoie toutes les statistiques de ton site web en temps réel au géant américain, GoAccess analyse le traffic du site en s'appuyant sur les logs du serveur web.

Au delà de respecter la vie privée de nos utilisateurs en évitant d'engrosser les californiens, cela permet aussi de retirer le popup ultra-énervant pour accepter les cookies. Cela contribue donc trÚs certainement à faire d'internet un lieu plus sympa. Rien que ça!

Le seul inconvénient est que cela repose sur une action manuelle qui n'est pas réalisable par un moldus.

Je me suis donc posé afin d'automatiser tout ça en faisant un mail automatique qui envoie tous les jour le rapport d'utilisation de iSignif. Voici un exemple:

Bonjour la team,

Aujourd'hui il y a eu 1784 visiteurs. L'heure ou il y a eu le plus de traffic a Ă©tĂ© 17 heures. Sans surprise, la page la plus visitĂ©e a Ă©tĂ© https://isignif.fr/. Il y a eu 0.09% de requĂȘtes qui on terminĂ©e en erreur 500.

Les nom de domaines suivants non on amené du traffic:

A demain.

Ça t'intĂ©resse de faire la mĂȘme chose ? Suis moi.

Récupérer le Dashboard et l'envoyer par mail

La premiĂšre chose facile Ă  faire consiste Ă  utiliser [GoAccess][goaccess] pour exporter le Dashboard au format HTML puis de se l'envoyer par mail avec la commande mail de Linux.

Tout cela se fait hyper facilement avec un script Bash qui:

  1. concatĂšne tous les logs de Apache en un seul gros fichier
  2. utilise GoAccess pour générer le rapport au fichier HTML
  3. envoie par mail l'export en piĂšce jointe

Cela donne donc ça:

# !/bin/bash

# concat logs
touch /tmp/complete_isignif_fr_access.log
cat /var/log/apache2/isignif_fr_access*.log >> /tmp/complete_isignif_fr_access.log
gzip -d /var/log/apache2/isignif_fr_access.log.*.gz --stdout >> /tmp/complete_isignif_fr_access.log

# generate HTML report
goaccess /tmp/complete_isignif_fr_access.log -o /tmp/goaccess_report.html

# send email
mail -s "Rapport d'utilisation de iSignif" support@isignif.fr -A /tmp/goaccess_report.html

La commande mail fait référence à GNU Mailutils qui est disponible par défault dans les distribution Linux. Si ce n'est pas le cas, un petit sudo apt install mailutils fait l'affaire.

J'ai mis le script dans /home/isignif/goaccess_report.sh et il suffit ensuite de définir le CRON qui va bien. Pour le rajouter, il suffit d'utiliser la commande crontab -e et de coller la ligne suivante.

0 19 * * * /bin/bash /home/isignif/goaccess_report.sh

Et voilà, tous les jours à 19h on reçoit un petit mail avec le Dashboard de GoAccess en piÚce joint.

Un mail récapitulatif pour la journée

C'est top mais tous les jours il faut prendre le temps d'ouvrir le Dashboard et de le regarder, l'interpréter, etc.. Bref, on peut faire mieux.

GoAccess permet d'exporter les résultats au format JSON. Qui dit JSON, dit utilisable par un script. Je me suis dit que je pouvait rédiger le mail qui récapitule la journée en utilisant les données extraite dans le rapport au format JSON.

Configurer les Logs de Apache2

Vu qu'on veut des statistiques par jour, on veut les logs d'apache découpés par jours (et non par taille comme le fait Apache2 par défault).

Apache gÚre ça nativement et c'est trÚs simple.

sudo vim /etc/apache2/sites-enabled/isignif.fr.conf
CustomLog "|/usr/bin/rotatelogs -f /var/log/apache2/isignif.access.%Y-%m-%d.log 86400" combined

Donc pour avoir le rapport GoAccess du jour au format JSON, ce petit snippet suffit:

TODAY=$(date '+%Y-%m-%d')
goaccess "/var/log/apache2/isignif.access.${TODAY}.log" -o /tmp/daily_goaccess_report.json

Fantastique. Essayons de lire un peu ce fichier.

Parser les résultats JSON avec jq

Afin de garder les choses les plus simples possibles, je me suis limité sur les choix des technos et j'ai préféré rester dans l'esprit UNIX, c'est à dire un outil pour chaque chose. J'ai donc choisis la librairie jq. Il s'installe avec:

sudo apt install jq

jq permet de parser un fichier JSON et de récupérer une valeur~dedans. Voici un petit exemple:

echo '{ "email": { "subject": "Hllo", "content": "Lorem ipsum" } }' | jq '.email.subject'
"Hllo"

Le résultat est étonnamment lisible et maintenable.jq s'utilise aussi parfaitement dans un script BASH et s'installe hyper facilement. C'est donc le parfait outil.

Je passe un petit peu vite sur comment l'utiliser car la documentation le fait trĂšs bien donc Read The Fucking Manual.

Pour mon cas, j'ai trouvé les informations suivantes utiles:

  • le nombre de visiteur du jour
cat /tmp/daily_goaccess_report.json | jq '.general.unique_visitors'
  • L'heure ou l'affluence a Ă©tĂ© la plus forte
cat /tmp/daily_goaccess_report.json | jq '.visit_time.data | max_by(.visitors.percents) | .data'
  • Le pourcentage de requĂȘtes qui termine en erreur 500:
cat /tmp/daily_goaccess_report.json | jq '.status_codes[][] | select(.data == "5xx Server Error") | .hits.percent' 2> /dev/null

Je te laisse en trouver d'autres.

La redaction du mail

Il suffit ensuite de mettre à Bash pour créer le corps du mail. On stock tout dans des variable et on construit notre message qu'on envoie par mail:

# ...

# generate daily JSON report
TODAY=$(date '+%Y-%m-%d')
goaccess "/var/log/apache2/isignif.access.${TODAY}.log" -o /tmp/daily_goaccess_report.json

# parsing daily JSON report
VISITORS=$(cat /tmp/daily_goaccess_report.json | jq '.general.unique_visitors')
RUSH_HOUR=$(cat /tmp/daily_goaccess_report.json | jq '.visit_time.data | max_by(.visitors.percents) | .data' | sed 's/"//g')
PERCENTAGE_500=$(cat /tmp/daily_goaccess_report.json | jq '.status_codes[][] | select(.data == "5xx Server Error") | .hits.percent' 2> /dev/null)
MOST_VIEWED_PAGE=$(cat /tmp/daily_goaccess_report.json | jq '.requests.data | max_by(.hits.count) | .data' | sed 's/"//g')
REFERRING_SITES=$(cat /tmp/daily_goaccess_report.json | jq '.referring_sites.data | sort_by(.hits.count) | reverse | .[] | "- \(.data) : \(.hits.count) requetes"' | sed 's/"//g')

# send email
cat <<EOF |
Bonjour la team,

Aujourd'hui il y a eu ${VISITORS} visiteurs. Ca a été le rush à ${RUSH_HOUR} heures (pensez y pour la com'). Sans surprise, la page la plus visitee a ete https://isignif${MOST_VIEWED_PAGE}. Il y a eu 0${PERCENTAGE_500}% de requetes qui ont terminees en erreur.

Les nom de domaines suivants nous ont amene du traffic:

${REFERRING_SITES}

A demain.
EOF
mail -s "Rapport de iSignif du ${TODAY}" support@isignif.fr

Et voilĂ . Le script final est disponible sur mon Github.

Conclusion

C'est plus compliqué mais complÚtement possible. Alors pourquoi c'est cool ? Plusieurs raisons :

  1. Parce que c'est ton script et que c'est toi qui l'a fait
  2. Cela fait apprend Ă  maĂźtriser son serveur web
  3. Tu ne dépend pas d'un service tiers de plus qui va siphonner tes donnés et celle de tes utilisateurs
  4. C'est entiĂšrement customisable

Liens

goaccess