Retour à l'accueil

Traçage OpenTelemetry en Fintech depuis le Frontend

L'article décrit l'implémentation d'OpenTelemetry pour le traçage de bout en bout dans un système fintech. Implémentation de CompositeLogger en TypeScript avec patch fetch et intégration React. L'architecture avec Collector, Jaeger et Prometheus accélère l'analyse des incidents.

Traçage OpenTelemetry : Expérience de l'équipe Fintech
Advertisement 728x90

Tracing de bout en bout dans les fintech : du frontend au collecteur OpenTelemetry

Dans les systèmes fintech distribués, des journaux sans traceId ne permettent pas de relier une erreur 500 à l’action de l’utilisateur. OpenTelemetry permet un tracing de bout en bout — depuis le frontend d’une application monopage (SPA) jusqu’aux services backend — via le collecteur OpenTelemetry. Notre implémentation TypeScript repose sur un CompositeLogger et un fetch modifié pour préserver la hiérarchie des spans dans les flux critiques, comme les virements bancaires.

Concepts fondamentaux d’OpenTelemetry pour développeurs frontend

OpenTelemetry normalise la collecte des données d’observabilité : traces, spans, événements et attributs.

  • Trace — structure racine identifiée par un traceId, utilisée pour regrouper des spans liées.
  • Span — opération temporelle avec horodatages de début et de fin ; elle supporte l’imbrication pour refléter la hiérarchie des appels.
  • Événement — occurrence horodatée liée à une span, accompagnée d’attributs personnalisés.
  • Attribut — métadonnée sous forme clé-valeur, permettant le filtrage, la recherche et l’enrichissement contextuel.

Ces primitives combinées vous permettent de suivre un clic utilisateur jusqu’aux intégrations backend sous-jacentes.

Google AdInline article slot

Aperçu de l’architecture d’observabilité

Le frontend envoie les traces via un microservice d’audit au collecteur OpenTelemetry. Les services backend — équipes produit et plateforme — acheminent leurs métriques vers Jaeger (traces), Prometheus (métriques) et Kibana (journaux). Grafana fournit des tableaux de bord unifiés.

Principaux avantages de cette architecture :

  • Ingestion centralisée — aucun accès direct du frontend à l’infrastructure interne d’observabilité.
  • Déploiement progressif par microservice, limitant les risques.
  • L’obfuscation des données sensibles est obligatoire — jamais optionnelle.

Implémentation frontend : l’interface Logger

L’abstraction fondamentale est une interface Logger, garantissant une journalisation cohérente et multiplateforme.

Google AdInline article slot
export interface Logger {
  readonly name: string;
  init?(options?: CompositeInitOptions | SentryInitOptions | AuditInitOptions): void;
  logError(error: Error, context?: ErrorContextType | ErrorContextType[]): void;
  logMessage?(message: string, context?: Record<string, unknown>): void;
}

CompositeLogger implémente le patron Composite, redirigeant les événements vers plusieurs loggers sous-jacents (OpenTelemetry, Sentry, Audit).

export class CompositeLogger implements Logger {
  public readonly name = "composite";

  constructor(private readonly loggers: Logger[]) {}

  init(options?: CompositeInitOptions): void {
    this.loggers.forEach((logger) => {
      logger.init?.(options?.[logger.name as keyof CompositeInitOptions]);
    });
  }

  logError(error: Error, context?: ErrorContextType[]): void {
    this.loggers.forEach((logger) => {
      logger.logError(error, context);
    });
  }

  logMessage(message: string, context?: Record<string, unknown>): void {
    this.loggers.forEach((logger) => {
      logger.logMessage?.(message, context);
    });
  }

  startBusinessProcess(name: string, attributes?: Attributes): void {
    this.loggers.forEach((logger) => {
      if (logger.name === "otlp") {
        (logger as OtlpLogger).startBusinessProcess(name, attributes);
      }
    });
  }

  addEvent(name: string, attributes?: Attributes): void {
    this.loggers.forEach((logger) => {
      if (logger.name === "otlp") {
        (logger as OtlpLogger).addEvent(name, attributes);
      }
    });
  }
}

Intégration React via Context

LoggerProvider et useLogger offrent un accès transparent au logger dans toute l’arborescence des composants.

import React, { createContext, useContext } from "react";
import { CompositeLogger } from "./composite-logger";

const LoggerContext = createContext<CompositeLogger | null>(null);

export const LoggerProvider: React.FC<{
  logger: CompositeLogger;
  children: React.ReactNode;
}> = ({ logger, children }) => (
  <LoggerContext.Provider value={logger}>{children}</LoggerContext.Provider>
);

export const useLogger = (): CompositeLogger => {
  const logger = useContext(LoggerContext);
  if (!logger) {
    throw new Error("Logger introuvable dans le contexte");
  }
  return logger;
};

OtlpLogger : modification de fetch et utilisation de StackContextManager

OtlpLogger initialise le WebTracerProvider, modifie fetch pour propager automatiquement les spans parentes, et exploite StackContextManager afin de résoudre la perte de contexte asynchrone dans les navigateurs — garantissant que les spans enfants s’attachent correctement aux processus métier sans passage manuel de contexte.

Google AdInline article slot

Exemple : flux de virement bancaire :

  • startBusinessProcess('virement-bancaire')
  • addEvent('etape-formulaire-1', {montant: 1000})
  • Appel fetch vers le backend — hérite automatiquement du contexte de la span courante
  • logError en cas d’échec d’intégration, préservant toute la lignée de la trace

Avantages de cette implémentation

  • Réduction du MTTR de 10× ou plus, grâce au filtrage instantané basé sur traceId sur les journaux frontend et backend.
  • Extensibilité : de nouveaux loggers (ex. Datadog, Honeycomb) s’intègrent via npm — aucune modification du code applicatif requise.
  • Corrélation structurée : des attributs cohérents permettent une correspondance précise entre événements frontend et backend.

Les visualisations Jaeger montrent le parcours complet : clic utilisateur → appel API → Kafka → backend plateforme.

Points clés à retenir

  • Le tracing de bout en bout unifie les journaux frontend et backend en faisant du traceId la seule source de vérité.
  • Le CompositeLogger protège les développeurs de la complexité tout en supportant une télémétrie multi-destinations.
  • Le fetch modifié assure une hiérarchie de spans fiable — même lors d’appels réseau asynchrones.
  • Le StackContextManager élimine le code répétitif lié au tracing côté client dans les frameworks JavaScript modernes.
  • L’obfuscation des données est indispensable pour répondre aux exigences réglementaires dans le secteur fintech.

— Editorial Team

Advertisement 728x90

Lire ensuite