Claude Code & Prometheus: Metriken und Alerting für Node.js einrichten
Ein Service, der läuft, ist kein Service, der beobachtbar ist. Der Unterschied zeigt sich erst dann, wenn etwas schiefläuft: entweder hast du Metriken, die dir sagen, wann und wo — oder du hast einen Alarm vom Kunden. Prometheus ist der De-facto-Standard für Metriken in produktionsreifen Node.js-Anwendungen, und dieser Artikel zeigt, wie du ihn von Null an einrichtest: prom-client, Counter, Gauge, Histogram, den /metrics-Endpoint, Scrape-Config, AlertManager und ein Grafana-Dashboard.
Claude Code beschleunigt dabei den Boilerplate erheblich: Metrik-Definitionen, Alert-Regeln, PromQL-Abfragen für das Dashboard — alles was repetitiv und fehleranfällig ist, lässt sich generieren und direkt in den Kontext einbinden.
Claude Code Mastery — Produktionsreife Workflows auf Deutsch
Monitoring ist ein Teil davon. Der Kurs zeigt, wie du Claude Code vollständig in deinen Entwicklungsalltag integrierst — Agents, Hooks, MCP-Server, Multi-Agent-Workflows. Einmalig bezahlt, kein Abo.
Zum Kurs — Jetzt starten → Einmalzahlung · Kein Abo · 14 Tage Rückgaberecht1. Prometheus Grundkonzepte
Prometheus ist ein Pull-basiertes Monitoring-System: es fragt deine Anwendung regelmäßig nach Metriken, anstatt dass die Anwendung sie aktiv wegschickt. Das hat einen wichtigen Vorteil — der Monitoring-Stack ist von deiner Anwendungslogik entkoppelt. Deine App stellt einen /metrics-Endpoint bereit, Prometheus scrapt ihn in konfigurierbaren Intervallen.
Die vier Metrik-Typen, die du kennen musst:
- Counter: Zählt monoton aufwärts — HTTP-Requests, verarbeitete Jobs, aufgetretene Fehler. Wird nie zurückgesetzt (außer bei einem Neustart). Sinnvoll mit
rate()in PromQL. - Gauge: Kann rauf und runter gehen — aktuelle Verbindungen, Speicherverbrauch, Queue-Tiefe. Misst einen Zustand zu einem bestimmten Zeitpunkt.
- Histogram: Misst Verteilungen — klassisch für Request-Latenz. Teilt Beobachtungen in konfigurierbare Buckets auf und ermöglicht Perzentil-Abfragen (p50, p95, p99).
- Summary: Ähnlich wie Histogram, berechnet Perzentile aber clientseitig. Weniger flexibel für nachträgliche Abfragen, dafür ohne Bucket-Konfiguration.
Faustregel: Histogram für Latenz und Request-Größen, Counter für Ereignisse, Gauge für Zustände. Summary ist in den meisten Fällen die schlechtere Wahl gegenüber Histogram — Prometheus empfiehlt Histograms offiziell für Latenz-Metriken.
2. prom-client in Node.js einbinden
Das offizielle Prometheus-Client für Node.js ist prom-client. Installation:
npm install prom-client
Grundlegende Einrichtung in einer Express-Anwendung:
const express = require('express');
const client = require('prom-client');
const app = express();
// Default-Metriken aktivieren (Node.js-Prozess-Metriken)
const register = new client.Registry();
client.collectDefaultMetrics({ register });
// /metrics Endpoint
app.get('/metrics', async (req, res) => {
res.set('Content-Type', register.contentType);
res.end(await register.metrics());
});
app.listen(3000);
collectDefaultMetrics aktiviert automatisch eine Reihe nützlicher Node.js-Metriken: Heap-Verbrauch, Event-Loop-Lag, aktive Handles, CPU-Zeit. Das sind gute Basismetriken ohne zusätzliche Arbeit.
3. Counter, Gauge, Histogram, Summary
Counter
const httpRequestsTotal = new client.Counter({
name: 'http_requests_total',
help: 'Gesamtanzahl HTTP-Requests',
labelNames: ['method', 'route', 'status_code'],
registers: [register],
});
// In der Route:
app.get('/api/users', (req, res) => {
// ... Handler-Logik
httpRequestsTotal.inc({ method: 'GET', route: '/api/users', status_code: 200 });
res.json(users);
});
Gauge
const activeConnections = new client.Gauge({
name: 'active_connections',
help: 'Anzahl aktiver WebSocket-Verbindungen',
registers: [register],
});
// Bei Verbindungsaufbau:
activeConnections.inc();
// Bei Verbindungsabbau:
activeConnections.dec();
Histogram
const httpRequestDuration = new client.Histogram({
name: 'http_request_duration_seconds',
help: 'Request-Dauer in Sekunden',
labelNames: ['method', 'route', 'status_code'],
buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5],
registers: [register],
});
// Als Middleware:
app.use((req, res, next) => {
const end = httpRequestDuration.startTimer();
res.on('finish', () => {
end({ method: req.method, route: req.path, status_code: res.statusCode });
});
next();
});
4. Custom Metrics
Über die Standard-Metriken hinaus willst du in der Regel anwendungsspezifische Metriken messen. Typische Beispiele:
// Business-Metriken
const ordersProcessed = new client.Counter({
name: 'orders_processed_total',
help: 'Verarbeitete Bestellungen gesamt',
labelNames: ['status'],
registers: [register],
});
const queueDepth = new client.Gauge({
name: 'job_queue_depth',
help: 'Anzahl wartender Jobs in der Queue',
registers: [register],
});
const dbQueryDuration = new client.Histogram({
name: 'db_query_duration_seconds',
help: 'Dauer von Datenbankabfragen',
labelNames: ['query_type', 'table'],
buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1],
registers: [register],
});
Claude Code hilft dir dabei, die richtigen Metrik-Typen und sinnvolle Label-Schemas zu wählen. Beschreibe, was du messen willst, und es schlägt die passende Implementierung vor — inklusive der Bucket-Grenzen für Histograms, die für dein spezifisches Latenz-Profil sinnvoll sind.
5. /metrics Endpoint absichern
Der /metrics-Endpoint sollte nicht öffentlich erreichbar sein — er enthält interne Informationen über deinen Service. Zwei gängige Ansätze:
// Option A: Separater Port (empfohlen)
const metricsApp = express();
metricsApp.get('/metrics', async (req, res) => {
res.set('Content-Type', register.contentType);
res.end(await register.metrics());
});
metricsApp.listen(9090, '127.0.0.1'); // Nur intern erreichbar
// Option B: Bearer-Token-Schutz
app.get('/metrics', (req, res, next) => {
const token = req.headers['authorization'];
if (token !== `Bearer ${process.env.METRICS_TOKEN}`) {
return res.status(401).end();
}
next();
}, async (req, res) => {
res.set('Content-Type', register.contentType);
res.end(await register.metrics());
});
Port-Binding: Wenn du einen separaten Port verwendest, binde ihn an 127.0.0.1, nicht an 0.0.0.0. Prometheus läuft im selben Netzwerk und erreicht ihn trotzdem — aber er ist von außen nicht erreichbar.
6. Scrape-Konfiguration
Prometheus muss wissen, welche Endpoints es scrapen soll. In prometheus.yml:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'node-app'
static_configs:
- targets: ['localhost:9090']
metrics_path: '/metrics'
- job_name: 'node-exporter'
static_configs:
- targets: ['localhost:9100']
Mit Docker Compose:
services:
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "127.0.0.1:9091:9090"
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=15d'
7. AlertManager
Prometheus wertet Alert-Regeln aus und sendet Alerts an den AlertManager, der für das Routing, Grouping und die eigentliche Benachrichtigung zuständig ist. Alert-Regel-Datei alerts.yml:
groups:
- name: node-app
rules:
- alert: HighErrorRate
expr: |
rate(http_requests_total{status_code=~"5.."}[5m])
/ rate(http_requests_total[5m]) > 0.05
for: 5m
labels:
severity: warning
annotations:
summary: "Fehlerquote über 5%"
description: "{{ $value | humanizePercentage }} der Requests schlagen fehl"
- alert: HighLatency
expr: |
histogram_quantile(0.95,
rate(http_request_duration_seconds_bucket[5m])
) > 1
for: 10m
labels:
severity: critical
annotations:
summary: "p95-Latenz über 1 Sekunde"
AlertManager-Konfiguration für Slack:
route:
group_by: ['alertname', 'severity']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: 'slack-notifications'
receivers:
- name: 'slack-notifications'
slack_configs:
- api_url: '${SLACK_WEBHOOK_URL}'
channel: '#alerts'
title: '{{ .GroupLabels.alertname }}'
text: '{{ range .Alerts }}{{ .Annotations.description }}{{ end }}'
8. Grafana-Dashboard bauen
Grafana visualisiert die Daten aus Prometheus. Nach der Einrichtung der Prometheus-Datasource (URL: http://prometheus:9090) kannst du Dashboards bauen. Vier unverzichtbare Panels für eine Node.js-Anwendung:
# Request-Rate (Requests/Sekunde)
rate(http_requests_total[5m])
# Fehlerquote
rate(http_requests_total{status_code=~"5.."}[5m])
/ rate(http_requests_total[5m])
# p95-Latenz
histogram_quantile(0.95,
rate(http_request_duration_seconds_bucket[5m])
)
# Node.js Heap-Verbrauch
nodejs_heap_size_used_bytes / nodejs_heap_size_total_bytes
Claude Code kann komplette Grafana-Dashboard-JSON-Definitionen generieren. Beschreibe, welche Metriken du siehst willst und welches Layout du dir vorstellst — es produziert die Dashboard-JSON, die du direkt in Grafana importieren kannst.
9. PromQL-Grundlagen
PromQL ist die Abfragesprache von Prometheus. Die wichtigsten Funktionen:
rate(metric[5m])— Durchschnittliche Rate pro Sekunde über die letzten 5 Minuten. Für Counter-Metriken, nie für Gauges.increase(metric[1h])— Absoluter Zuwachs über einen Zeitraum. Nützlich für "wie viele Requests in der letzten Stunde".histogram_quantile(0.95, rate(...))— Berechnet Perzentile aus Histogram-Buckets. Das p95 ist die häufigste Latenz-Metrik.sum by (label)(metric)— Aggregiert Metriken und gruppiert nach einem Label. Für "Fehler nach Route" o.ä.avg_over_time(metric[1h])— Durchschnitt über Zeit für Gauge-Metriken.
"PromQL sieht zunächst komplex aus, aber 80% der Dashboards kommen mit vier Funktionen aus: rate(), histogram_quantile(), sum by() und avg_over_time(). Den Rest lernst du, wenn du ihn brauchst."
Ein vollständiges Beispiel — Fehlerquote nach Route, nur für Routen mit mehr als 10 Requests/Minute:
sum by (route) (
rate(http_requests_total{status_code=~"5.."}[5m])
)
/
sum by (route) (
rate(http_requests_total[5m])
)
> 0 and
sum by (route) (
rate(http_requests_total[5m])
) > 10/60
Verwandte Artikel, die auf diesem Thema aufbauen:
- Claude Code Debugging — Bugs mit Claude Code systematisch finden und beheben
- Claude Code für Unternehmen — Deployment, Zugriffskontrolle und Team-Workflows
Claude Code Mastery — von Monitoring bis zum produktiven Agenten
Prometheus ist ein Baustein. Im Kurs lernst du, wie du Claude Code vollständig in deinen Stack integrierst — Agents, Hooks, MCP-Server, Multi-Agent-Workflows. Vollständig auf Deutsch, einmalig bezahlt.
Jetzt starten → Einmalzahlung · Kein Abo · 14 Tage RückgaberechtKurs · Claude Code Mastery
Von Monitoring zum produktiven AI-Agenten
Prometheus. Agents. MCP. Hooks. Multi-Agent-Workflows. Alles auf Deutsch, einmalig bezahlt — kein Abo, keine Plattformabhängigkeit.
Einmalzahlung · Kein Abo · 14 Tage Rückgaberecht