Surveillance en TypeScript : traçage, métriques et logs pour Node.js

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Observabilité en TypeScript : de la boîte noire au système transparent

\n\n

Imaginez que votre application TypeScript est un mécanisme complexe composé de milliers d'engrenages. Tout fonctionne parfaitement, jusqu'à ce que ça casse. Et voilà que vous recevez un message : « Le site ralentit ». Où chercher le problème ? Base de données ? API ? Ou est-ce simplement l'un des microservices qui est tombé ?

\n\n

Sans observabilité, vous devrez deviner comme un chaman avec son tambour. Avec l'observabilité, vous voyez l'ensemble du tableau : où la performance a chuté, quelle requête a provoqué l'erreur et pourquoi la mémoire a fui.

\n\n

Dans cet article, nous allons décortiquer les trois piliers de l'observabilité — traçage, métriques et logs — et apprendre à les intégrer dans des applications TypeScript à l'aide d'exemples concrets. Vous découvrirez comment transformer votre application d'une boîte noire en un système transparent, diagnosticable en quelques minutes.

\n\n

Pourquoi l'observabilité est-elle cruciale pour les applications TypeScript ?

\n\n

TypeScript n'est pas qu'un simple sur-ensemble de JavaScript. C'est un langage utilisé pour écrire le backend de systèmes à forte charge, des microservices et même des outils en ligne de commande. Et plus le système est complexe, plus il est important de comprendre ce qui s'y passe.

\n\n

La journalisation traditionnelle, c'est bien, mais insuffisant. Lorsque vous avez 50 microservices, les logs deviennent du bruit blanc. Vous avez besoin de :

\n\n
    \n
  • Traçage — pour suivre le chemin d'une seule requête à travers tous les services.
  • \n
  • Métriques — pour voir que la RAM augmente à vue d'œil.
  • \n
  • Logs structurés — pour ne pas chercher une aiguille dans une botte de foin.
  • \n
\n\n

Mettons cela en œuvre dans une application réelle.

\n\n

Traçage en TypeScript : OpenTelemetry en pratique

\n\n

Le traçage est l'histoire de la vie d'une seule requête. Vous voyez combien de temps chaque étape a pris : de la requête HTTP à la requête en base de données. En TypeScript, le standard de facto est OpenTelemetry.

\n\n

Installation et configuration d'OpenTelemetry

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

Créons un fichier tracing.ts pour initialiser le traçage :

\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

Désormais, chaque requête HTTP, chaque appel à la base de données sera automatiquement tracé. Vous verrez dans l'interface Jaeger UI (ou Grafana Tempo) la carte complète des appels.

\n\n

Création manuelle de spans

\n\n

L'auto-instrumentation, c'est génial, mais il faut parfois ajouter ses propres marqueurs. Par exemple, mesurer le temps d'exécution d'une logique métier complexe :

\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        // Votre logique de traitement de commande\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

Book Recommendations