Un buon log non è una frase: è un evento con dati interrogabili. ILogger supporta il logging strutturato, che conserva separatamente il testo e i valori.
Segnaposto, non interpolazione
// Da evitare: il valore si perde dentro la stringa e la stringa si costruisce sempre
log.LogInformation($"Ordine {ordine.Id} creato da {utente}");
// Corretto: Id e Utente restano campi separati e interrogabili
log.LogInformation("Ordine {OrdineId} creato da {Utente}", ordine.Id, utente);
Nei sistemi di raccolta dei log si potrà cercare "tutti gli eventi con OrdineId = 4521" invece di cercare testo.
LoggerMessage: log generati a compilazione
Per i log frequenti, l'attributo LoggerMessage genera metodi ottimizzati che evitano allocazioni e controllano già a compilazione che i segnaposto corrispondano ai parametri.
public static partial class Log
{
[LoggerMessage(EventId = 1001, Level = LogLevel.Information,
Message = "Ordine {OrdineId} creato per {Importo} euro")]
public static partial void OrdineCreato(this ILogger logger, int ordineId, decimal importo);
[LoggerMessage(EventId = 1002, Level = LogLevel.Warning,
Message = "Pagamento rifiutato per l'ordine {OrdineId}: {Motivo}")]
public static partial void PagamentoRifiutato(this ILogger logger, int ordineId, string motivo);
}
log.OrdineCreato(ordine.Id, ordine.Totale);
Livelli e rumore
- Information per gli eventi di business significativi.
- Warning per situazioni anomale ma gestite.
- Error per operazioni fallite, sempre con l'eccezione come primo argomento.
- Debug per i dettagli, disattivati in produzione.
E mai dati personali o segreti nei log: password, token e dati sensibili non devono finire in un file che molte persone possono leggere.
Commenti (0)
Nessun commento ancora.