Superlog auto-hébergé : installation et empreinte réelle
Découvrez ce que Superlog installe vraiment : Postgres, ClickHouse, OpenTelemetry et quatre services Node, avec ses limites avant de le lancer sur votre VPS.
Ce que l’auto-hébergement de Superlog installe réellement
Pour auto-héberger Superlog, vous clonez le dépôt, démarrez Postgres, ClickHouse et un collecteur OpenTelemetry avec Docker Compose, exécutez une migration de base de données, puis démarrez quatre services Node depuis les sources. Vos applications envoient leurs traces, journaux et métriques OTLP (protocole OpenTelemetry) vers un port de réception. Superlog les identifie, regroupe les occurrences répétées dans un incident unique, puis l’agent runner communautaire par défaut enregistre un résumé local de l’incident. L’installation prend un après-midi. L’empreinte et les limites réelles sont les points à lire avant de commencer.
Superlog est distribué sous licence Apache 2.0 et son code se trouve sur github.com/superloglabs/superlog. Au 13 octobre 2026, le projet compte environ 1.5k stars, environ 490 commits sur main, et aucune release taguée. Épinglez vous-même un commit au lieu d’exécuter la version correspondant à main le matin où vous l’avez cloné.
Ce à quoi Superlog répond, contrairement à Uptime Kuma et Langfuse
Les outils de monitoring auto-hébergés semblent interchangeables au premier abord. Ils ne le sont pas, et choisir le mauvais outil vous fait mobiliser un serveur sans aucun bénéfice.
- Uptime Kuma sonde vos endpoints depuis l’extérieur et répond à une seule question : est-il disponible ?
- Zabbix surveille les hôtes et les services sur Ubuntu 24.04, en contrôlant le CPU, la mémoire, le disque et l’état des services par rapport aux seuils que vous définissez.
- Langfuse trace les appels LLM, en enregistrant pour chacun le prompt, le modèle, les tokens, la latence et le coût.
- Superlog exploite la télémétrie déjà émise par vos services courants et transforme les défaillances répétées en incidents.
Superlog répond à une autre question : quelque chose est en panne, qu’est-ce qui est en panne et pourquoi ? Il ne se prononce pas sur les appels LLM et ne vous sonde pas depuis l’extérieur. Il ingère l’OTLP émis par le code habituel de vos applications et place un agent à l’étape de triage, c’est-à-dire lors de la première analyse qu’effectuerait de toute façon un opérateur d’astreinte.
Pour le budget d’un VPS, la distinction importante concerne le stockage. Superlog intègre un column store, car la télémétrie est écrite une seule fois, puis interrogée par plage temporelle sur des millions de lignes. C’est précisément le rôle de ClickHouse, contrairement à Postgres. Postgres reste toutefois présent dans la stack pour stocker les petites données relationnelles : projets, utilisateurs, incidents et clés d’ingestion.
Que démarre réellement docker compose up -d ?
Trois conteneurs, et aucun ne correspond à Superlog. Cela surprend les personnes qui s’attendent à une installation en une seule commande.
postgres:16, publié sur le port hôte 5434clickhouse/clickhouse-server:26.1, sur le port 8123 pour HTTP et 9000 pour le protocole natifotel/opentelemetry-collector-contrib:0.150.1, sur le port 4317 pour gRPC et 4318 pour OTLP sur HTTP
Les applications Superlog s’exécutent sur l’hôte, depuis les sources, et sont lancées par pnpm dev. Au 13 octobre 2026, le dépôt ne contient aucun fichier compose destiné à la production. Une installation durable nécessite donc vos propres unités systemd ou les Dockerfiles fournis dans l’arborescence, un par application. Les applications api, worker et proxy disposent chacune d’un script start servant à encapsuler une unité. L’application web n’en possède pas : c’est une application Vite. Vous devez donc la construire avec son script build, puis servir les fichiers générés comme fichiers statiques depuis nginx ou Caddy, ou exécuter son script preview, qui correspond à vite preview.
Gardez en tête le chemin parcouru par une requête, car chaque erreur ci-dessous correspond à une rupture sur l’un de ses sauts. Votre application envoie les données OTLP au proxy d’ingestion Superlog. Le proxy authentifie la requête avec votre clé d’ingestion, lui ajoute l’identifiant du projet, puis la transmet au collector. Le collector supprime tous les attributs superlog.* que le client a tenté de définir, ajoute superlog.project_id à partir de l’en-tête fourni par le proxy, regroupe les données, puis les écrit dans ClickHouse. L’application web et l’API relisent ensuite la télémétrie depuis ClickHouse et récupèrent toutes les autres données depuis Postgres.
La suppression de ces attributs constitue un véritable contrôle de la multi-location, et non un simple élément décoratif. Sans elle, toute personne disposant d’une clé d’ingestion valide pourrait définir elle-même superlog.project_id et écrire dans les données d’un autre projet.
Quelle taille faut-il prévoir pour le VPS ?
Prévoyez 4 vCPU, 8 Go de RAM et 40 Go de SSD pour une installation sur un seul nœud avec un faible volume d’ingestion. Il s’agit d’un seuil de planification, pas d’une mesure. Utilisez-le comme point de départ et comparez-le à votre propre trafic.
La mémoire est utilisée à quatre endroits. ClickHouse est conçu pour des machines disposant de beaucoup de RAM, et ses valeurs par défaut partent de cette hypothèse. Postgres 16 reste modeste dans ce cas, car il stocke les métadonnées et non la télémétrie. Le collector est également modeste. Les quatre processus Node comprennent un serveur de développement Vite et trois processus tsx watch. Mesurez leur consommation mémoire sur votre propre machine.
Le disque est le problème plus discret. pnpm install dans ce monorepo installe le SDK AWS, un client ClickHouse, le SDK OpenTelemetry et une toolchain React avant même que vous n’ayez ingéré une seule span. ClickHouse augmente ensuite avec votre trafic. Mesurez les deux éléments suivants :
df -h /
free -m
docker stats --no-stream
docker compose exec clickhouse clickhouse-client --database superlog --query "SELECT table, formatReadableSize(sum(bytes_on_disk)) AS size FROM system.parts WHERE active AND database = 'superlog' GROUP BY table ORDER BY sum(bytes_on_disk) DESC"La charge la plus problématique vient des pics : un déploiement défectueux peut produire des milliers d’erreurs identiques par minute. Le fingerprinting les regroupe en un seul incident pour le lecteur, mais ClickHouse écrit toujours chaque ligne sous-jacente.
C’est à vous de définir la durée de rétention. L’exporter ClickHouse du collector crée les tables, otel_traces, otel_logs et une table par type de métrique. Il n’applique une durée de vie que si la configuration dans infra/collector/config.yaml en définit une. Rien n’expire automatiquement. Un mois de forte activité peut donc remplir tout le disque si vous ne l’anticipez pas.
Installer depuis un commit épinglé
git clone https://github.com/superloglabs/superlog.git
cd superlog
git tag -l
git log -1 --format='%H %cs %s'git tag -l n’affichant rien est le résultat attendu au 13 octobre 2026. Choisissez le commit que vous avez testé et restez dessus :
git checkout 0d3a6c8bb63eda3493e6ba0003e7c2a70750bc1ePassons ensuite à la toolchain :
node -v
corepack enable
corepack prepare pnpm@9.12.0 --activate
pnpm -vpackage.json déclare engines.node comme >=20.0.0 et packageManager comme pnpm@9.12.0. Une version incompatible de Node n’arrête pas automatiquement l’installation : l’application des versions requises par le moteur dépend de la configuration, et pnpm 9.12.0 suit un chemin d’avertissement lorsque engineStrict est désactivé. Le paquet nodejs disponible dans l’archive Ubuntu 24.04 est antérieur à la version 20. Installez donc Node 20 ou une version ultérieure depuis NodeSource ou avec nvm. Le dépôt fournit un .nvmrc. nvm use sélectionne donc la version prévue si nvm est installé.
pnpm install
docker compose up -d
docker compose psAttendez les health checks au lieu de considérer que up -d signifie que le service est prêt. Postgres et ClickHouse en déclarent chacun un dans le fichier compose :
curl -sS http://127.0.0.1:8123/ping
pg_isready -h 127.0.0.1 -p 5434 -U postgresClickHouse répond sur Ok. et pg_isready répond sur accepting connections. Une connexion refusée sur 8123 signifie que le conteneur est encore en cours de démarrage ou qu’il s’est arrêté. docker compose logs clickhouse indique lequel de ces cas s’applique, et docker inspect $(docker compose ps -q clickhouse) | grep -i oomkilled signale true lorsque le kernel l’a tué pour manque de mémoire. Cela indique que la machine est trop petite, et non que votre configuration est incorrecte.
Passons ensuite à la migration et aux applications :
pnpm --filter @superlog/db db:migrate
pnpm devNotez le port : 5434, et non 5432. Le fichier compose publie Postgres sur 5434 pour éviter un conflit avec une instance Postgres déjà installée sur l’hôte. Les fichiers .env.example de l’application utilisent le même port, avec DATABASE_URL=postgres://postgres:postgres@localhost:5434/superlog. Si vous dirigez la migration vers 5432 sur une machine qui exécute déjà Postgres, vous obtenez soit une connexion refusée, soit, pire encore, une migration appliquée à la mauvaise base de données.
pnpm dev exécute turbo run dev. Cela démarre le script dev de chaque application via Turborepo, notamment api, web, worker et proxy, et mélange leur sortie dans un seul terminal. Le Procfile du dépôt liste les mêmes quatre processus et redirige la sortie de chacun vers tmp/logs/. Lancez-le avec un Procfile runner tel que overmind ou foreman plutôt qu’avec pnpm dev si vous voulez surveiller ingest dans tail -f tmp/logs/proxy.log. Le README indique l’application web sur http://localhost:5173, l’API sur http://localhost:4100 et l’ingestion OTLP sur http://localhost:4101.
Vérifiez ce qui écoute réellement avant de lui envoyer des requêtes :
ss -lntp | grep -E '4000|4100|4101|5173'
curl -sS http://127.0.0.1:4101/healthCela aura son importance plus tard. Le proxy lit son propre port dans la variable d’environnement PORT et utilise 4000 par défaut lorsque PORT n’est pas définie. Le apps/proxy/.env.example qu’il charge définit également PORT=4000, même si le README indique l’ingestion sur 4101 (les deux vérifications ont été effectuées le 13 octobre 2026). Utilisez le port indiqué par ss. Les exemples ci-dessous utilisent 4101. Remplacez-le par 4000 si c’est ce port qui écoute. Une unité systemd que vous écrivez vous-même ne définit rien, sauf si vous y ajoutez PORT. Un exporter configuré pour 4101 alors que le proxy écoute sur 4000 échoue donc avec une connexion refusée, sans fournir d’autre indication.
Envoyer une trace, produire une erreur, observer un incident
Créez un projet dans l’application web et copiez sa clé d’ingestion. Le point d’ingestion authentifie chaque requête avec cette clé. Les données de télémétrie envoyées sans clé n’atteignent donc jamais ClickHouse.
Pointez n’importe quel SDK OpenTelemetry vers le point d’ingestion à l’aide des variables d’environnement standard :
export OTEL_SERVICE_NAME=checkout-api
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4101
export OTEL_EXPORTER_OTLP_HEADERS='x-api-key=YOUR_INGEST_KEY'Le point d’ingestion lit la clé dans l’en-tête x-api-key. Il accepte également authorization: bearer YOUR_INGEST_KEY si votre exporter est plus facile à configurer de cette manière. Il expose les trois chemins OTLP standard, /v1/traces, /v1/logs et /v1/metrics, ainsi que /health.
Un piège mérite d’être signalé. OTEL_EXPORTER_OTLP_ENDPOINT est une URL de base à laquelle le SDK ajoute le chemin correspondant au signal. Les variables propres à chaque signal, telles que OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, sont utilisées exactement telles quelles, sans ajout de chemin. Si vous définissez la variable propre au signal sur http://127.0.0.1:4101, chaque export est envoyé vers /. Ce chemin ne correspond à aucune route. Rien n’arrive donc au point d’ingestion et le SDK journalise un échec d’export, alors que votre application semble fonctionner normalement.
Pour un service Node, le chemin sans modification du code suffit à vérifier le pipeline :
npm install @opentelemetry/api @opentelemetry/auto-instrumentations-node
node --require @opentelemetry/auto-instrumentations-node/register server.jsProvoquez maintenant volontairement une erreur. N’importe quelle route qui lève une exception convient :
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/boomVérifiez les étapes dans l’ordre. La première rupture indique l’étape qui a échoué :
tail -n 50 tmp/logs/proxy.log
docker compose exec clickhouse clickhouse-client --database superlog --query 'SELECT count() FROM otel_traces'Si le compteur otel_traces augmente alors que l’application web reste vide, le projet ne correspond pas à la clé utilisée. Vérifiez donc à quel projet la clé d’ingestion appartient. Un compteur qui reste stable alors que le journal du proxy montre de l’activité indique un problème au niveau du collector ou de l’écriture dans ClickHouse. Consultez docker compose logs collector. Si le journal du proxy ne contient aucune activité, l’exporter n’a jamais atteint le point d’ingestion : port incorrect, chemin incorrect ou clé rejetée.
Dans l’application web, ces échecs répétés apparaissent comme un seul incident, et non comme une ligne par requête. Superlog calcule l’empreinte des signaux entrants et regroupe ceux qui correspondent. La différence est importante : la boîte de réception contient alors un seul élément au lieu de 4,000 erreurs identiques. L’agent runner communautaire par défaut enregistre ensuite un résumé d’incident local pour ce groupe.
Une investigation assistée par un modèle nécessite de configurer un fournisseur de modèles et un agent runner compatible. Le runner communautaire par défaut enregistre un résumé local. Reprenez les noms de ces variables dans le fichier .env.example présent dans le répertoire de chaque application du commit que vous avez épinglé, plutôt que dans une documentation externe, car ils évoluent avec main. Il en va de même pour les intégrations GitHub et Sentry, qui fournissent leurs propres documents de configuration dans docs/github-app-setup.md et docs/sentry-app-setup.md. La structure des payloads de webhook est documentée dans docs/webhooks.md.
Gardez l’ingestion privée et l’agent en lecture seule
Docker publie par défaut les ports des conteneurs sur 0.0.0.0, et ces ports publiés contournent ufw. Docker achemine le trafic des conteneurs dans la table nat. Un paquet destiné à un port publié est donc redirigé avant d’atteindre les chaînes INPUT et OUTPUT, où se trouvent les règles d’ufw. Ufw n’a alors aucun contrôle sur ce trafic. Sur un VPS doté d’une adresse IP publique, le fichier Compose fourni expose ClickHouse HTTP sur 8123 et Postgres sur 5434, ce qui les rend accessibles depuis Internet. Les identifiants de ce fichier sont ceux du développement : l’utilisateur ClickHouse default avec un mot de passe vide, et Postgres avec postgres comme nom d’utilisateur et comme mot de passe.
Liez ces ports à loopback. Chaque port publié dans le fichier Compose utilise une variable d’environnement pour son côté hôte. Il suffit donc de créer un fichier .env à la racine du dépôt :
POSTGRES_HOST_PORT=127.0.0.1:5434
CLICKHOUSE_HTTP_HOST_PORT=127.0.0.1:8123
CLICKHOUSE_TCP_HOST_PORT=127.0.0.1:9000
COLLECTOR_GRPC_HOST_PORT=127.0.0.1:4317
COLLECTOR_HTTP_HOST_PORT=127.0.0.1:4318Vérifiez le résultat avant de lui faire confiance, puis recréez les conteneurs :
docker compose config
docker compose up -d
ss -lntp | grep -E '5434|8123|9000|4317|4318'docker compose config affiche le fichier résolu. Vous pouvez ainsi lire 127.0.0.1:5434:5432 au lieu de faire des suppositions. ss doit ensuite afficher 127.0.0.1:5434, et jamais 0.0.0.0:5434. Il suffit de redéclarer ports dans un fichier d’override Compose pour conserver les deux bindings lorsque l’adresse IP de l’hôte change. Compose 2.24.4 et les versions ultérieures prennent en charge ports: !override pour remplacer la liste.
L’ingestion nécessite la même attention. Votre clé d’ingestion est transmise dans un en-tête. Elle doit donc être protégée par TLS (transport layer security) : terminez TLS dans nginx ou Caddy en amont du proxy, ou gardez l’ingestion dans un réseau privé ou un tunnel WireGuard. L’application web sur 5173 est un serveur de développement Vite. Elle ne doit pas être exposée sur Internet.
Passons ensuite à l’agent lui-même. Superlog indique que l’agent analyse les problèmes et propose un correctif. Le terme important est « propose ». Gardez-le en lecture seule sur la production jusqu’à ce que vous l’ayez observé sur plusieurs incidents réels. Une GitHub App en lecture seule ne peut pas pousser une branche de correctif ni ouvrir de pull request. Le guide de configuration exige les permissions d’écriture Contents et Pull requests pour ce workflow, ainsi que la permission d’écriture Issues pour les commentaires. Un agent qui lit la télémétrie et écrit un correctif peut être utile. Un agent capable de redémarrer vos services représente un niveau de risque différent. Cette décision doit être prise volontairement, et non héritée d’une configuration par défaut. Le coût mérite la même attention lors de la configuration d’un runner utilisant un modèle : prévoyez le budget consacré à l’agent sur un VPS avant de le diriger vers un système de production très verbeux, et consignez ce que l’agent a réellement fait afin qu’une pull request inattendue dispose d’une piste d’audit.
Échecs courants et messages associés
ERR_PNPM_UNSUPPORTED_ENGINEpendantpnpm installsignifie qu’une exigence du moteur est incompatible. pnpm 9.12.0 vérifie les exigences de Node et de pnpm. Relevez les versions demandée et actuelle dans l’erreur, puis vérifieznode -vetpnpm -v.ECONNREFUSED 127.0.0.1:5434pendant la migration signifie que la stack Compose n’est pas démarrée, ou queDATABASE_URLindique le mauvais port.- Vérifiez les redémarrages de ClickHouse avec
docker compose logs clickhouse, puis vérifiez que le conteneur est bienOOMKilledavectrue. - Lorsqu’un exporter signale une réussite alors que l’application web reste vide, cela signifie généralement que les données sont directement parvenues au collector sur 4318, sans passer par l’ajout du project stamp effectué par le proxy.
- Un refus de connexion sur 4101 signifie généralement que le proxy écoute sur 4000, le port utilisé par défaut par son code et défini par son
.env.example. Définissez explicitementPORTdans le fichier d’unité ou dans le.envde l’application. - Si
docker compose psaffiche0.0.0.0:8123, vos bindings loopback ne sont pas actifs. Exécutezdocker compose configet consultez les ports résolus.
Flawless, HyperProbe et la place de Superlog
Cette catégorie est récente, et les outils se distinguent par ce que l’agent est autorisé à manipuler. Le dépôt Flawless présente désormais CISRE, une plateforme d’AI SRE (site reliability engineering) pour Kubernetes et les infrastructures cloud, sous licence PolyForm Noncommercial. HyperProbe place des probes dans un processus en cours d’exécution pour capturer l’état des variables et expose cet état à un assistant via MCP (model context protocol). Il documente également l’auto-hébergement avec Docker Compose et une clé de licence.
Superlog se situe entre les deux. Il gère l’ensemble du pipeline, de la réception OTLP au stockage dans ClickHouse, et place l’agent à l’étape de triage plutôt qu’à celle de la correction. C’est précisément pour cette raison que son auto-hébergement constitue une décision d’infrastructure, et non l’ajout d’un conteneur que vous pouvez oublier. Dès que vous exécutez Superlog, vous exploitez un column store. Il nécessite le même niveau de maintenance que toute autre base de données dont vous avez la responsabilité.
FAQ
De combien de RAM Superlog auto-hébergé a-t-il besoin ?
Prévoyez 8 GB de RAM, 4 vCPU et 40 GB de disque pour un nœud unique avec un faible volume d’ingestion. La stack comprend Postgres, ClickHouse, un collecteur OpenTelemetry et quatre processus Node. ClickHouse a également besoin d’une marge suffisante. Mesurez vos propres valeurs avec docker stats --no-stream et free -m au lieu de vous fier à un chiffre publié, y compris celui-ci.
Vers quel port dois-je configurer mon exportateur OTLP ?
Utilisez le proxy d’ingestion Superlog, que le README configure sur http://localhost:4101. Il fournit /v1/traces, /v1/logs et /v1/metrics. Il s’authentifie avec la clé d’ingestion de votre projet, récupérée depuis l’en-tête x-api-key ou depuis un en-tête authorization: bearer. Le port 4318 correspond au collecteur OpenTelemetry sous-jacent. Un export direct vers ce port contourne le proxy, qui est le composant chargé d’ajouter l’identifiant de votre projet aux données. Le proxy utilise le port 4000 si PORT n’est pas défini. Son .env.example définit également la valeur 4000. Exécutez donc ss -lntp et vérifiez le port sur lequel il écoute avant de supposer qu’il s’agit de 4101.
Superlog remplace-t-il Uptime Kuma ou Zabbix ?
Non. Uptime Kuma vérifie depuis l’extérieur de votre réseau si un endpoint répond. Zabbix surveille les métriques des hôtes et des services par rapport aux seuils que vous définissez. Superlog consomme les traces, les logs et les métriques émises par vos applications, puis regroupe les échecs répétés en incidents. Conservez un probe externe de disponibilité en complément. Un probe exécuté ailleurs continue ainsi de signaler les incidents lorsque le serveur qui héberge votre pipeline de télémétrie est lui-même arrêté.
L’agent Superlog peut-il modifier mes systèmes de production ?
Uniquement selon les permissions que vous lui accordez. Le runner communautaire par défaut enregistre un résumé local de l’incident. Les autres runtimes d’investigation dépendent du runner que vous configurez. Limitez les credentials de production à la lecture. La création de pull requests nécessite des permissions d’écriture GitHub distinctes pour les branches et les pull requests. Considérez l’accès en écriture à la production comme une décision distincte, à prendre délibérément. Un agent capable de redémarrer des services représente un engagement bien plus important qu’un agent qui lit la télémétrie et écrit un patch à examiner.
Dois-je figer un commit ou suivre main ?
Figez un commit. Le repository ne comportait aucun release tag au 13 octobre 2026. Notez le SHA que vous avez testé, déployez celui-ci et lisez le diff avant de passer à la version suivante. git log --oneline <old-sha>..main correspond à la revue. Les fichiers .env.example propres à chaque application sont le premier emplacement à vérifier pour repérer les nouvelles variables requises après une mise à jour.