I bug in produzione capitano a tutti. La differenza tra un disastro e un fastidio temporaneo sta nella preparazione, nella risposta coordinata e nel miglioramento continuo. Questa guida pratica copre prevenzione, rilevamento, triage, contenimento, risoluzione e post-mortem, con esempi e checklist operative.
Prevenzione intelligente (prima che succeda)
- Feature flags: rilascia codice disattivato per poter spegnere rapidamente parti difettose senza rollback completi.
- Guardrail automatici: test end-to-end critici, contract test tra servizi, linting e analisi statica in CI.
- Quality gates: blocca i deploy se la copertura minima o gli smoke test non passano.
- Osservabilità by design: log strutturati, tracing distribuito, metriche (p95/p99), health check e dashboard pre-configurate.
- Rollback facile: strategie di deployment reversibili (blue/green, canary) e procedure documentate.
- Chaos e load testing: trova i punti deboli prima che lo facciano gli utenti.
Rilevamento rapido
- Alert azionabili: regole su error rate, latenza, codice 5xx, conversioni e code backlog. Ogni alert deve indicare chi agisce e come.
- Triangolazione: correla log, metriche e trace per isolare il servizio, la versione e l’endpoint coinvolti.
- Segnalazioni utenti: moduli in-app e canali di supporto con ID incidente e raccolta automatica del contesto (browser, release, feature flag).
Triage: classificare per impatto e urgenza
| Severità | Descrizione | Tempo target | Azione |
|---|---|---|---|
| S1 | Interruzione totale o perdita dati | Immediato | War room, blocco rilasci, fix/rollback |
| S2 | Funzionalità chiave degradata | Ore | Hotfix o disattiva feature |
| S3 | Bug non critico con workaround | Giorni | Pianifica sprint |
| S4 | Minimi o cosmetici | Backlog | Batch periodico |
Contenimento immediato
- Disattiva la feature tramite flag o kill switch.
- Rollback alla release stabile precedente; conserva i log della release difettosa.
- Throttling o circuit breaker su dipendenze lente per proteggere il sistema.
- Comunicazione chiara: stato interno (chat dedicata) e messaggi utente (banner di stato, pagina status).
Diagnosi e risoluzione
- Riproduci il problema in staging con la stessa versione, dati sintetici simili e feature flag identici.
- Isola la regressione con git bisect e confronta la configurazione runtime (variabili, secret, limiti).
- Strumenta il punto sospetto: log a livello
debugtemporaneo o trace spans più granulari. - Scrivi il test che fallisce prima del fix: evita ricadute.
- Hotfix piccolo, revisioni rapide, e canary progressivo con metriche di guardia.
Esempio di runbook per un endpoint 5xx
1. Verifica dashboard: error rate > 2% su /checkout
2. Controlla release attiva: v2025.08.07-canary
3. Disattiva flag "promo_dynamic_pricing"
4. Se 5xx persistono > 5 minuti, esegui rollback a v2025.08.05
5. Contatta on-call backend e SRE nel canale #incident-ops
6. Apri ticket "INC-####" con timeline e grafici
7. Avvia post-mortem entro 48 ore
Comunicazione durante l’incidente
- Un unico incident commander: decide priorità e deleghe, tiene la timeline.
- Canali separati: tecnico (profondo) e stakeholder (sintetico). Riduci il rumore.
- Aggiornamenti cadenzati: es. ogni 15–30 minuti, con stato, impatto, azioni successive e ETA.
Post-mortem senza colpe
- Fatti e timeline: che cosa è successo, quando e con quali segnali.
- Causa radice (tecnica e organizzativa), non colpe personali.
- Azioni correttive SMART: responsabile, scadenza e verifica di efficacia.
- Condivisione: rendi il post-mortem ricercabile e rivedilo periodicamente.
Miglioramento continuo
- Debt budget: quota fissa di sprint per affrontare cause ricorrenti.
- Indicatori di qualità: MTTR, MTTD, tasso di rollback, regressioni riaperte.
- Playbook aggiornati: integra ogni lezione nel runbook e nelle checklist di rilascio.
- Formazione: simulazioni periodiche (game day) e guardrail automatizzati in CI/CD.
Checklist operative
Prima del rilascio
- Changelog e migrazioni documentati
- Smoke test su staging e produzione dopo il deploy
- Feature flags pronti per rollback logico
- Dashboard e alert verificati
Durante l’incidente
- Nomina incident commander
- Classifica severità (S1–S4)
- Applica contenimento (flag/rollback/throttling)
- Comunica a utenti e stakeholder
Dopo l’incidente
- Post-mortem entro 48 ore
- Test di regressione aggiunti
- Azioni correttive con responsabile e data
- Retrospettiva e aggiornamento playbook
Pattern tecnici utili
- Idempotenza e retry con backoff per chiamate instabili.
- Rate limiting e token bucket per proteggere risorse core.
- Bulkhead e circuit breaker per confinare i guasti.
- Validazioni lato server con messaggi diagnostici nei log.
- Schema versioning e migrazioni forward-compatible.
Esempio di log strutturato
{
"timestamp": "2025-08-08T10:15:30Z",
"level": "ERROR",
"service": "payments",
"version": "v2025.08.07",
"trace_id": "9b1d7e...",
"span_id": "91af02...",
"endpoint": "POST /checkout",
"user_segment": "EU",
"error": {"type":"TimeoutError","message":"gateway > 2s"},
"feature_flags": {"promo_dynamic_pricing": true},
"kv": {"bank":"XYZ","attempt":2}
}
Template di annuncio stato per gli utenti
Stiamo riscontrando un problema che impatta i pagamenti per alcuni utenti EU. Il team è al lavoro per ripristinare il servizio. Aggiornamento previsto alle 11:30 CEST. Ci scusiamo per il disagio.
Conclusione
Non esiste zero bug in produzione. Esiste però una disciplina che riduce l’impatto: prevenzione, osservabilità, risposta coordinata, apprendimento sistematico. Con processi chiari e strumenti adeguati, i bug diventano occasioni per rendere il tuo sistema più resiliente.