5.3 KiB
title, excerpt, author, date, category, tags, coverImage, hidden
| title | excerpt | author | date | category | tags | coverImage | hidden | |||
|---|---|---|---|---|---|---|---|---|---|---|
| Implementare un logger categorizzabile | Scopri come implementare un logger categorizzabile in Flutter per migliorare la gestione dei log. | francesco | 25 aprile 2025 | Sviluppo frontend |
|
/assets/posts/logger/head.png?height=600&width=1200 | true |
Quando si pubblica un'applicazione, spesso si ha bisogno di un modo per monitorare le performance e il comportamento dell'app. Un modo comune per farlo è utilizzare un logger, che può registrare eventi, errori e altre informazioni utili. In questo articolo, esploreremo come implementare un logger categorizzabile in Flutter, che ci permetterà di organizzare i log in categorie specifiche e facilitare la loro gestione.
Perché un logger categorizzabile?
Molti progetti utilizzano Firebase Crashlytics o Sentry per monitorare gli errori e le performance. Tuttavia, questi strumenti richiedono che l'applicazione sia costantemente in contatto con il servizio per inviare i log. In alcuni casi, potrebbe non essere necessario avere un flusso continuo di log, ma può bastare registrare gli eventi localmente e inviarli in un secondo momento, ad esempio quando l'app è online o quando l'utente lo richiede. È proprio qui che entra in gioco il logger categorizzabile.
Un logger categorizzabile consente di organizzare i log in categorie specifiche, rendendo più facile la loro gestione e analisi. Possiamo ad esempio avere categorie per gli errori, le performance, le azioni degli utenti e così via. In questo modo, possiamo filtrare i log in base alla categoria e concentrarci solo su quelli che ci interessano in un determinato momento.
Creazione del logger
Iniziamo definendo i tipi di eventi di cui vogliamo tenere traccia:
enum LogLevel {
debug(0),
info(1),
warning(2),
error(3),
fatal(99);
const LogLevel(this.value);
final int value;
}
In questo esempio, abbiamo definito cinque livelli di log: debug, info, warning,
error e fatal. Ogni livello ha un valore associato che ci permette di
classificarli in ordine di gravità. È qui che possiamo decidere di aggiungere
categorie come performance, userAction, network e così via.
Passiamo ora alla classe Logger. Questa classe sarà responsabile della registrazione dei log e della loro gestione. Ecco un esempio di implementazione:
typedef LogTransformer = void Function(LogEntry entry);
class LogEntry {
final LogLevel level;
final String message;
final String? category;
final DateTime timestamp;
// ...
}
class Logger {
static final Logger _instance = Logger._internal();
factory Logger() => _instance;
Logger._internal();
final List<LogTransformer> _transformers = [];
void addTransformer(LogTransformer transformer) {
_transformers.add(transformer);
}
void log(LogLevel level, String message, {String? category}) {
final entry = LogEntry(
level: level,
message: message,
category: category,
timestamp: DateTime.now(),
);
for (final transformer in _transformers) {
// Invia il messaggio trasformato a un servizio di logging
// oppure a un repository locale.
transformer(entry);
}
}
}
In questo esempio, abbiamo creato una classe Logger che utilizza il
singleton pattern per garantire che ci sia solo un'istanza del logger in tutta
l'applicazione. La classe ha un metodo log che accetta un livello di log,
un messaggio e una categoria opzionale. Quando viene chiamato il metodo log,
viene creato un oggetto LogEntry che contiene tutte le informazioni sul log.
Il logger accetta anche una lista di trasformatori (LogTransformer) che sono
responsabili della gestione dei log. Questi trasformatori possono essere
utilizzati per inviare i log a un servizio esterno, salvarli in un file locale
o eseguire qualsiasi altra operazione necessaria, come salvare i log in una
List per una successiva visione degli stessi.
Il modo in cui abbiamo definito l'enum LogLevel e la classe LogEntry ci
permette di filtrare molto facilmente i log in base alla loro categoria:
// Assumiamo di avere una lista di log del tipo
List<LogEntry> _logs = [];
// Filtriamo i log in base alla categoria
LogLevel category = LogLevel.warning;
List<LogEntry> filteredLogs = _logs
.where((log) => log.category.value >= category.value)
.toList();
Così facendo, ignoriamo tutti i log di tipo debug e info. Ovviamente, possiamo
anche prendere solo i log di una categoria specifica, ad esempio performance o userAction,
a seconda delle nostre esigenze.
Conclusione
In questo articolo, abbiamo visto come implementare un logger categorizzabile
in Flutter. Questo approccio ci consente di organizzare i log in categorie
specifiche, facilitando la loro gestione e analisi. Abbiamo anche visto come
creare una classe Logger che utilizza il singleton pattern e accetta
trasformatori per gestire i log in modo flessibile.
Abbiamo implementato un logger molto semplice ma estremamente potente. A TECHTONIC FAULT, crediamo che la semplicità sia la chiave per un buon sviluppo software, senza compromettere la potenza e la flessibilità. Con questo logger, possiamo monitorare le performance e il comportamento delle nostre applicazioni in modo efficace e senza complicazioni inutili.