Have you used any logger plugin (flutter log handler , flog)
#flutter
Answer
Overview
Yes, Flutter has several logging plugins for better debugging, error tracking, and production monitoring. Popular options include logger, fimber, f_logs, and pretty_dio_logger for network logs.
1. logger Package (Most Popular)
Beautiful, colorful console logs with multiple levels.
Installation
yamldependencies: logger: ^2.0.0
Basic Usage
dartimport 'package:logger/logger.dart'; final logger = Logger(); void main() { logger.d('Debug message'); // Debug logger.i('Info message'); // Info logger.w('Warning message'); // Warning logger.e('Error message'); // Error logger.wtf('What a terrible failure!'); // Fatal }
Custom Configuration
dartfinal logger = Logger( printer: PrettyPrinter( methodCount: 2, // Stack trace depth errorMethodCount: 8, // Error stack trace lineLength: 120, // Console width colors: true, // Colorful output printEmojis: true, // Add emoji icons printTime: true, // Include timestamp ), ); // Simple output (no colors/stack trace) final simpleLogger = Logger( printer: SimplePrinter(), );
Log Levels
dart// Development — verbose Logger.level = Level.verbose; // All logs // Production — errors only Logger.level = Level.error; // No logs Logger.level = Level.nothing;
Log to File
dartimport 'dart:io'; class FileOutput extends LogOutput { final File file; FileOutput(this.file); void output(OutputEvent event) { for (var line in event.lines) { file.writeAsStringSync('$line ', mode: FileMode.append); } } } final logger = Logger( output: FileOutput(File('logs.txt')), );
2. fimber (Lightweight)
Lightweight logging inspired by Timber (Android).
Installation
yamldependencies: fimber: ^0.7.0
Usage
dartimport 'package:fimber/fimber.dart'; void main() { Fimber.plantTree(DebugTree()); // Setup logger Fimber.d('Debug message'); Fimber.i('Info message'); Fimber.w('Warning message'); Fimber.e('Error message'); }
Custom Tree
dartclass CrashReportingTree extends LogTree { void log(String level, String message, {String? tag, dynamic ex}) { if (level == 'E') { // Send error to Crashlytics, Sentry, etc. crashlytics.recordError(message, ex); } } } Fimber.plantTree(CrashReportingTree());
3. f_logs (File Logging)
Logs to files with filtering and export.
Installation
yamldependencies: f_logs: ^2.0.0
Usage
dartimport 'package:f_logs/f_logs.dart'; void main() async { await FLog.applyConfigurations( isDevelopmentDebuggingEnabled: true, timestampFormat: LogsConfig.DEFAULT_TIMESTAMP, ); FLog.info(text: 'App started'); FLog.warning(text: 'Low battery'); FLog.error(text: 'Network error', exception: Exception('Timeout')); }
Export Logs
dart// Export logs to file final file = await FLog.exportLogs(); print('Logs saved to: ${file.path}'); // Share logs via email, WhatsApp, etc. Share.shareFiles([file.path], text: 'App logs');
Clear Logs
dartawait FLog.clearLogs();
4. pretty_dio_logger (Network Logging)
Logs HTTP requests/responses for Dio.
Installation
yamldependencies: dio: ^5.3.0 pretty_dio_logger: ^1.3.0
Usage
dartimport 'package:dio/dio.dart'; import 'package:pretty_dio_logger/pretty_dio_logger.dart'; final dio = Dio(); dio.interceptors.add( PrettyDioLogger( requestHeader: true, requestBody: true, responseBody: true, responseHeader: false, error: true, compact: true, maxWidth: 90, ), ); // All network calls now logged final response = await dio.get('https://api.example.com/users');
Output:
text┌────────────────────────────────────────────────────────────── │ GET https://api.example.com/users ├────────────────────────────────────────────────────────────── │ Headers: │ • content-type: application/json ├────────────────────────────────────────────────────────────── │ Response [200 OK] (250ms) │ Body: │ {"users": [...]} └──────────────────────────────────────────────────────────────
5. talker (All-in-One)
Logs, errors, exceptions, and HTTP logs in one package.
Installation
yamldependencies: talker: ^3.0.0 talker_dio_logger: ^3.0.0 talker_flutter: ^3.0.0
Usage
dartimport 'package:talker_flutter/talker_flutter.dart'; final talker = Talker(); void main() { talker.info('App started'); talker.error('Something went wrong'); runApp(MyApp(talker: talker)); } // View logs in UI TalkerScreen(talker: talker);
Features:
- Console logging
- UI viewer (built-in logs screen)
- HTTP logging (Dio interceptor)
- Error tracking
- Custom filters
Comparison Table
| Package | Size | Features | Best For |
|---|---|---|---|
| logger | Small | Colorful console, stack traces | Development |
| fimber | Tiny | Lightweight, custom trees | Production |
| f_logs | Medium | File export, email logs | Production |
| pretty_dio_logger | Small | Network logs only | Dio HTTP |
| talker | Large | All-in-one (logs + UI) | Full apps |
Production Logging Setup
dartimport 'package:logger/logger.dart'; import 'package:flutter/foundation.dart'; class AppLogger { static final Logger _logger = Logger( printer: PrettyPrinter( methodCount: kDebugMode ? 2 : 0, // Stack trace in debug only colors: kDebugMode, printEmojis: kDebugMode, ), level: kDebugMode ? Level.debug : Level.error, // Errors only in release ); static void debug(String message) => _logger.d(message); static void info(String message) => _logger.i(message); static void warning(String message) => _logger.w(message); static void error(String message, [dynamic error, StackTrace? stackTrace]) { _logger.e(message, error: error, stackTrace: stackTrace); // Send to crash reporting in production if (!kDebugMode) { FirebaseCrashlytics.instance.recordError(error, stackTrace); } } } // Usage AppLogger.info('User logged in'); AppLogger.error('API call failed', error, stackTrace);
Best Practices
dart// ✅ Use different log levels logger.d('Detailed debug info'); logger.i('User action'); logger.w('Potential issue'); logger.e('Error occurred'); // ✅ Disable logs in release Logger.level = kDebugMode ? Level.verbose : Level.error; // ✅ Add context to logs logger.e('API Error', error: error, stackTrace: stackTrace); // ✅ Use custom logger wrapper class MyLogger { static void logNetworkError(String url, int statusCode) { logger.e('Network Error: $url returned $statusCode'); } } // ❌ Don't log sensitive data logger.d('Password: $password'); // ❌ Security risk // ❌ Don't log in hot paths (performance) for (var i = 0; i < 10000; i++) { logger.d('Loop $i'); // ❌ Slows down app }
Integration with Crash Reporting
dartimport 'package:firebase_crashlytics/firebase_crashlytics.dart'; class CrashlyticsLogger { static void log(String message) { logger.i(message); FirebaseCrashlytics.instance.log(message); } static void recordError(dynamic error, StackTrace stackTrace) { logger.e('Error', error: error, stackTrace: stackTrace); FirebaseCrashlytics.instance.recordError(error, stackTrace); } }
Complete Example
dartimport 'package:flutter/material.dart'; import 'package:logger/logger.dart'; final logger = Logger( printer: PrettyPrinter( methodCount: 2, colors: true, printEmojis: true, ), ); void main() { logger.i('App started'); runApp(MyApp()); } class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( home: HomePage(), ); } } class HomePage extends StatelessWidget { Future<void> fetchData() async { try { logger.d('Fetching data...'); // API call final response = await http.get(Uri.parse('https://api.example.com')); logger.i('Data fetched successfully'); } catch (e, stackTrace) { logger.e('Failed to fetch data', error: e, stackTrace: stackTrace); } } Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Logger Example')), body: Center( child: ElevatedButton( onPressed: fetchData, child: Text('Fetch Data'), ), ), ); } }
Learn more: