À proposExpertiseProjetsParcoursBlogContact
Discuter
À proposExpertiseProjetsParcoursBlogContactDiscuter

Yao David Logan

Software Engineer fullstack spécialisé en SaaS, automatisation métier et plateformes web/mobile scalables.

NavigationExpertiseProjetsParcoursBlogContact
LiensGitHubLinkedInEmail
© 2026 Yao David Logan. Tous droits réservés.
Observabilité d'une plateforme fintech — logs, métriques, traces et audit
Retour au blog

Tech

Xin@

Observabilité d'une plateforme fintech — logs, métriques, traces et audit

YDLYao David Logan9 min de lecture23 mai 2026

CatégorieTech

Lecture9 min de lecture

Publié23 mai 2026

Vues281

Partages0

Commentaires0

Sommaire
  1. 011. Le contexte
  2. 022. Les trois piliers — logs, métriques, traces
  3. 033. Pattern 1 — Logs structurés en JSON
  4. 044. Pattern 2 — Niveaux de log avec discipline
  5. 055. Pattern 3 — Propagation du trace ID
  6. 066. Pattern 4 — Métriques business + métriques techniques
  7. 077. Pattern 5 — Traces distribuées avec OpenTelemetry
  8. 088. Pattern 6 — Sampling intelligent
  9. 099. Pattern 7 — Alertes qui réveillent vs alertes qui informent
  10. 1010. Pattern 8 — Dashboard "santé en 5 secondes"
  11. 1111. Pattern 9 — Audit log séparé
  12. 1212. Pièges à éviter
  13. 1313. Conclusion

Logs JSON structurés, trace ID propagé, OpenTelemetry, alertes P1/P2/P3 avec runbooks, audit log append-only : la boîte à outils pour diagnostiquer un incident fintech en 5 minutes.

Sur une plateforme financière, "ça marche en dev" ne suffit pas. Voici comment j'instrumente logs, métriques et traces pour qu'un incident à 3 h du matin trouve sa cause en 5 minutes.

1. Le contexte

Nexus est une plateforme d'investissement financier. Quand un utilisateur fait un dépôt, une dizaine d'opérations s'enchaînent : auth, scoring KYC, vérification solde, appel à la passerelle de paiement, webhook de confirmation, mise à jour du compte, notification. Si l'une casse, l'utilisateur voit "transaction échouée" — mais sans observabilité, on ne sait pas où ça a cassé.

L'observabilité n'est pas un luxe sur ce genre de plateforme. C'est ce qui permet à un incident de 3 h du matin d'être diagnostiqué en 5 minutes au lieu de 5 heures. Cet article condense ce que j'ai mis en place.

2. Les trois piliers — logs, métriques, traces

Logs

Ce qui s'est passé. Texte structuré, lisible par humain et machine. Granularité : une ligne par événement notable.

Métriques

Combien, à quelle fréquence. Séries temporelles agrégées. Granularité : un point par minute typiquement.

Traces distribuées

Le chemin d'une requête à travers plusieurs services. Une trace = un ID unique propagé. Granularité : un span par étape.

Les trois sont complémentaires. Une métrique alerte ("le taux d'erreur explose"), un log montre la cause ("Stripe a renvoyé 503"), une trace montre où dans la chaîne ("entre auth-service et payment-service, latence 8s").

3. Pattern 1 — Logs structurés en JSON

Un log non-structuré est inutilisable pour la corrélation. Tous les logs Nexus sont en JSON, avec une structure stable.

TypeScript
1// src/utils/logger.ts
2import winston from "winston";
3 
4export const logger = winston.createLogger({
5 level: process.env.LOG_LEVEL ?? "info",
6 format: winston.format.combine(
7 winston.format.timestamp(),
8 winston.format.errors({ stack: true }),
9 winston.format.json(),
10 ),
11 defaultMeta: { service: "nexus-api", env: process.env.NODE_ENV },
12 transports: [new winston.transports.Console()],
13});

Une ligne typique :

JSON
1{
2 "timestamp": "2026-03-12T14:32:08.412Z",
3 "level": "info",
4 "service": "nexus-api",
5 "env": "production",
6 "trace_id": "abc123",
7 "user_id": "u_8jhq...",
8 "operation": "deposit.initiate",
9 "amount_xof": 50000,
10 "gateway": "mtn_momo",
11 "msg": "Deposit initiated"
12}

Le trace_id est la clé. Tous les logs d'une même requête le partagent. Loki ou Elasticsearch indexent ce champ, et une recherche trace_id="abc123" reconstruit toute l'histoire.

4. Pattern 2 — Niveaux de log avec discipline

Quatre niveaux, et c'est tout. Un cinquième tue la lisibilité.

NiveauQuandExemple
ERRORQuelque chose a vraiment cassé et un humain doit savoirWebhook signature invalide
WARNAnomalie qui ne casse pas mais qui doit être surveilléeRetry après 3 échecs
INFOÉvénement notable du businessPaiement confirmé, KYC validé
DEBUGDétails techniques utiles en investigationPayload reçu, query SQL

Règle de discipline : DEBUG est désactivé en prod par défaut. Activable temporairement via une variable d'env sans redéploiement. Si vos logs prod sont à 80 % DEBUG, vous n'avez pas de logs — vous avez du bruit.

5. Pattern 3 — Propagation du trace ID

Sans trace ID propagé, vous ne pouvez pas suivre une requête entre services. Sur Nexus, le gateway génère un trace ID à chaque requête entrante et le propage en header HTTP x-trace-id.

TypeScript
1// src/middlewares/traceContext.ts
2import { randomUUID } from "node:crypto";
3import { AsyncLocalStorage } from "node:async_hooks";
4 
5const storage = new AsyncLocalStorage<{ traceId: string }>();
6 
7export function traceContext(req, res, next) {
8 const traceId = req.header("x-trace-id") ?? randomUUID();
9 res.setHeader("x-trace-id", traceId);
10 storage.run({ traceId }, () => next());
11}
12 
13export function currentTraceId(): string | undefined {
14 return storage.getStore()?.traceId;
15}

Le logger inclut automatiquement trace_id dans chaque log :

TypeScript
1const log = (level, msg, meta = {}) =>
2 logger.log({ level, message: msg, trace_id: currentTraceId(), ...meta });

Chaque appel HTTP downstream propage le header. La trace devient ininterrompue.

6. Pattern 4 — Métriques business + métriques techniques

Deux familles distinctes, deux dashboards distincts.

Métriques techniques (red signals)

  • Taux d'erreur HTTP par route (4xx, 5xx)
  • Latence p50, p95, p99 par route
  • Saturation : CPU, mémoire, connexions DB, queue depth
  • Disponibilité par service (probe régulière)

Métriques business (golden signals)

  • Volume de dépôts / retraits par minute
  • Taux de complétion KYC
  • Time-to-money (du clic dépôt à la confirmation utilisateur)
  • Solde global de la plateforme
TypeScript
1// src/observability/metrics.ts
2import prom from "prom-client";
3 
4export const depositCounter = new prom.Counter({
5 name: "nexus_deposit_total",
6 help: "Total deposits initiated",
7 labelNames: ["gateway", "currency", "status"],
8});
9 
10export const depositLatency = new prom.Histogram({
11 name: "nexus_deposit_seconds",
12 help: "Deposit completion time",
13 labelNames: ["gateway"],
14 buckets: [0.5, 1, 2, 5, 10, 30],
15});

Une alerte business ("volume de dépôts divisé par 3 dans la dernière heure") signale plus tôt qu'une alerte technique ("le service paiement répond plus lentement"). Les deux comptent.

7. Pattern 5 — Traces distribuées avec OpenTelemetry

Pour les requêtes qui traversent plusieurs services, OpenTelemetry trace chaque span.

TypeScript
1// src/observability/tracing.ts
2import { NodeSDK } from "@opentelemetry/sdk-node";
3import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
4import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
5 
6const sdk = new NodeSDK({
7 traceExporter: new OTLPTraceExporter({ url: process.env.OTLP_ENDPOINT }),
8 instrumentations: [getNodeAutoInstrumentations()],
9});
10 
11sdk.start();

Avec auto-instrumentation, chaque appel HTTP, requête SQL, query Redis devient un span automatiquement. Pour les opérations métier, on ajoute des spans manuels :

TypeScript
1import { trace } from "@opentelemetry/api";
2 
3const tracer = trace.getTracer("nexus-api");
4 
5async function processDeposit(input: DepositInput) {
6 return tracer.startActiveSpan("deposit.process", async (span) => {
7 span.setAttribute("amount", input.amount);
8 span.setAttribute("gateway", input.gateway);
9 try {
10 const result = await doProcess(input);
11 span.setStatus({ code: 1 }); // OK
12 return result;
13 } catch (error) {
14 span.recordException(error);
15 span.setStatus({ code: 2, message: error.message });
16 throw error;
17 } finally {
18 span.end();
19 }
20 });
21}

Visualisation dans Tempo ou Jaeger : on voit la cascade complète, où chaque étape a passé combien de ms, et où ça a cassé.

8. Pattern 6 — Sampling intelligent

Tracer 100 % des requêtes en production coûte cher en stockage et en bande passante. Sampling :

  • 100 % des erreurs — toujours tracées
  • 100 % des opérations financières — non négociable
  • 10 % des requêtes de lecture — échantillonnage
  • 1 % des healthchecks — quasi-rien
TypeScript
1const sampler = new ParentBasedSampler({
2 root: new TraceIdRatioBasedSampler(0.1),
3 remoteParentSampled: new AlwaysOnSampler(),
4});

Coût stockage divisé par 10 sans perdre les signaux qui comptent.

9. Pattern 7 — Alertes qui réveillent vs alertes qui informent

Trois canaux d'alerte, trois urgences distinctes :

  • P1 (réveille à 3 h) : plateforme down, paiement impossible, solde corrompu
  • P2 (Slack heures ouvrées) : latence dégradée, taux d'erreur > 1 %, queue qui grossit
  • P3 (digest hebdo) : warnings récurrents, métriques business en baisse
YAML
1# prometheus/alerts.yml
2groups:
3 - name: nexus.p1
4 rules:
5 - alert: PaymentServiceDown
6 expr: up{service="payment-service"} == 0
7 for: 1m
8 labels: { severity: p1 }
9 annotations:
10 summary: "Payment service is down"
11 runbook: "https://wiki.nexus/runbooks/payment-down"

Chaque alerte P1 a un runbook : 5 étapes à suivre dans l'ordre. Pas de "réfléchir à 3 h du matin" — exécuter le runbook, vérifier, escalader si pas résolu en 15 min.

10. Pattern 8 — Dashboard "santé en 5 secondes"

Un seul dashboard ouvert sur un grand écran à l'open space. Trois blocs :

  1. État des services : 6 cases vertes / rouges
  2. Métriques business clés : dépôts/h, retraits/h, KYC validés/h
  3. Erreurs des 15 dernières minutes : top 5 par fréquence

Si tout est vert, on n'y regarde pas. Si quelque chose passe au rouge, tout le monde voit en même temps. Pas besoin d'attendre l'alerte Slack.

11. Pattern 9 — Audit log séparé

Les logs applicatifs ne suffisent pas pour l'audit fintech. Un log séparé, append-only, conservé 7 ans minimum :

SQL
1CREATE TABLE audit_log (
2 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
3 actor_type VARCHAR(20) NOT NULL,
4 actor_id UUID NULL,
5 action VARCHAR(80) NOT NULL,
6 resource VARCHAR(80) NOT NULL,
7 resource_id UUID NULL,
8 before JSONB NULL,
9 after JSONB NULL,
10 trace_id VARCHAR(64) NOT NULL,
11 at TIMESTAMP NOT NULL DEFAULT NOW()
12);
13 
14-- Refus de UPDATE/DELETE via trigger
15CREATE FUNCTION audit_immutable() RETURNS trigger AS $$
16BEGIN RAISE EXCEPTION 'audit_log is append-only'; END;
17$$ LANGUAGE plpgsql;
18CREATE TRIGGER no_update BEFORE UPDATE ON audit_log
19 FOR EACH ROW EXECUTE FUNCTION audit_immutable();
20CREATE TRIGGER no_delete BEFORE DELETE ON audit_log
21 FOR EACH ROW EXECUTE FUNCTION audit_immutable();

Cet audit est ce qu'un régulateur ou un auditeur va lire. Il doit être propre, complet, immuable.

12. Pièges à éviter

PiègeSymptômeCorrection
Logs en texte platRecherche impossibleJSON structuré, indexé
Pas de trace ID propagéRequête introuvable inter-serviceUUID propagé en header partout
Trop de niveaux de logBruit ingérable4 niveaux max, DEBUG off en prod
Alertes sans runbookPanique nocturneChaque P1 a son runbook
Sampling 100 %Coût stockage exorbitantSampling intelligent par criticité
Pas d'audit séparéRisque conformitéTable audit_log append-only, 7 ans
Dashboards trop détaillésPersonne ne regardeUn dashboard santé, 5 secondes
Métriques uniquement techniquesDrift business invisibleMétriques business + techniques distinctes

13. Conclusion

L'observabilité n'est pas un sujet d'infra. C'est un sujet de résilience opérationnelle. Une plateforme fintech sans observabilité claire est une bombe à retardement : le premier incident sérieux durera 6 heures, perdra des transactions, et entamera la confiance des utilisateurs.

Quatre fondamentaux pour démarrer : logs JSON structurés avec trace ID propagé, métriques business + techniques distinctes, traces distribuées sur les opérations critiques, audit log append-only séparé.

Le coût est réel (~2 semaines de setup initial, ~20 % d'overhead de code). Le bénéfice est inestimable la première fois qu'un incident à 3 h du matin se diagnostique en 5 minutes.

Commentaires

Réactions des lecteurs

Aucun commentaire pour l'instant

Aucun spam — l'email sert uniquement à vérifier votre identité.

·

Soyez le premier à réagir à cet article.

←PrécédentDX 2026 — choisir son socle Node.js + TypeScript sans se piégerTech · 7 min de lectureSuivantDu MVP à la traction — 8 patterns pour ne pas livrer un SaaS B2B qui dortBusiness · 8 min de lecture→
Prochain échange

Transformer cette lecture en décision produit.

Si ce sujet ressemble à un problème réel dans votre produit, je peux intervenir sur le diagnostic, l'architecture, le backend, l'interface et les automatisations qui rendent une plateforme exploitable.

Format
CDI, freelance, mission longue
Focus
SaaS, API, back-office, automatisation
Discuter du sujetTélécharger le CV

Newsletter

Recevoir les prochaines notes techniques.

Une sélection courte sur SaaS, architecture backend, automatisation métier et qualité produit. Pas de bruit, seulement des idées applicables.