Monitoring in TypeScript: Tracing, Metriken und Logs für Node.js

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Observability in TypeScript: Vom Black-Box-System zur transparenten Architektur

\n\n

Stellen Sie sich vor, Ihre TypeScript-Anwendung sei ein komplexer Mechanismus aus tausenden Zahnrädern. Alles läuft perfekt – bis etwas kaputt geht. Und dann erhalten Sie die Nachricht: „Die Website ist langsam.“ Wo suchen Sie nach dem Problem? Datenbank? API? Oder ist einfach einer der Microservices ausgefallen?

\n\n

Ohne Observability (Beobachtbarkeit) werden Sie raten müssen wie ein Schamane mit seiner Rassel. Mit Observability sehen Sie das gesamte Bild: wo die Leistung eingebrochen ist, welche Anfrage den Fehler verursacht hat und warum Speicher ausgelaufen ist.

\n\n

In diesem Artikel werden wir die drei Säulen der Observability – Tracing, Metriken und Logs – behandeln und lernen, wie man sie in TypeScript-Anwendungen anhand realer Beispiele implementiert. Sie erfahren, wie Sie Ihre Anwendung von einer Black Box in ein transparentes System verwandeln, das in Minuten diagnostiziert werden kann.

\n\n

Warum Observability für TypeScript-Anwendungen kritisch ist

\n\n

TypeScript ist nicht nur ein Aufsatz zu JavaScript. Es ist eine Sprache, in der Backends für hochlastige Systeme, Microservices und sogar CLI-Tools geschrieben werden. Und je komplexer das System, desto wichtiger ist es zu verstehen, was darin passiert.

\n\n

Traditionelles Logging ist gut, aber nicht ausreichend. Wenn Sie 50 Microservices haben, werden Logs zu weißem Rauschen. Sie benötigen:

\n\n
    \n
  • Tracing – um den Weg einer einzelnen Anfrage durch alle Dienste zu verfolgen.
  • \n
  • Metriken – um zu sehen, dass der RAM wie Hefeteig wächst.
  • \n
  • Strukturierte Logs – um nicht die Nadel im Heuhaufen zu suchen.
  • \n
\n\n

Lassen Sie uns dies in eine echte Anwendung implementieren.

\n\n

Tracing in TypeScript: OpenTelemetry in der Praxis

\n\n

Tracing (Trace-Verfolgung) ist die Lebensgeschichte einer einzelnen Anfrage. Sie sehen, wie viel Zeit jeder Schritt benötigt hat: von der HTTP-Anfrage bis zur Datenbankabfrage. In TypeScript ist OpenTelemetry der De-facto-Standard.

\n\n

Installation und Konfiguration von OpenTelemetry

\n\n
npm install @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-jaeger
\n\n

Erstellen wir eine Datei tracing.ts zur Initialisierung des Trackings:

\n\n
import { NodeSDK } from '@opentelemetry/sdk-node';\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';\nimport { JaegerExporter } from '@opentelemetry/exporter-jaeger';\nimport { Resource } from '@opentelemetry/resources';\nimport { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';\n\nconst jaegerExporter = new JaegerExporter({\n    endpoint: 'http://localhost:14268/api/traces',\n    serviceName: 'my-typescript-app',\n});\n\nconst sdk = new NodeSDK({\n    resource: new Resource({\n        [SemanticResourceAttributes.SERVICE_NAME]: 'my-typescript-app',\n        [SemanticResourceAttributes.SERVICE_VERSION]: '1.0.0',\n    }),\n    traceExporter: jaegerExporter,\n    instrumentations: [getNodeAutoInstrumentations()],\n});\n\nsdk.start();\n
\n\n

Jede HTTP-Anfrage, jeder Datenbankaufruf wird nun automatisch getraced. Sie sehen in der Jaeger UI (oder Grafana Tempo) die vollständige Aufrufkarte.

\n\n

Manuelle Erstellung von Spans

\n\n

Auto-Instrumentierung ist großartig, aber manchmal müssen Sie eigene Markierungen hinzufügen. Zum Beispiel die Ausführungszeit komplexer Geschäftslogik messen:

\n\n
import { trace } from '@opentelemetry/api';\n\nconst tracer = trace.getTracer('business-logic');\n\nasync function processOrder(orderId: string): Promise<void> {\n    const span = tracer.startSpan('process-order', {\n        attributes: { 'order.id': orderId },\n    });\n\n    try {\n        // Ihre Auftragsverarbeitungslogik\n        await validateOrder(orderId);\n        await chargePayment(orderId);\n        await sendConfirmation(orderId);\n\n        span.setStatus({ code: 1 }); // OK\n    } catch (error) {\n        span.recordException(error as Error);\n        span.setStatus                

Blogs

Buchempfehlungen