modulo 20 di 24 / Ore 41-60
Moduli 17-24 / Checkpoint 60 ore
Osservabilità: capire cosa è successo
Come costruire osservabilità minima nel Registro con un logger semplice: eventi da registrare, struttura dei log, come ricostruire cosa è successo leggendo la sequenza degli eventi.
Osservabilità: capire cosa è successo
Questa lezione appartiene al Modulo 20 — Logging e osservabilità minima.
Obiettivo della lezione
Costruire nel Registro la capacità di ricostruire cosa è successo leggendo i log — senza dover riaprire il codice, senza dover riprodurre il problema, guardando solo la sequenza di eventi registrati.
Alla fine i log del Registro raccontano una storia leggibile: quale azione è stata tentata, qual è stato il risultato, quale errore è comparso.
Perché serve nel percorso
Senza osservabilità, quando qualcosa va storto devi ricreare il problema passo per passo. Con i log giusti, puoi leggere cosa è successo e capire dove si trova il problema in pochi secondi.
Nel Registro del laboratorio
Scenario di esempio — un prestito fallisce:
Con i log corretti, la console mostra questa sequenza:
[INFO] ui_prestito_richiesto { strumentoId: "str-003", studenteId: "stu-042" }
[INFO] caso_uso_registra_prestito_avviato { strumentoId: "str-003" }
[WARN] registra_prestito_strumento_guasto { strumentoId: "str-003", stato: "guasto" }
[ERROR] ui_registra_prestito_fallita { codice: "STRUMENTO_GUASTO_NON_PRESTABILE" }
Leggendo questa sequenza sai esattamente cosa è successo: l’utente ha tentato di prestare lo strumento “str-003”, il caso d’uso ha trovato lo strumento ma era guasto, l’operazione è stata rifiutata e la UI ha mostrato l’errore.
Scenario di successo:
[INFO] ui_prestito_richiesto { strumentoId: "str-001", studenteId: "stu-015" }
[INFO] caso_uso_registra_prestito_avviato { strumentoId: "str-001" }
[INFO] prestito_registrato { strumentoId: "str-001", prestitoId: "pre-007" }
[INFO] ui_prestito_confermato { prestitoId: "pre-007" }
Chiaro, sequenziale, senza dati personali (studenteId è un ID anonimo).
Procedura guidata
- Identifica gli eventi principali del Registro: quali azioni avvengono, quali errori possono comparire.
- Assegna un nome a ogni evento (formato:
contesto_azione_esito). - Aggiungi i log al codice usando il logger creato nella lezione precedente.
- Usa il Registro normalmente e leggi la console: la sequenza racconta la storia?
- Simula un errore e verifica che la causa sia leggibile dai log.
Attività in classe
Definisci gli eventi da loggare per l’operazione “chiudi prestito”:
## Piano di logging per chiudiPrestito
Evento 1 — avvio operazione nella UI:
nome:
dati minimi:
Evento 2 — caso d'uso avviato:
nome:
dati minimi:
Evento 3 — successo:
nome:
dati minimi:
Evento 4 — errore PRESTITO_NON_TROVATO:
nome:
dati minimi:
Evento 5 — errore PRESTITO_GIA_CHIUSO:
nome:
dati minimi:
Poi implementa i log e verifica che la sequenza sia leggibile in console.
Spiegazione guidata per studiare
L’osservabilità minima richiede tre tipi di eventi:
1. Evento di input — cosa è arrivato nel sistema:
logger.info("ui_chiudi_prestito_richiesto", { prestitoId });
2. Evento di processo — cosa ha fatto il sistema:
logger.info("prestito_chiuso", { prestitoId, chiusura: new Date().toISOString() });
// oppure in caso di errore:
logger.warn("chiudi_prestito_gia_chiuso", { prestitoId });
3. Evento di output — cosa ha mostrato la UI:
logger.info("ui_chiudi_prestito_confermato", { prestitoId });
// oppure:
logger.error("ui_chiudi_prestito_fallita", err, { prestitoId });
Con questi tre tipi, puoi ricostruire ogni operazione del Registro.
Struttura dei nomi degli eventi:
[contesto]_[azione]_[esito opzionale]
ui_prestito_richiesto
caso_uso_registra_prestito_avviato
prestito_registrato
ui_prestito_confermato
ui_prestito_fallita
Cosa includere nei dati:
- sempre: gli ID degli oggetti coinvolti (strumentoId, prestitoId);
- per gli errori: il codice errore;
- mai: nomi di studenti, contenuto completo degli oggetti.
Esempio completo del flusso registraPrestito:
// src/presentation/azioniPrestito.js
document.getElementById("btn-presta").addEventListener("click", () => {
const strumentoId = document.getElementById("strumento-selezionato").value;
const studenteId = document.getElementById("studente-id").value;
logger.info("ui_prestito_richiesto", { strumentoId }); // log input
try {
const risultato = registraPrestito({ strumentoId, studenteId }, archivioStrumenti, archivioPrestiti);
logger.info("ui_prestito_confermato", { prestitoId: risultato.id }); // log output successo
mostraMessaggio(elem, "Prestito registrato.", "successo");
} catch (err) {
logger.error("ui_prestito_fallita", err, { strumentoId }); // log output errore
mostraMessaggio(elem, traduciErrore(err.message), "errore");
}
});
// src/application/registraPrestito.js
export function registraPrestito({ strumentoId, studenteId }, archivioStrumenti, archivioPrestiti) {
logger.info("caso_uso_registra_prestito_avviato", { strumentoId }); // log processo
const strumento = archivioStrumenti.trovaPerId(strumentoId);
if (!strumento) {
logger.warn("registra_prestito_strumento_non_trovato", { strumentoId });
throw new Error("STRUMENTO_NON_TROVATO");
}
if (strumento.stato !== "disponibile") {
logger.warn("registra_prestito_strumento_non_disponibile", { strumentoId, stato: strumento.stato });
throw new Error(`STRUMENTO_${strumento.stato.toUpperCase()}_NON_PRESTABILE`);
}
const prestito = { id: crypto.randomUUID(), strumentoId, studenteId, apertura: new Date(), chiusura: null };
archivioPrestiti.salva(prestito);
archivioStrumenti.aggiorna({ ...strumento, stato: "in_prestito" });
logger.info("prestito_registrato", { strumentoId, prestitoId: prestito.id }); // log successo
return prestito;
}
Passo per passo nel progetto
- Elenca tutte le operazioni del Registro: registra strumento, cerca, presta, chiudi, segnala guasto.
- Per ogni operazione: definisci 3 eventi (input, processo, output).
- Aggiungi i log nel codice — partendo dal caso d’uso più usato.
- Usa il Registro e verifica che la console mostri la sequenza corretta.
- Simula un errore e verifica che la causa sia leggibile.
Prova di comprensione
- Cosa si intende per “ricostruire cosa è successo dai log”?
- Perché loggare
strumentoIde non il nome dello strumento? - Qual è la differenza tra
logger.warnelogger.errornel Registro? - Come si verifica che i log siano sufficienti senza aprire il codice?
Errori da evitare
- loggare oggetti completi (
JSON.stringify(strumento)) — contiene dati non necessari; - usare nomi di eventi generici (
errore,ok,fatto) — non permettono di capire cosa è successo; - loggare solo gli errori e non i successi — non si capisce se il sistema funziona normalmente;
- loggare troppo — 20 messaggi per ogni click rendono la console inutile.
Prodotto da consegnare
I log per tutte le operazioni principali del Registro (registra strumento, registra prestito, chiudi prestito, segnala guasto) con eventi di input, processo e output. La console mostra una sequenza leggibile dopo 5 minuti di uso normale.
Checklist di chiusura
- ogni operazione principale ha almeno 3 eventi loggati (input, processo, output)
- i nomi degli eventi seguono il formato
[contesto]_[azione]_[esito] - i log non contengono nomi di studenti o oggetti completi
- la sequenza dei log in console racconta la storia dell’operazione
- gli errori includono il codice errore come contesto
Risultato atteso
Ho aggiunto log strutturati per registraPrestito e chiudiPrestito.
La console mostra la sequenza ui_richiesto → caso_uso_avviato → prestito_registrato.
In caso di errore la sequenza mostra la causa specifica (strumento guasto, prestito chiuso).
I log non contengono dati personali degli studenti.
Il prossimo passo sarebbe aggiungere log per registraStrumento e cercaStrumenti.