Loging e traccia degli eventi
Loging e traccia degli eventi
1) Obiettivo e cornice
I cavi e le roulotte sono le fondamenta della osservabilità.
I loghi rispondono a «cosa è successo» e «con quale contesto».
Le roulotte rispondono a «dove e perché lentamente/erroneamente» nel percorso di richiesta distribuito.
- Structured by default (JSON); Trace-first: ogni riga del percorso caldo è collegata a «trace _ id »/« span _ id».
- Minimo rumore, massimo segnale: livelli, sampling, anti-cardinalità.
- Sicurezza e privacy: occultamento, modifica, separazione degli accessi.
- Diagrammi di logi ed eventi versionati.
2) Tassonomia degli eventi
Separare flussi e indici per destinazione:1. Logi tecnici (runtime, errori, timeout di rete, retrai).
2. Gli eventi aziendali (registrazione, deposito, tasso, ritiro, fase KYC) sono idonei per gli analisti alimentari e gli incidenti sulle vie «monetarie».
3. Controllo (chi/quando ha cambiato cosa: configi, accessibilità, bandiere, limiti) è un registro immutabile.
4. Sicurezza (autenticazione, escalation di privilegi, sanzione/flag RER).
5. Infrastruttura (K8s events, autoscaling, HPA/VPA, nodi/disco/rete).
Per ciascun thread, le regole di retino, indicizzazione e accesso sono separate.
3) Loga strutturale (riferimento 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" }
}
Requisiti: schema piatto + allegati per dominio, campi obbligatori ('ts, level, service, env, trace _ id, msg'), valori numerici, non righe.
4) Livelli, cardinalità e volume
I livelli sono «DEBUG» (non in vendita), «INFO» (fatti aziendali), «WARN» (anomalie), «ERRORE», «FATAL» (crash).
Cardinalità: evitare chiavi arbitrarie/label dinamici. Niente «ID in chiave».
Messaggi ripetuti rate-limit attivare DEBUG solo scoped e in base al tempo (feature flag).
Idempotenza: logica «idempotency _ key» per sopprimere gli eventi duplicati dai consumatori.
5) Privacy e sicurezza
Maschera PII/segreti sugli agenti (Fluent Bit/Vector): mappe di occultamento chiave («email», «card», «token», «authorization»).
Hashtag user _ key, mantenere solo il contesto desiderato (paese, livello KYC, VIP-tier).
Separare lo storage da caldo (ricerca online) e freddo (archivio senza PI/c da un contesto tagliato).
Controllo - append-only, storage WORM, accesso solo least private.
6) Traccia: standard e contesto
W3C Trace Text: intestazioni «traceparent »/« tracestate», più baggage per chiavi sicure (ad esempio «tenant _ id», «region»).
Collegamento tra metriche e trailer: Exceplars - Trasferisci «trace _ id» ai punti di istogramma samplati (accelera RCA).
Sampling: sampling di base 1-5% + dinamico «su errori/p95 lento» al 100% per le richieste problematiche.
Links: per le code asincrone/saghe, collegare gli spans attraverso links, non solo attraverso parent'
7) Raccolta e routing
Agenti: Fluent Bit/Vector per i cassetti; Esportazione OTLP in .
Collector: gateway centrale (batch/form/filter/routing).
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)
OTel Raccoglitore (sezione):
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) Strumenti: SDK esempi
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 Traccia intestazione
nginx proxy_set_header traceparent $http_traceparent;
proxy_set_header tracestate $http_tracestate;
9) Loghi come segnale per gli alert e le attività automatiche
Pattern errati ('psp _ decline', 'fraud _ flag') aggregare e correlare con SLO.
Alert su pattern-rate: "5xx a/withdraw> 0. 5% per 10", "fraud _ flag spike> + 200% per la base".
Azione automatica: con «withdrawals _ manual _ mode = true», accendi kill-switch attraverso la piattaforma dei flag.
rate(count_over_time({service="payments-api", level="ERROR", event="psp_decline"}[5m])) > 5
10) Retenschn, indicizzazione, archiviazione
Caldo: 7-14 giorni (indagine rapida).
Caldo: 30-90 giorni (trend, RCA).
Freddo: 180-365 + (archivio, controllo) - compressione, classi a basso costo, forse senza ricerca a tutto testo.
Indicizzazione: chiavi fisse ('service, env, level, event, trace _ id, user. tenant _ id '), proibizione dell'indice «tutto di fila».
Limiti per la dimensione dell'evento (ad esempio, ≤ 32KB), trim/basso: «superfluo in storage - nemico MTTR».
11) Controllo e invariabilità
Gli eventi di controllo scrivono un flusso separato con firme/hash, tempo del server, 'who/what/when/why', riferimento al ticket.
«Chi ha inserito la bandiera dei bonus al 100% in DE?» - La risposta deve essere in 1-2 richieste.
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) Eventi aziendali e modello di dati
Gli eventi aziendali non sono «testo nei fogli», ma un contratto:- `event_type`, `event_id`, `occurred_at`, `actor`, `subject`, `amount`, `currency`, `status`, `idempotency_key`.
- Utilizzare Outbox e at-least-once con i consumatori idempotati.
13) Kubernets e topeline
Agenti Sidecar/DaemonSet con buffer su disco (interruzioni di rete).
Annotazioni sottostanti da instradare ('log. type`, `retention. tier`).
Assemblare i logi dei controller K8s separatamente (indice cluster).
ini
[FILTER]
Name modify
Match
Remove authorization, password, card_number
14) Anti-pattern
Fogli stringa «come necessario», nessun «trace _ id».
PII/segreti nei cassetti, i dampi payload sono interi.
Milioni di chiavi uniche → l'indicizzazione esplosa.
DEBUG in vendita 24/7.
Miscelare il controllo, la sicurezza e i tecnici in un unico indice.
Nessuna regola di restauro o test di ripristino dall'archivio.
15) Assegno foglio di implementazione (0-45 giorni)
0-10 giorni
Abilita W3C Trace Text in gateway/client, spazza le intestazioni.
Traduce i fogli di allegato in JSON, aggiungi «trace _ id »/« span _ id».
Impedisci PII/segreti (maschera su agente), approva l'elenco dei campi.
11-25 giorni
Espandi flussi: tech/biz/audit/sicurezza/infra, imposta retino e ACL.
Abilita OTel Raccoglitore, tail-sampling errori/query lente.
Dashboard «Log Rate/Errore by Route» + Jump-to-trace (Excempars).
26-45 giorni
Alert per modelli di eventi e correlazione con SLO.
Archivio/ripristino (DR-Test) per i fogli freddi.
Linter diagrammi in CHI, contratto per eventi aziendali.
16) Metriche di maturità
La copertura di query «trace _ id» è del 95%.
La percentuale di ≥ JSON è del 99%.
Gli incidenti trovati via jump-to-trace sono stati risolti <15 mine (p50).
0 casi di PII nei fogli (scanner di perdita).
Ritensh rispettato in tutti i flussi (verifica automatica).
17) Applicazioni: mini snippet
Generazione W3C traceparent (pseudo)
txt traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
PromQL - raccordo di fogli e SLO (esempio)
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
Titoli OpenAPI - Corellari
yaml components:
parameters:
Traceparent:
name: traceparent in: header required: false schema: { type: string }
18) Conclusione
Un tracciato forte di loging e tracciabilità è un contratto + disciplina: logi JSON strutturali, unâ trace _ id ", trattamento sicuro del PII, instradamento e ritocco dei flussi, e un collegamento stretto con SLO, alerting e ritocchi. Passare da una discarica di testi a contratti di eventi e piste, e diagnosticare gli incidenti di prod sarà veloce, prevedibile e verificabile.