GH GambleHub

Loger et tracer des événements

Loger et tracer des événements

1) Objectif et cadre

Les logs et les tracés sont les fondements de l'observation.
Les logs répondent à « ce qui s'est passé » et « avec quel contexte ».
Les tracés répondent à « où et pourquoi lentement/par erreur » dans le chemin de requête distribué.

Principes clés :
  • Structured by default (JSON); Trace-first : Chaque journal du chemin chaud est lié à 'trace _ id '/' span _ id'.
  • Minimum de bruit, maximum de signal : niveaux, sampling, anti-cardinalité.
  • Sécurité et vie privée : masquage, édition, délimitation d'accès.
  • Diagrammes de logs et d'événements versionnés.

2) Taxonomie des événements

Séparez les flux et les index comme prévu :

1. Logs techniques (runtime, erreurs, temporisations réseau, retraits).

2. Les événements d'affaires (enregistrement, dépôt, pari, retrait, KYC-étape) sont adaptés à l'analyse des produits et aux incidents sur les voies « monétaires ».

3. L'audit (qui/quand a changé : configis, accès, drapeaux, limites) est un journal immuable.

4. Sécurité (authentification, escalade des privilèges, drapeaux de sanctions/RER).

5. Infrastructure (K8s événements, autoscaling, HPA/VPA, nœuds/disque/réseau).

Pour chaque flux, des règles distinctes de rétention, d'indexation et d'accès.


3) Logue structurelle (référence JSON)

json
{
"ts": "2025-11-03T14:28:15.123Z",
"level": "ERROR",
"service": "payments-api",
"env": "prod",
"region": "eu-central-1",
"trace_id": "8a4f0c2e9b1f42d7",
"span_id": "c7d1f3a4b8b6e912",
"parent_span_id": "a1b2c3d4e5f60789",
"logger": "withdraw.handler",
"event": "psp_decline",
"msg": "PSP declined transaction",
"http": { "method": "POST", "route": "/withdraw", "status": 502, "latency_ms": 842 },
"user": { "tenant_id": "t_9f2", "user_key": "hash_0a7c", "vip_tier": 3 },
"payment": { "psp": "acme", "amount": 120.50, "currency": "EUR", "idempotency_key": "u123:wd:7845" },
"safe": true,         // пройдена проверка на секреты
"version": "1.14.2",     // версия сервиса (SemVer)
"build": "sha-1f2a3b4",
"kubernetes": { "pod": "payments-7cbdf", "node": "ip-10-0-2-41" }
}

Exigences : schéma plat + pièces jointes par domaine, champs obligatoires ('ts, level, service, bou, trace_id, msg'), valeurs numériques - nombres, non-lignes.


4) Niveaux, cardinalité et volume

Niveaux : 'DEBUG' (pas dans la vente), 'INFO' (faits commerciaux), 'WARN' (anomalies),' ERROR '(erreurs),' FATAL '.
Cardinalité : éviter les clés arbitraires/étiquettes dynamiques. Pas d'ID.
Sampling des logs : rate-limit messages répétés ; incluez « DEBUG » seulement scopé et dans le temps (feature flag).
Idempotence : Loger 'idempotency _ key' pour supprimer les duplications d'événements par les consommateurs.


5) Vie privée et sécurité

Masquer les PII/secrets sur les agents (Fluent Bit/Vector) : cartes de masquage par clés ('email', 'card', 'token', 'autorisation').
Hachez 'user _ key', ne conservez que le contexte requis (pays, niveau KYC, VIP-tier).
Séparez les entrepôts : chauds (recherche en ligne) et froids (archives sans PII/c dans un contexte réduit).
Audit - append-only, stockage WORM, accès uniquement selon le principe least privilège.


6) Traçage : Normes et contexte

W3C Trace Context : titres 'traceparent '/' tracestate', plus baggage pour les clés sécurisées (par exemple, 'tenant _ id', 'region').
Association des métriques et des tracés : Exemplars - Passez 'trace _ id'aux points semplés des histogrammes (accélère RCA).
Sampling : sampling de base 1-5 % + dynamique « sur erreur/p95 lent » jusqu'à 100 % pour les requêtes problématiques.
Liens : pour les files d'attente/sags asynchrones, liez les spans via 'liens' et pas seulement via 'parent'.


7) Collecte et routage

Agents : Bit/vecteur fluent pour les logs ; Exportation OTLP vers OpenTelemetry Collector.
Collecteur : passerelle centrale (batch/bou/filter/routing).

Convoyeur recommandé :

App → (OTLP logs/traces/metrics) → OTel Collector
→ logs: redact → route(security    audit    tech    biz) → hot index / cold archive
→ traces: tail_sampling(errors    p95>threshold) → APM backend
→ metrics: Prometheus exporter (for SLO/alerts)
Collecteur OTel (fragment) :
yaml processors:
batch: {}
attributes:
actions:
- key: env value: prod action: insert filter/logs:
logs:
include:
match_type: strict resource_attributes:
- key: service.name value: payments-api exporters:
otlp/traces: { endpoint: "apm:4317", tls: { insecure: true } }
loki: { endpoint: "http://loki:3100/loki/api/v1/push" }
prometheus: {}
service:
pipelines:
logs: { receivers: [otlp], processors: [attributes,batch], exporters: [loki] }
traces: { receivers: [otlp], processors: [batch], exporters: [otlp/traces] }
metrics: { receivers: [otlp], processors: [batch], exporters: [prometheus] }

8) Instrumentation : exemples de SDK

8. 1 Node. js (Pino + OTel)

js import pino from "pino";
import { context, trace } from "@opentelemetry/api";

const logger = pino({ level: process.env.LOG_LEVEL          "info" });

function log(info) {
const span = trace.getSpan(context.active());
const base = span? { trace_id: span.spanContext().traceId, span_id: span.spanContext().spanId }: {};
logger.info({...base,...info });
}

// пример log({ event: "deposit.created", amount: 50, currency: "EUR", user: { user_key: "hash_0a7c" } });

8. 2 Java (SLF4J + OTel)

java
MDC.put("trace_id", Span.current().getSpanContext().getTraceId());
MDC.put("span_id", Span.current().getSpanContext().getSpanId());
log.info("psp_response status={} latency_ms={}", status, latency);

8. 3 Python (structlog + OTel)

python import structlog from opentelemetry import trace log = structlog.get_logger()

def log_json(event, kwargs):
span = trace.get_current_span()
ctx = {}
if span and span.get_span_context().is_valid:
ctx = {"trace_id": span.get_span_context().trace_id, "span_id": span.get_span_context().span_id}
log.msg(event=event, ctx, kwargs)

8. 4 NGINX → trace des titres

nginx proxy_set_header traceparent $http_traceparent;
proxy_set_header tracestate $http_tracestate;

9) Logs comme signal pour alerts et auto-action

Agrégez et corrélez les motifs erronés ('psp _ decline', 'fraud _ flag') avec SLO.
Alerts sur pattern-rate : "5xx par/withdraw> 0. 5 % pour 10m', « fraud_flag spike> + 200 % de la base ».
Auto-action : dans le log'withdrawals _ manual _ mode = true ', activez kill-switch via la plate-forme des drapeaux.

Exemple de règle (pseudo-expression) :

rate(count_over_time({service="payments-api", level="ERROR", event="psp_decline"}[5m])) > 5

10) Rétention, indexation, stockage

Chaud : 7-14 jours (enquête rapide).
Chaud : 30-90 jours (tendances, RCA).
Froid : 180-365 + (archives, audit) - compression, classes bon marché, peut-être sans recherche en texte intégral.
Indexation : clés fixes ('service, bou, level, event, trace_id, user. tenant_id'), l'interdiction de l'indice « au total ».
Limites sur la taille de l'événement (par exemple, ≤ 32KB), trim/bas : « superflu dans le stockage est l'ennemi de MTTR ».


11) Audit et invariabilité

Écrivez des événements d'audit avec un thread séparé avec des signatures/hashs, l'heure du serveur, 'who/what/when/why', une référence ticket.
« Qui a inclus le drapeau bonus 100 % dans DE ? » - la réponse doit être dans 1-2 demandes.

Exemple d'audit :
json
{
"ts": "2025-11-03T14:00:00.000Z",
"actor": "alice@company",
"action": "feature_flag.update",
"target": "bonus.enable_vip",
"old": {"rollout": 10},
"new": {"rollout": 100},
"reason": "campaign_2311",
"ticket": "OPS-3481",
"trace_id": "cf12ab.."
}

12) Événements commerciaux et modèle de données

Les événements commerciaux ne sont pas un « texte dans les loges », mais un contrat :
  • `event_type`, `event_id`, `occurred_at`, `actor`, `subject`, `amount`, `currency`, `status`, `idempotency_key`.
  • Utilisez Outbox et « at-least-once » avec les consommateurs idempotent.

13) Kubernetes et les loges pipeline

Sidecar/DaemonSet agents avec tampon par disque (en cas de coupures réseau).
Annotations de points de routage ('log. type`, `retention. tier`).
Collectez les logs des contrôleurs K8s séparément (index de cluster).

Bit fluent (masquage, fragment) :
ini
[FILTER]
Name     modify
Match
Remove    authorization, password, card_number

14) Anti-modèles

Logs de chaîne « comme il faut », absence de 'trace _ id'.
PII/secrets dans les logs, vides payload entiers.
Des millions de clés uniques → une indexation « éclatée ».
DEBUG en vente 24/7.
Mélanger l'audit, la sécurité et les techniciens en un seul index.
Il n'y a pas de stratégie de rétention ni de test de restauration à partir de l'archive.


15) Chèque de mise en œuvre (0-45 jours)

0-10 jours

Activer W3C Trace Context dans gateway/clients, en-tête.
Convertir les logs d'application en JSON, ajouter 'trace _ id '/' span _ id'.
Interdire les PII/secrets (masquage sur l'agent), approuver la liste des champs.

11-25 jours

Décomposer les flux : tech/biz/audit/security/infra, définir la rétention et l'ACL.
Activer OTel Collector, faire tail-sampling erreurs/requêtes lentes.
Dashboards « Log Rate/Error by route » + Jump-to-trace (Exemplars).

26-45 jours

Alertes selon les modèles d'événements et corrélation avec SLO.
Archive/restauration (DR test) pour les logs froids.
Linter logs schems in CI, contrat pour événements d'affaires.


16) Métriques de maturité

Couverture des requêtes 'trace _ id' ≥ 95 %.
La part des logs JSON ≥ 99 %.
Les incidents trouvés par la via « jump-to-trace » ont été résolus <15 min (p50).
0 cas de PII dans les logs (scanner des fuites).
Retenshn est respecté pour tous les flux (nous prouvons automatiquement l'audit).


17) Applications : Mini-clips

Génération de traceparent W3C (pseudo)

txt traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01

BouQL est un groupe de logs et de SLO (exemple)


high_error_logs = rate(log_events_total{service="payments-api",level="ERROR"}[5m])
5xx_rate = sum(rate(http_requests_total{service="payments-api",status=~"5.."}[5m])) / sum(rate(http_requests_total{service="payments-api"}[5m]))
alert if high_error_logs > 10 and 5xx_rate > 0.005

OpenAPI - titres coraliens

yaml components:
parameters:
Traceparent:
name: traceparent in: header required: false schema: { type: string }

18) Conclusion

Un circuit de logage et de traçage fort est un accord + discipline : JSON-logs structurels, un seul 'trace _ id', un traitement PII sécurisé, un routage et un recentrage par flux, ainsi qu'un lien étroit avec SLO, alerting et reculs. Faites la transition de la « décharge de textes » aux contrats d'événements et de pistes, et le diagnostic des incidents prod deviendra rapide, prévisible et vérifiable.

Contact

Prendre contact

Contactez-nous pour toute question ou demande d’assistance.Nous sommes toujours prêts à vous aider !

Commencer l’intégration

L’Email est obligatoire. Telegram ou WhatsApp — optionnels.

Votre nom optionnel
Email optionnel
Objet optionnel
Message optionnel
Telegram optionnel
@
Si vous indiquez Telegram — nous vous répondrons aussi là-bas.
WhatsApp optionnel
Format : +code pays et numéro (ex. +33XXXXXXXXX).

En cliquant sur ce bouton, vous acceptez le traitement de vos données.