Einleitung: Warum fortgeschrittene Überwachung für Node.js eine Notwendigkeit ist
\nIn der modernen Webentwicklung geht die Überwachung über die einfache Fehlerprotokollierung hinaus. Für kritische Node.js-Anwendungen – von Microservices bis hin zu stark ausgelasteten APIs – ist eine proaktive Metrikenerfassung, intelligente Alarme und Datenvisualisierung erforderlich. Auf fortgeschrittenem Niveau sprechen wir nicht nur von "die Anwendung lebt", sondern von ihrer Leistung, Engpässen und der Vorhersage von Ausfällen.
\nIn diesem Artikel werden wir erläutern, wie man ein vollständiges Überwachungssystem für eine JavaScript (Node.js)-Anwendung aufbaut: von der Erfassung benutzerdefinierter Metriken bis zur Konfiguration von Alarmen über Prometheus und Grafana. Sie erfahren, wie Sie die integrierten Funktionen von Node.js und moderne Bibliotheken zur proaktiven Überwachung des Dienststatus nutzen.
\n\n1. Erfassung fortgeschrittener Metriken: Vom Event Loop bis zu benutzerdefinierten Zählern
\nEine grundlegende Metrik ist die Serverantwortzeit. Eine fortgeschrittene Metrik ist die Event-Loop-Verzögerung, die Anzahl aktiver Deskriptoren und die Häufigkeit der Garbage Collection. Betrachten wir, wie diese Daten mit process und der Bibliothek prom-client (Client für Prometheus) erfasst werden.
1.1. Event-Loop-Metriken und Systemressourcen
\nNode.js ist single-threaded, daher ist die Event-Loop-Verzögerung kritisch. Wir messen sie mit process.hrtime() und exportieren sie als Histogramm.
const client = require('prom-client');\nconst eventLoopDelay = new client.Histogram({\n name: 'nodejs_event_loop_delay_seconds',\n help: 'Event-Loop-Verzögerung in Sekunden',\n buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1]\n});\n\nfunction measureEventLoop() {\n const start = process.hrtime.bigint();\n setImmediate(() => {\n const duration = Number(process.hrtime.bigint() - start) / 1e9;\n eventLoopDelay.observe(duration);\n });\n}\nsetInterval(measureEventLoop, 5000);\n\n1.2. Benutzerdefinierte Metriken der Geschäftslogik
\nNeben Systemmetriken sollten auch Geschäftskennzahlen überwacht werden: Anzahl verarbeiteter Bestellungen, Validierungsfehler, Ausführungszeit externer Anfragen.
\nconst orderCounter = new client.Counter({\n name: 'app_orders_total',\n help: 'Gesamtzahl der verarbeiteten Bestellungen',\n labelNames: ['status'] // success, failed\n});\n\n// Beispielverwendung im Handler\napp.post('/api/order', async (req, res) => {\n try {\n await processOrder(req.body);\n orderCounter.inc({ status: 'success' });\n res.send('OK');\n } catch (err) {\n orderCounter.inc({ status: 'failed' });\n res.status(500).send('Error');\n }\n});\n\n2. Metrikenexport und Integration mit Prometheus
\nDamit Prometheus Metriken sammeln kann, muss ein Endpunkt /metrics erstellt werden. Wir verwenden das Standard-Register von prom-client.
2.1. Erstellen des Endpunkts zur Sammlung
\nconst express = require('express');\nconst app = express();\nconst client = require('prom-client');\n\n// Standard-Node.js-Metriken sammeln\nclient.collectDefaultMetrics({ timeout: 5000 });\n\napp.get('/metrics', async (req, res) => {\n res.set('Content-Type', client.register.contentType);\n res.end(await client.register.metrics());\n});\n\napp.listen(3000, () => console.log('Metrics server on :3000'));\n\n2.2. Prometheus-Konfiguration
\nFügen Sie in der Datei prometheus.yml ein Ziel für Ihre Anwendung hinzu:
scrape_configs:\n - job_name: 'nodejs-app'\n static_configs:\n - targets: ['localhost:3000']\nNach dem Neustart von Prometheus werden die Metriken standardmäßig alle 15 Sekunden gesammelt.
\n\n3. Alarmkonfiguration: Von einfachen Schwellenwerten bis zur Anomalieanalyse
\nAlarme sind die Reaktion auf Metriken, die außerhalb des Normalbereichs liegen. Auf fortgeschrittenem Niveau verwenden wir PromQL für komplexe Bedingungen und konfigurieren Regeln im Alertmanager.
\n\n3.1. Grundlegende Alarmregeln
\nErstellen Sie eine Datei alerts.yml:
Blogs
Buchempfehlungen
Lesen Sie auch
Fehlerbehandlung in Rust: try/catch und mehr – Fortgeschrittenes Niveau
Leerzeichen in Go entfernen: Wie man überflüssige Zeichen in einer Zeichenkette loswird
Profiling von Rust-Code: Engpässe in der Praxis finden
Monorepository mit Java: Code-Organisation in der Praxis
Caching in Go: Redis, Memcached und integrierte Lösungen von A bis Z