Pourquoi Appclacks est la meilleure solution de health check blackbox du marché
J’ai récemment open source tout l’écosystème Appclacks. Je résume dans cet article pourquoi la partie health check du projet est la meilleure du marché.
Le monitoring blackbox est pénible
J’ai fait de la prod tout ma carrière, et l’observability est un sujet qui me passionne. Mais dans le monde du monitoring, un sujet en apparence simple est en fait toujours pénible: le blackbox monitoring.
Lorsqu’on déploie des services ou de l’infrastructure, on veut généralement exécuter des health checks dessus, de différents types. Par exemple:
-
Toutes les 10 secondes, exécuter une requête HTTP sur une API
-
Vérifier régulirement si un certificat TLS va expirer
-
Vérifier qu’un port TCP est ouvert et répond
En cas de problèmes, on veut être alerté. On veut aussi pouvoir facilement configure le health check à exécuter. Dans le cas d’une requête HTTP, on veut pouvoir choisir la méthode HTTP, le path, passer des paramètres, des headers, changer le code retour attendu…
Quelles sont les solutions du marché ?
Produits SaaS
Les SaaS comme statuscake permettent d’exécuter des health checks depuis plusieurs régions du monde. Ca marche, mais ce sont des solutions propriétaires qui ne fonctionnent de plus que sur des endpoints publics.
Hors aujourd’hui on a énormément d’endpoints privés (beaucoup plus que ceux publics) à surveiller (API et services internes par exemple).
De plus, le tooling laisse parfois à désirer pour certains providers SaaS. En plus, les SaaS ont toujours leurs propres formats de métriques, leurs propres moyens d’envoyer des alertes, et donc ça s’intègre toujours mal avec les plateformes d’observability internes.
Bref, on est coincé et donc généralement les équipes utilisent une combinaison de produits SaaS plus un produit self hosted. Et c’est super pénible d’avoir à maintenir deux outils.
Produit self hosted
UI cool, outillage léger
Des solutions comme uptime kuma permettent de configurer des health checks et d’avoir un dashboard.
Alors c’est joli et ça suffit pour du petit besoin mais là aussi l’outillage est généralement léger et ça s’intègre mal dans des infras "modernes" (format de métriques, customisation des checks…).
Et au final l’UI n’est pas importante si vous avez déjà un Grafana pour tout le reste de votre stack.
Blackbox exporter
Dans l’écosystème Prometheus, Blackbox exporter est l’outil permettant d’exécuter des health checks.
Ca marche, mais sa configuration est pénible, sa manière de fonctionner (les health checks s’exécutent en "scrapant" blackbox exporter avec certains paramètres) aussi.
Le service discovery avec blackbox exporter est aussi complètement lié à Prometheus et c’est aussi très pénible dans certains cas.
De manière générale je trouve l’UX de blackbox exporter dégueulasse.
Cabourotte
Il y a plus de 4 ans j’étais ultra saoulé par blackbox exporter et donc j’ai écrit Cabourotte.
C’était à la base un simple binaire Go qui exécute des health checks définis dans un fichier de configuration périodiquement. Il peut toujours s’utiliser comme cela aujourd’hui, comme expliqué dans sa doc.
demo
Voici un exemple de configuration Cabourotte avec un check HTTP et un TCP:
http:
host: "127.0.0.1"
port: 9013
http-checks:
- name: "mcorbin-http-check"
description: "http healthcheck example"
valid-status:
- 200
target: "mcorbin.fr"
port: 443
protocol: "https"
path: "/"
timeout: 5s
interval: 10s
method: "GET"
redirect: true
tcp-checks:
- name: "google-tcp-check"
target: "google.com"
port: 443
timeout: 2s
interval: 5s
Si vous installez Cabourotte, vous pouvez le lancer avec cabourotte daemon --config ~/.cabourotte.yaml --debug
: il va démarrer et commencer à exécuter les health checks:
{"level":"debug","ts":1723495850.0730598,"caller":"healthcheck/tcp.go:117","msg":"start executing healthcheck","target":"google.com","port":443,"name":"google-tcp-check"}
{"level":"debug","ts":1723495850.0731,"caller":"healthcheck/http.go:197","msg":"start executing healthcheck","target":"mcorbin.fr","port":443,"name":"mcorbin-http-check"}
{"level":"debug","ts":1723495850.584044,"caller":"exporter/root.go:128","msg":"Healthcheck successful","name":"mcorbin-http-check","labels":null,"healthcheck-timestamp":1723495850}
{"level":"debug","ts":1723495850.5841985,"caller":"exporter/root.go:128","msg":"Healthcheck successful","name":"google-tcp-check","labels":null,"healthcheck-timestamp":1723495850}
Cabourotte expose les métriques des health checks au format Prometheus sur /metrics
:
# TYPE healthcheck_duration_seconds histogram
healthcheck_duration_seconds_bucket{name="google-tcp-check",le="0.005"} 0
healthcheck_duration_seconds_bucket{name="google-tcp-check",le="0.01"} 0
healthcheck_duration_seconds_bucket{name="google-tcp-check",le="0.025"} 0
healthcheck_duration_seconds_bucket{name="google-tcp-check",le="0.05"} 1
healthcheck_duration_seconds_bucket{name="google-tcp-check",le="0.1"} 3
healthcheck_duration_seconds_bucket{name="google-tcp-check",le="0.25"} 12
healthcheck_duration_seconds_bucket{name="google-tcp-check",le="0.5"} 14
healthcheck_duration_seconds_bucket{name="google-tcp-check",le="0.75"} 16
healthcheck_duration_seconds_bucket{name="google-tcp-check",le="1"} 16
healthcheck_duration_seconds_bucket{name="google-tcp-check",le="2.5"} 16
healthcheck_duration_seconds_bucket{name="google-tcp-check",le="5"} 16
healthcheck_duration_seconds_bucket{name="google-tcp-check",le="7.5"} 16
healthcheck_duration_seconds_bucket{name="google-tcp-check",le="10"} 16
healthcheck_duration_seconds_bucket{name="google-tcp-check",le="+Inf"} 16
healthcheck_duration_seconds_sum{name="google-tcp-check"} 3.3517029240000005
healthcheck_duration_seconds_count{name="google-tcp-check"} 16
healthcheck_duration_seconds_bucket{name="mcorbin-http-check",le="0.005"} 0
healthcheck_duration_seconds_bucket{name="mcorbin-http-check",le="0.01"} 0
healthcheck_duration_seconds_bucket{name="mcorbin-http-check",le="0.025"} 0
healthcheck_duration_seconds_bucket{name="mcorbin-http-check",le="0.05"} 0
healthcheck_duration_seconds_bucket{name="mcorbin-http-check",le="0.1"} 1
healthcheck_duration_seconds_bucket{name="mcorbin-http-check",le="0.25"} 4
healthcheck_duration_seconds_bucket{name="mcorbin-http-check",le="0.5"} 6
healthcheck_duration_seconds_bucket{name="mcorbin-http-check",le="0.75"} 8
healthcheck_duration_seconds_bucket{name="mcorbin-http-check",le="1"} 8
healthcheck_duration_seconds_bucket{name="mcorbin-http-check",le="2.5"} 8
healthcheck_duration_seconds_bucket{name="mcorbin-http-check",le="5"} 8
healthcheck_duration_seconds_bucket{name="mcorbin-http-check",le="7.5"} 8
healthcheck_duration_seconds_bucket{name="mcorbin-http-check",le="10"} 8
healthcheck_duration_seconds_bucket{name="mcorbin-http-check",le="+Inf"} 8
healthcheck_duration_seconds_sum{name="mcorbin-http-check"} 2.4320273130000003
healthcheck_duration_seconds_count{name="mcorbin-http-check"} 8
# HELP healthcheck_total Count the number of healthchecks executions.
# TYPE healthcheck_total counter
healthcheck_total{name="google-tcp-check",status="success"} 16
healthcheck_total{name="mcorbin-http-check",status="success"} 8
Avec cela (bucket + counter Prometheus), il est facile de configurer des règles d’alerting quelle que soit votre stack d’observability: tous les outils (propriétaires comme open source) comprennent le format Prometheus, donc ils peuvent tous ingérer ces métriques et vous pourrez définir des règles d’alerte sur le temps d’exécution des checks ou leurs status (success ou failure). Pareil pour les dashboards.
Je le répète: je pense que les bons outils ne sont pas les outils "clés en main" mais qui s’insèrent dans l’écosystème observability. Je ne suis pas intéressé par avoir 2 outils de dashboard, ou 2 outils d’alerting: je veux des standards.
Cabourotte supporte des tonnes d’options pour les checks (voir la doc pour la liste) et 5 types de checks (TCP, HTTP, DNS, TLS, commandes shell arbitraires).
Il génère des logs en JSON, facilement consommables, supporte le hot reload sur SIGHUP, permet de pousser si besoin les résultats des checks dans des systèmes externes, via HTTP par exemple, dispose d’une API, et même d’une UI basique degueulasse pour récupérer l’état courant des checks:
On peut même exécuter des health checks one-off
avec via l’API: ce check ne va pas s’exécuter périodiquement mais s’exécutera immédiatement et vous retournera le résultat: pratique pour lancer vite fait quelques tests sur un endpoint encore non configuré.
Et on peut très bien utiliser Cabourotte comme cela: vous déployez le binaire sur un ou des serveurs, vous le configurez via fichier de configuration ou API, vous consommez ses métriques et voilà. Ca marche très bien.
Appclacks
Mais je voulais aller plus loin. C’est bien beau le fichier de configuration pour configurer les checks mais moi j’ai dizaines voir des centaines d’endpoints à monitorer, ultra dynamiques, je veux plusieurs Point of Presence pour mes checks… bref faut passer l’outil au niveau supérieur. Appclacks server est né.
Appclacks server, c’est une API HTTP avec une base de données PostgreSQL qui fournit des produits liés au monitoring. Une des fonctionnalités est de configurer les health checks pour Cabourotte.
Au lieu de créer les health checks dans Cabourotte via le fichier de configuration ou l’API, vous les créez dans Appclacks.
Il est ensuite possible de configurer Cabourotte pour venir périodiquement chercher sa configuration en tapant l’API d’Appclacks.
demo
Suivez la doc pour démarrer Appclacks + Cabourotte en local via docker compose:
Vous avez donc maintenant en local
-
PostgreSQL
-
Appclacks, qui utilise la base de données et expose une API
-
Cabourotte, configuré pour découvrir sa configuration via Appclacks.
Ici, la configuration de Cabourotte contient seulement ceci:
http:
host: "0.0.0.0"
port: 9013
discovery:
http:
- name: "http-discorery"
interval: 10s
host: "localhost"
port: 9000
protocol: "http"
path: "/api/v1/cabourotte/discovery"
Toutes les 10 secondes, Cabourotte viendra chercher les health checks configurés dans Appclacks en tapant localhost:9000/api/v1/cabourotte/discovery
et mettra sa configuration à jour. Les health checks s’exécuteront ensuite de la même façon que via le fichier de configuration.
Pourquoi c’est intéressant ? Car vous gérez tous vos définitions de health checks de manière centralisée. Vous pouvez déployer 1, 2, 3, 10… instances de Cabourotte à travers le monde et elles viendront toutes chercher leurs configurations régulièrement en tapant l’API d’Appclacks (qui supporte du Basic Auth et mTLS d’ailleurs si besoin).
On peut même sélectionner quelles health checks exécuter dans cabourotte via des labels. Par exemple passer dans l’option query.labels
de la partie discovery environment=production,team=sre
ferait que cette instance de Cabourotte n’exécuterait que les health checks configurés avec ces labels dans Appclacks (voir doc).
J’ai fait un énorme effort sur le tooling d’Appclacks pour gérer les health checks:
-
Une CLI implémentant tout ce qu’il faut pour gérer les health checks (create, update, delete, list…)
-
Un provider Terraform pour gérer les checks d’Appclacks en infra as code
-
Un Operator Kubernetes pour gérer les health checks via une Custom Resources Definitions depuis vos clusters Kubernetes
-
Un SDK Golang qui permet de facilement écrire votre outillage si besoin.
Il y en a pour tout les goûts.
Conclusion
Résultat ? On a un outil:
-
state-of-the-art sur la partie outillage (qui est obligatoire aujourd’hui pour les gens exigeants)
-
qui expose des métriques au format Prometheus, un standard du marché
-
Facile à déployer (binaires statiques + PostgreSQL, tout le monde sait faire) et à utiliser, et qui fonctionne dans tous les contextes.
-
Scalable: vous déployer autant d’instances de Cabourotte que vous voulez, chaque changement sera propagé partout lors d’un changement dans la partie définition des checks côté server.
Appclacks fournit aussi d’autres outils liés à l’observability que je présenterai dans d’autres articles prochainement.
Mais je pense qu’aujourd’hui, sur la partie health check, c’est déjà un très bon outil qui je l’espère trouvera sa place.
N’hésitez pas à l’essayer et à me faire des retours. J’ai pas voulu surcharger l’article, suivez la doc pour des exemples ;)
Add a comment
If you have a bug/issue with the commenting system, please send me an email (my email is in the "About" section).