Pivert's Blog

FrugalSentinel — Monitoring serverless à 0€


Reading Time: 6 minutes
  • Aucune VM à maintenir — pas de Docker, pas de systemd, pas de mises à jour
  • Aucune dépendance externe — pas de pip install qui casse six mois plus tard
  • Aucune base de données — état JSON sur S3, rotation automatique
  • Aucune facture — tout tient dans le free tier Scaleway (128 MB recommandé, 75 GB S3)

Architecture et choix techniques

FrugalSentinel est un monolithe minimaliste conçu pour l’immobilité : une fois déployé, il ne nécessite aucune maintenance.

Python 3.13, stdlib uniquement

Le runtime est volontairement réduit à l’os : urllib pour les requêtes HTTP, json pour la sérialisation, concurrent.futures pour le parallélisme, ssl pour l’analyse des certificats. Aucun framework, aucune bibliothèque tierce. Le code écrit aujourd’hui fonctionnera dans 5 ans sans modification.

Python a un tradeoff : les cold starts sont légèrement plus lents qu’avec Go ou Rust. Mais l’avantage est considérable : Python permet d’écrire des probes complexes en quelques lignes — comme l’API de liste des serveurs Luanti, qui nécessite du parsing JSON et de la logique de matching. Implémenter un notifier alternatif (email, webhook, Slack) est un module de 20 lignes, pas un conteneur complet.

Exécution parallèle : ThreadPoolExecutor

Tous les checks sont lancés en parallèle via ThreadPoolExecutor (8 workers). Comme 95% du temps d’exécution est passé à attendre des réponses réseau, le GIL de Python est relâché pendant ces attentes — les threads s’exécutent réellement en parallèle. Résultat : le temps total d’une run est dicté par le check le plus lent, pas par la somme de tous les checks. Avec 20 services dont le plus lent prend 2 secondes, 128 MB de RAM suffisent largement.

S3 comme seule base de données

L’état est stocké sous forme de JSON sur Scaleway Object Storage. Le client S3 est pur Python (AWS Signature V4, urllib uniquement). Pas de boto3, pas de libcurl. Zéro point de défaillance externe.

Rotation : temps réel → quotidien → mensuel gz

Les données sont organisées en trois niveaux :

Niveau Contenu Rétention Taille (19 checks)
Temps réel 48 mesures glissantes Réécrit à chaque run ~70 KB
Quotidien Résumé par jour 30 jours ~15 KB/jour
Mensuel gzip Archive compressée 18 mois+ ~200 KB/mois

À l’échelle de l’infrastructure pivert.org, l’empreinte totale sur S3 est d’environ 2 MB/mois. Le free tier S3 offre 75 GB — soit plus de 30 ans de monitoring avant d’atteindre la limite.

Dashboard statique : zéro latence, zéro coût

Le dashboard est une page HTML/CSS/JS vanilla hébergée sur le même bucket S3. Il charge le snapshot JSON via une requête statique — aucun appel à la fonction n’est nécessaire. La page se charge en moins de 500 ms. L’auto-refresh est activé par défaut, et l’heure affichée provient du fichier S3 (pas de l’horloge locale du navigateur).

→ Dashboard en direct

Modularité : ajouter un check en 4 lignes

Chaque protocole vit dans monitoring/modules/. Pour ajouter un check :

def check(config: dict) -> dict:
return {"success": bool, "msg": str, ...champs_optionnels}

Module Protocole Particularités
check_https.py HTTPS + keyword Certificat avant la requête HTTP. Auth basique. TLS insecure possible.
check_http.py HTTP statut + keyword Mot-clé dans la réponse
check_tcp.py TCP connect Timeout configurable, port arbitraire
check_smtp.py SMTP STARTTLS Port 587 (25/465 bloqués en serverless)
check_luanti.py Luanti server API Joueurs, lag, version, uptime

Alertes : confirmation progressive + récupération

Une notification n’est envoyée que si un check échoue 2 fois sur les 3 derniers runs. Une notification de récupération est automatiquement envoyée quand le service revient en ligne. Le notifier supporte ntfy.sh (instance publique ou auto-hébergée via ntfy_url), et le système permet d’implémenter facilement d’autres backends.

Souveraineté : n’importe quel cloud

FrugalSentinel fonctionne sur tout cloud avec des fonctions serverless + stockage S3-compatible : AWS Lambda + S3, Google Cloud Functions, Azure Functions, ou des clouds souverains français comme Scaleway ou OVHcloud. Un ZIP de quelques dizaines de KB contient tout le code. Aucun vendor lock-in.

Coût : 0€, scalable jusqu’à ~24 services

Scaleway Serverless Functions offre un free tier généreux : 1 000 000 requêtes/mois et 400 000 GB-s/mois. Avec les paramètres recommandés (128 MB de RAM, ~15 secondes d’exécution) :

Scénario RAM GB-s/mois % free tier
19 services × 5 min 128 MB 16 200 4,0%
24 services × 5 min 128 MB 20 480 5,1%
19 services × 1 min 128 MB 81 000 20%
+1 service supplémentaire 128 MB +853 GB-s +0,2%

Au-delà du free tier, le coût marginal est €0.000005/GB-s (€0.50/100k). Passer de 24 à 25 services toutes les 5 minutes ajouterait ~€0.004/mois. Le coût marginal d’un check est inférieur à 1 centime par mois.

Démarrer en 3 commandes

  • cp .env.example .env — renseigner vos credentials S3
  • python3 handler.py — test local (mode filesystem si pas de S3)
  • ./package.sh — génère frugalsentinel.zip prêt pour Scaleway Functions

→ README complet et code source sur GitLab

Licence

FrugalSentinel est publié sous licence GNU GPL. Dépôt public : gitlab.com/pivert/FrugalSentinel

→ Code source · → Dashboard en direct

FrugalSentinel est un système de monitoring serverless complet, écrit en Python 3.13 avec la bibliothèque standard uniquement (zéro dépendance pip), exécuté sur le free tier Scaleway Functions, stockant son état sur Scaleway Object Storage (S3), et alertant via ntfy.sh. Résultat : monitoring professionnel pour exactement 0€ par mois.

Le problème que FrugalSentinel résout

Toutes les solutions de monitoring modernes suivent le même schéma : un tier gratuit séduisant, puis un mur de facturation. Datadog, UptimeRobot, Uptime Kuma autohébergé (Docker + VM), Grafana Cloud — toutes imposent soit un coût mensuel, soit une infrastructure dédiée à maintenir.

FrugalSentinel part d’une hypothèse différente : si votre cloud fournit un tier gratuit serverless avec stockage S3, vous pouvez y faire tourner un monitoring complet sans sortir la carte bleue. L’astuce n’est pas dans l’optimisation des coûts — elle est dans l’absence totale de coût, par construction.

  • Aucune VM à maintenir — pas de Docker, pas de systemd, pas de mises à jour
  • Aucune dépendance externe — pas de pip install qui casse six mois plus tard
  • Aucune base de données — état JSON sur S3, rotation automatique
  • Aucune facture — tout tient dans le free tier Scaleway (128 MB recommandé, 75 GB S3)

Architecture et choix techniques

FrugalSentinel est un monolithe minimaliste conçu pour l’immobilité : une fois déployé, il ne nécessite aucune maintenance.

Python 3.13, stdlib uniquement

Le runtime est volontairement réduit à l’os : urllib pour les requêtes HTTP, json pour la sérialisation, concurrent.futures pour le parallélisme, ssl pour l’analyse des certificats. Aucun framework, aucune bibliothèque tierce. Le code écrit aujourd’hui fonctionnera dans 5 ans sans modification.

Python a un tradeoff : les cold starts sont légèrement plus lents qu’avec Go ou Rust. Mais l’avantage est considérable : Python permet d’écrire des probes complexes en quelques lignes — comme l’API de liste des serveurs Luanti, qui nécessite du parsing JSON et de la logique de matching. Implémenter un notifier alternatif (email, webhook, Slack) est un module de 20 lignes, pas un conteneur complet.

Exécution parallèle : ThreadPoolExecutor

Tous les checks sont lancés en parallèle via ThreadPoolExecutor (8 workers). Comme 95% du temps d’exécution est passé à attendre des réponses réseau, le GIL de Python est relâché pendant ces attentes — les threads s’exécutent réellement en parallèle. Résultat : le temps total d’une run est dicté par le check le plus lent, pas par la somme de tous les checks. Avec 20 services dont le plus lent prend 2 secondes, 128 MB de RAM suffisent largement.

S3 comme seule base de données

L’état est stocké sous forme de JSON sur Scaleway Object Storage. Le client S3 est pur Python (AWS Signature V4, urllib uniquement). Pas de boto3, pas de libcurl. Zéro point de défaillance externe.

Rotation : temps réel → quotidien → mensuel gz

Les données sont organisées en trois niveaux :

Niveau Contenu Rétention Taille (19 checks)
Temps réel 48 mesures glissantes Réécrit à chaque run ~70 KB
Quotidien Résumé par jour 30 jours ~15 KB/jour
Mensuel gzip Archive compressée 18 mois+ ~200 KB/mois

À l’échelle de l’infrastructure pivert.org, l’empreinte totale sur S3 est d’environ 2 MB/mois. Le free tier S3 offre 75 GB — soit plus de 30 ans de monitoring avant d’atteindre la limite.

Dashboard statique : zéro latence, zéro coût

Le dashboard est une page HTML/CSS/JS vanilla hébergée sur le même bucket S3. Il charge le snapshot JSON via une requête statique — aucun appel à la fonction n’est nécessaire. La page se charge en moins de 500 ms. L’auto-refresh est activé par défaut, et l’heure affichée provient du fichier S3 (pas de l’horloge locale du navigateur).

→ Dashboard en direct

Modularité : ajouter un check en 4 lignes

Chaque protocole vit dans monitoring/modules/. Pour ajouter un check :

def check(config: dict) -> dict:
return {"success": bool, "msg": str, ...champs_optionnels}

Module Protocole Particularités
check_https.py HTTPS + keyword Certificat avant la requête HTTP. Auth basique. TLS insecure possible.
check_http.py HTTP statut + keyword Mot-clé dans la réponse
check_tcp.py TCP connect Timeout configurable, port arbitraire
check_smtp.py SMTP STARTTLS Port 587 (25/465 bloqués en serverless)
check_luanti.py Luanti server API Joueurs, lag, version, uptime

Alertes : confirmation progressive + récupération

Une notification n’est envoyée que si un check échoue 2 fois sur les 3 derniers runs. Une notification de récupération est automatiquement envoyée quand le service revient en ligne. Le notifier supporte ntfy.sh (instance publique ou auto-hébergée via ntfy_url), et le système permet d’implémenter facilement d’autres backends.

Souveraineté : n’importe quel cloud

FrugalSentinel fonctionne sur tout cloud avec des fonctions serverless + stockage S3-compatible : AWS Lambda + S3, Google Cloud Functions, Azure Functions, ou des clouds souverains français comme Scaleway ou OVHcloud. Un ZIP de quelques dizaines de KB contient tout le code. Aucun vendor lock-in.

Coût : 0€, scalable jusqu’à ~24 services

Scaleway Serverless Functions offre un free tier généreux : 1 000 000 requêtes/mois et 400 000 GB-s/mois. Avec les paramètres recommandés (128 MB de RAM, ~15 secondes d’exécution) :

Scénario RAM GB-s/mois % free tier
19 services × 5 min 128 MB 16 200 4,0%
24 services × 5 min 128 MB 20 480 5,1%
19 services × 1 min 128 MB 81 000 20%
+1 service supplémentaire 128 MB +853 GB-s +0,2%

Au-delà du free tier, le coût marginal est €0.000005/GB-s (€0.50/100k). Passer de 24 à 25 services toutes les 5 minutes ajouterait ~€0.004/mois. Le coût marginal d’un check est inférieur à 1 centime par mois.

Démarrer en 3 commandes

  • cp .env.example .env — renseigner vos credentials S3
  • python3 handler.py — test local (mode filesystem si pas de S3)
  • ./package.sh — génère frugalsentinel.zip prêt pour Scaleway Functions

→ README complet et code source sur GitLab

Licence

FrugalSentinel est publié sous licence GNU GPL. Dépôt public : gitlab.com/pivert/FrugalSentinel

→ Code source · → Dashboard en direct

Like it ?

Get notified on new posts (max 1 / month)
Soyez informés lors des prochains articles

Leave a Reply

Your email address will not be published. Required fields are marked *