--- title: "Implementare un logger categorizzabile" excerpt: "Scopri come implementare un logger categorizzabile in Flutter per migliorare la gestione dei log." author: francesco date: "25 aprile 2025" category: "Sviluppo frontend" tags: - Flutter - Frontend - Log coverImage: "/assets/posts/logger/head.png?height=600&width=1200" hidden: 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: ```dart 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: ```dart 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 _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: ```dart // Assumiamo di avere una lista di log del tipo List _logs = []; // Filtriamo i log in base alla categoria LogLevel category = LogLevel.warning; List 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.