modulo 20 di 24 / Ore 41-60
Moduli 17-24 / Checkpoint 60 ore
Esercizio: ricostruire un errore dai log
Leggere una sequenza di log del Registro del laboratorio, ricostruire cosa è successo e individuare dove si è verificato l'errore senza guardare il codice sorgente.
Esercizio: ricostruire un errore dai log
Questa lezione appartiene al Modulo 20 — Logging e osservabilità minima.
Cos’è questo esercizio
Hai a disposizione una sequenza di log prodotti dal Registro durante una sessione reale. Devi rispondere a tre domande senza guardare il codice sorgente:
- Cosa stava facendo l’utente?
- Dove si è verificato l’errore?
- Cosa ha causato l’errore?
Questo è il lavoro dell’osservabilità: i log devono essere abbastanza informativi da permettere la diagnosi senza accedere al codice.
Log da analizzare — Scenario A
Leggi questa sequenza di log nell’ordine in cui appare nella console:
[INFO] prestito_avviato { strumentoId: "str-042", origine: "ui" }
[INFO] strumento_trovato { strumentoId: "str-042", stato: "disponibile" }
[INFO] regola_verificata { strumentoId: "str-042", esito: "ok" }
[ERROR] salvataggio_fallito { operazione: "salva_prestito", errore: "ARCHIVIO_NON_DISPONIBILE" }
[INFO] messaggio_utente { testo: "Non riesco a salvare i dati. Riprova tra poco." }
Domande:
- Quale operazione stava eseguendo l’utente?
- Il dominio ha trovato qualcosa di sbagliato? Come lo sai?
- Dove si è verificato l’errore? In quale livello?
- L’utente ha ricevuto un messaggio comprensibile?
- Cosa faresti per diagnosticare l’errore infrastrutturale?
Log da analizzare — Scenario B
[INFO] prestito_avviato { strumentoId: "str-017", origine: "ui" }
[ERROR] strumento_non_trovato { strumentoId: "str-017" }
[INFO] messaggio_utente { testo: "Strumento non trovato. Controlla l'ID." }
Domande:
- L’errore è di dominio, applicativo o infrastrutturale?
- Quale passo del caso d’uso non ha trovato il dato?
- Cosa suggeriresti all’utente per risolvere?
- Questo log è sufficiente per diagnosticare il problema senza guardare il codice?
Log da analizzare — Scenario C (log mal fatto)
[INFO] click ricevuto
[ERROR] Uncaught TypeError: Cannot read properties of undefined (reading 'stato')
at registraPrestito (application/registraPrestito.js:14)
at HTMLButtonElement.<anonymous> (presentation/ui.js:32)
[INFO] operazione completata
Domande:
- Questo log permette di capire cosa stava facendo l’utente? Perché no?
- Quale informazione manca nel primo
[INFO]? - Lo stack trace è utile per il debugging — ma è adatto a essere mostrato all’utente?
- L’ultimo
[INFO] operazione completataè accurato? Cosa è andato storto? - Come riscriveresti il logging di questo scenario?
Come costruire log leggibili
Dopo aver analizzato i tre scenari, puoi costruire un pattern di logging per il tuo Registro.
Un buon log ha:
- evento — cosa è successo (
prestito_avviato,strumento_non_trovato) - contesto — i dati minimi per capire di cosa si tratta (
strumentoId,prestitoId) - livello —
INFOper eventi normali,ERRORper fallimenti - mai dati personali — no nomi di studenti, no testo libero dell’utente
// Logger minimale per il Registro (wrapper di console)
const logger = {
info: (evento, dati = {}) => {
console.log(`[INFO] ${evento}`, dati);
},
error: (evento, dati = {}) => {
console.error(`[ERROR] ${evento}`, dati);
}
};
// Uso nei casi d'uso
async function registraPrestito(comando) {
logger.info("prestito_avviato", { strumentoId: comando.strumentoId });
const strumento = await archivioStrumenti.trovaPerId(comando.strumentoId);
if (!strumento) {
logger.error("strumento_non_trovato", { strumentoId: comando.strumentoId });
throw new Error("STRUMENTO_NON_TROVATO");
}
logger.info("strumento_trovato", { strumentoId: strumento.id, stato: strumento.stato });
// ...resto del caso d'uso
}
Procedura guidata
- Leggi ogni scenario di log dall’alto in basso, come una storia.
- Identifica il punto in cui la storia cambia: dove compare il primo
[ERROR]? - Rispondi alle domande per iscritto — senza aprire il codice.
- Confronta le tue risposte con il gruppo o col docente.
- Per lo Scenario C: riscrivi il logging come vorresti che fosse.
Attività in classe
## Analisi log — mie risposte
Scenario A:
1. Operazione:
2. Problema nel dominio:
3. Livello dell'errore:
4. Messaggio utente adeguato (sì/no):
5. Prossimo passo di diagnosi:
Scenario B:
1. Tipo di errore:
2. Passo che ha fallito:
3. Suggerimento all'utente:
4. Log sufficiente (sì/no):
Scenario C:
1. Informazione mancante:
2. Riscrittura proposta del logging:
Spiegazione guidata per studiare
Leggere i log è una competenza pratica. Un log ben scritto permette di capire cosa è successo senza riaprire il codice — come un medico che legge un referto invece di riesaminare il paziente da zero.
Il punto centrale è: il log deve raccontare una storia. Ogni riga è un evento. La sequenza degli eventi ricostruisce l’operazione. Il primo [ERROR] indica dove la storia si è interrotta.
Il rischio tipico è il log troppo vago ("click ricevuto", "operazione completata") o il log che espone stack trace tecnici — utili per il developer, non per la diagnosi in produzione. Il punto di equilibrio è: evento + contesto + livello, senza dati personali.
Passo per passo nel progetto
- Apri la console del browser mentre usi il tuo Registro.
- Esegui tre operazioni: registra uno strumento, apri un prestito, segnala un guasto.
- Leggi i log prodotti: raccontano la storia dell’operazione? Si capisce dove sono nel codice?
- Se i log sono assenti o confusi, aggiungi
logger.infonei casi d’uso principali. - Prova a provocare un errore (strumento inesistente) e verifica che il log lo registri chiaramente.
Esempio da leggere lentamente
// Log di una sessione con due operazioni: una ok, una fallita
[INFO] strumento_registrato { strumentoId: "str-051", categoria: "Elettrico" }
[INFO] prestito_avviato { strumentoId: "str-051" }
[INFO] strumento_trovato { stato: "disponibile" }
[INFO] regola_verificata { esito: "ok" }
[INFO] prestito_salvato { prestitoId: "pre-001" }
[INFO] strumento_aggiornato { stato: "in_prestito" }
[INFO] prestito_avviato { strumentoId: "str-999" }
[ERROR] strumento_non_trovato { strumentoId: "str-999" }
Dalla seconda sequenza si capisce immediatamente: l’utente ha tentato di prestare uno strumento con ID str-999 che non esiste nell’archivio. Nessun dato personale, nessuno stack trace — solo l’evento e il contesto minimo.
Prova di comprensione
- Riesci a ricostruire la storia dello Scenario A senza guardare il codice?
- Cosa rende il log dello Scenario C inutilizzabile per la diagnosi?
- Quale informazione aggiungeresti al log
prestito_avviatoper renderlo più utile?
Errori da evitare
- scrivere log così vaghi da non poter ricostruire nulla (
"errore","ok"); - includere nomi di studenti o testo libero dell’utente nei log;
- mostrare stack trace completi all’utente nella UI;
- non loggare nulla e scoprire in retrospettiva di non poter diagnosticare il problema.
Prodotto da consegnare
Può essere:
- le risposte scritte ai tre scenari di log;
- la riscrittura del log dello Scenario C;
- un
loggerminimale aggiunto al progetto con almeno tre eventi registrati nei casi d’uso principali.
Checklist di chiusura
- Ho risposto per iscritto alle domande dei tre scenari
- Ho identificato il livello dell’errore in ogni scenario
- Ho riscritto il logging dello Scenario C in modo più leggibile
- Il mio Registro produce log che permettono di ricostruire le operazioni principali
- I log non contengono nomi di studenti o dati personali
Domande per la revisione
- Guardando i log del tuo Registro, riesci a ricostruire l’ultima sessione di test?
- C’è qualche operazione che non produce nessun log? Quale?
- Come distingueresti un errore applicativo da uno infrastrutturale leggendo solo i log?
Risultato atteso
Alla fine lo studente deve saper dire:
Nello Scenario A, l'errore è [tipo] e si è verificato nel livello [X] perché [motivo].
Nello Scenario C, il log è mal scritto perché [motivo] — lo riscriverei così: [proposta].
Nel mio Registro, ho aggiunto log per [eventi principali].
Se questa spiegazione non è possibile, la lezione non è ancora davvero conclusa.