Aller au contenu

Corréler le navigateur et le service

HTTP Guardian et MIC peuvent porter le même identifiant depuis une action utilisateur jusqu'aux logs du service. L'objectif n'est pas de recréer le tracing distribué : l'identifiant facilite la recherche opérationnelle, tandis que traceparent reste le standard pour relier les spans navigateur, HTTP et SQL.

Contrat recommandé

  • X-Request-Id couvre une requête logique, retries compris. Utilisez-le pour rechercher les logs et répondre au support.
  • X-Correlation-Id couvre un parcours métier pouvant traverser plusieurs requêtes. Utilisez-le pour un regroupement fonctionnel explicite.
  • traceparent couvre une trace distribuée. Utilisez-le pour relier les spans OpenTelemetry jusqu'aux dépendances instrumentées.

Pour obtenir immédiatement un identifiant présent dans tous les logs structurés MIC, utilisez X-Request-Id. correlationIdGuard() conserve la même valeur pendant les retries et LogContextMiddleware la valide, la lie au contexte de log puis la renvoie dans la réponse.

Côté navigateur

Installez la préversion publique actuelle de HTTP Guardian :

npm install @cedvict/http-guardian@next

Configurez le guard avec le nom de header attendu par le contexte de log MIC :

import {
  correlationIdGuard,
  createApiParserStructured,
  createHttpClient,
  noAuth,
} from "@cedvict/http-guardian";

export const api = createHttpClient({
  baseUrl: "https://api.example.com",
  auth: noAuth(),
  parser: createApiParserStructured(),
  guards: [
    correlationIdGuard({ headerName: "X-Request-Id" }),
  ],
});

Un identifiant est généré une seule fois par requête logique. Si un plugin de retry rejoue l'appel, toutes les tentatives gardent donc le même identifiant. Le header renvoyé par le service est aussi recopié dans ctx.meta.correlationId pour les plugins HTTP Guardian de journalisation, Sentry ou OpenTelemetry.

Côté MIC avec FastAPI

from fastapi import FastAPI
from mic.observability import LogContextMiddleware

app = FastAPI()
app.add_middleware(LogContextMiddleware)

Chaque log structuré émis pendant la requête reçoit request_id. La réponse porte le même X-Request-Id. Une valeur entrante non conforme à l'allow-list [A-Za-z0-9_-]{1,128} est remplacée au lieu d'être recopiée dans les logs et les headers.

Côté MIC avec Litestar

from litestar import Litestar
from litestar.middleware import DefineMiddleware
from mic.observability import LogContextMiddleware

app = Litestar(
    route_handlers=[...],
    middleware=[DefineMiddleware(LogContextMiddleware)],
)

Le middleware est ASGI : le contrat et les champs de log sont identiques avec FastAPI et Litestar.

Parcours métier avec X-Correlation-Id

Si le même identifiant doit couvrir plusieurs requêtes, conservez le nom par défaut côté navigateur :

guards: [correlationIdGuard()]

Activez alors le middleware de corrélation MIC :

from fastapi import FastAPI
from mic.fastapi import CorrelationMiddleware

app = FastAPI()
app.add_middleware(CorrelationMiddleware)
from litestar import Litestar
from litestar.middleware import DefineMiddleware
from mic.litestar import CorrelationMiddleware

app = Litestar(
    route_handlers=[...],
    middleware=[DefineMiddleware(CorrelationMiddleware)],
)

MIC expose alors l'identifiant dans request.state.correlation_id avec FastAPI, ou dans scope["state"]["correlation_id"] avec Litestar. Il renvoie également X-Correlation-Id, X-Request-Id et X-Response-Time-ms.

Pour une corrélation automatique des logs, préférez le contrat X-Request-Id de la section précédente. Un identifiant de parcours métier peut être journalisé en plus, mais il ne remplace pas l'identifiant de requête.

Frontend et API sur des origines différentes

La politique CORS de l'API doit :

  • autoriser X-Request-Id ou X-Correlation-Id dans les headers de requête ;
  • exposer le même header dans Access-Control-Expose-Headers pour que HTTP Guardian puisse lire la valeur renvoyée par le service.

Sans exposition du header de réponse, la propagation vers le service fonctionne toujours, mais le navigateur ne peut pas lire la valeur normalisée par l'API.

Vérification opérationnelle

curl -i https://api.example.com/health \
  -H 'X-Request-Id: checkout-smoke-42'

Le contrôle est complet lorsque :

  1. la réponse contient X-Request-Id: checkout-smoke-42 ;
  2. les logs MIC de cette requête contiennent "request_id":"checkout-smoke-42" ;
  3. les retries éventuels portent la même valeur ;
  4. les spans distribués continuent d'utiliser traceparent indépendamment.