Erweitertes Monitoring von TypeScript-Anwendungen: Metriken und Alarme
\nIn der modernen Entwicklung geht Monitoring über die einfache Überprüfung "lebt der Server noch" hinaus. Für TypeScript-Anwendungen, die in komplexen verteilten Umgebungen laufen, ist ein erweitertes Observability-System erforderlich. Es reicht nicht aus, nur Fehler zu protokollieren – es müssen benutzerdefinierte Leistungsmetriken gesammelt, intelligente Alarme konfiguriert und Dashboards für prädiktive Analysen erstellt werden. In diesem Artikel betrachten wir, wie professionelles Monitoring von TypeScript-Anwendungen mit modernen Tools und Best Practices umgesetzt wird.
\n\n1. Erfassung benutzerdefinierter Leistungsmetriken
\nBasis-Metriken (CPU, Speicher) liefern oft kein vollständiges Bild. Für TypeScript-Anwendungen sind Geschäftsmetriken und Laufzeitmetriken von entscheidender Bedeutung. Betrachten wir die Einrichtung der Erfassung benutzerdefinierter Metriken mit der Bibliothek prom-client (Prometheus-Client für Node.js).
Arten benutzerdefinierter Metriken
\n- \n
- Counter (Zähler) – zum Zählen von Ereignissen (Anfragen, Fehler). \n
- Gauge (Messwert) – für Werte, die steigen und fallen können (Anzahl aktiver Verbindungen). \n
- Histogram (Histogramm) – für die Verteilung von Werten (Antwortzeit). \n
- Summary (Zusammenfassung) – für Quantile der Ausführungszeit. \n
Beispiel: Registrierung benutzerdefinierter Metriken in TypeScript
\nimport client from 'prom-client';\nimport express, { Request, Response } from 'express';\n\n// Erstellen eines Metrikregisters\nconst register = new client.Registry();\nclient.collectDefaultMetrics({ register });\n\n// Benutzerdefinierter Fehlerzähler\nconst errorCounter = new client.Counter({\n name: 'app_errors_total',\n help: 'Total number of application errors',\n labelNames: ['type', 'code'],\n registers: [register],\n});\n\n// Histogramm der Antwortzeit\nconst httpRequestDuration = new client.Histogram({\n name: 'http_request_duration_seconds',\n help: 'Duration of HTTP requests in seconds',\n labelNames: ['method', 'route', 'status'],\n buckets: [0.01, 0.05, 0.1, 0.5, 1, 2, 5],\n registers: [register],\n});\n\n// Gauge aktiver Benutzer\nconst activeUsers = new client.Gauge({\n name: 'active_users_count',\n help: 'Number of currently active users',\n labelNames: ['user_type'],\n registers: [register],\n});\n\nconst app = express();\n\n// Middleware zum Messen der Anfragezeit\napp.use((req: Request, res: Response, next) => {\n const end = httpRequestDuration.startTimer();\n res.on('finish', () => {\n end({ method: req.method, route: req.path, status: res.statusCode });\n });\n next();\n});\n\n// Endpunkt für Metriken\napp.get('/metrics', async (req: Request, res: Response) => {\n res.set('Content-Type', register.contentType);\n res.end(await register.metrics());\n});\n\n// Fehlersimulation\napp.get('/error', (req: Request, res: Response) => {\n errorCounter.inc({ type: 'validation', code: '400' });\n res.status(400).send('Bad Request');\n});\n\napp.listen(3000, () => console.log('Server on port 3000'));\n\n2. Integration mit Prometheus und Grafana
\nDie gesammelten Metriken müssen exportiert und visualisiert werden. Prometheus fragt unseren Endpunkt /metrics ab, und Grafana zeigt die Daten auf Dashboards an.
Prometheus-Konfiguration für die TypeScript-Anwendung
\n# prometheus.yml\nglobal:\n scrape_interval: 15s\nscrape_configs:\n - job_name: 'typescript-app'\n static_configs:\n - targets: ['localhost:3000']\n metrics_path: '/metrics'\n # Hinzufügen von Umgebungs-Labels\n relabel_configs:\n - source_labels: [__address__]\n target_label: instance\n regex: '([^:]+):.*'\n replacement: '${1}'\n\nErweiterte PromQL-Abfragen zur Analyse
\n- \n
rate(app_errors_total[5m])– Fehlerrate in den letzten 5 Minuten. \nhistogram_quantile(0.95, rate(http_request_durati