flutter_log_interceptor 0.1.0 copy "flutter_log_interceptor: ^0.1.0" to clipboard
flutter_log_interceptor: ^0.1.0 copied to clipboard

The smart, zero-setup logging layer for Flutter. Beautiful colored logs, HTTP interception, in-app overlay, auto-silent in release — all from one line: FLog.init()

example/lib/main.dart

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_log_interceptor/flutter_log_interceptor.dart';
import 'package:http/http.dart' as http;

void main() {
  FLog.init(
    theme: FLogTheme.minimal,
    minLevel: FLogLevel.debug,
    autoLogErrors: true,
    persistLogs: true,
    maxStoredLogs: 500,
    boxedLogs: true,
    showFloatingButton: true,
  );

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FLog Demo',
      navigatorObservers: [FLog.navigatorObserver],
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: Stack(
        children: [
          const HomePage(),
          FLogOverlay(),
        ],
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with FLogMixin {
  final Dio _dio = Dio();
  late final FLogHttpClient _httpClient;

  @override
  void initState() {
    super.initState();
    _dio.interceptors.add(FLogDioInterceptor());
    _httpClient = FLogHttpClient(http.Client());
    logI('HomePage initialised');
  }

  @override
  void dispose() {
    _httpClient.close();
    super.dispose();
  }

  Future<void> _runDemoLogs() async {
    logD('Button tapped — running demo logs');

    FLog.d('Debug message', tag: 'Demo');
    FLog.i('Info message', tag: 'Demo');
    FLog.w('Warning — something to watch', tag: 'Demo');

    FLog.i('Order placed', tag: 'OrderService', data: {
      'orderId': 'ORD_991',
      'amount': 2999,
      'success': true,
    });

    try {
      throw Exception('Simulated payment timeout');
    } catch (e, st) {
      FLog.e('Payment gateway timeout',
          tag: 'CartService', error: e, stackTrace: st);
    }

    try {
      throw Exception('Simulated crash');
    } catch (e, st) {
      FLog.f('Unhandled exception', tag: 'App', error: e, stackTrace: st);
    }
  }

  Future<void> _runLongLogs() async {
    // Long message — over 120 chars, should show expand arrow
    FLog.i(
      'User session validated successfully after token refresh. '
      'Access token expires in 3600 seconds. Refresh token expires in 30 days. '
      'User roles: [admin, editor, viewer]. Last login: 2024-01-15T09:32:11Z.',
      tag: 'AuthService',
    );

    // Warning with rich data map
    FLog.w('Cache miss — falling back to network', tag: 'CacheManager', data: {
      'key': 'user_profile_v2_usr_00912',
      'strategy': 'stale-while-revalidate',
      'ttl': 300,
      'miss_reason': 'expired',
      'fallback_url': 'https://api.example.com/v2/users/00912/profile',
      'retry_count': 3,
      'last_cached_at': '2024-01-15T08:00:00Z',
      'cache_size_kb': 1024,
    });

    // Warning with deep nested data
    FLog.w('Sync conflict — remote config out of date',
        tag: 'SyncService',
        data: {
          'userId': 'usr_00912',
          'conflictField': 'notification_preferences',
          'localValue': {'push': true, 'email': false, 'sms': true},
          'remoteValue': {'push': false, 'email': true, 'sms': true},
          'resolution': 'pending_manual_review',
          'attemptedAt': '2024-01-15T09:35:22.441Z',
        });

    // Error with error object only (no data param on FLog.e)
    FLog.e(
      'Failed to sync user preferences with remote config',
      tag: 'SyncService',
      error: StateError(
          'Remote config returned 409 Conflict — concurrent write detected'),
    );

    // Fatal with a real stack trace
    try {
      _simulateDeepCrash();
    } catch (e, st) {
      FLog.f(
        'Unrecoverable state — payment pipeline corrupted. '
        'Transaction rolled back. Customer support notified.',
        tag: 'PaymentPipeline',
        error: e,
        stackTrace: st,
      );
    }
  }

  void _simulateDeepCrash() {
    _levelOne();
  }

  void _levelOne() => _levelTwo();
  void _levelTwo() => _levelThree();
  void _levelThree() => throw Exception(
        'NullPointerException: paymentIntent was null after 3 retries. '
        'Stripe SDK returned error code: card_declined. '
        'Decline reason: insufficient_funds.',
      );

  Future<void> _runDioRequest() async {
    try {
      await _dio.get<dynamic>('https://jsonplaceholder.typicode.com/todos/1');
    } catch (_) {
      // errors are already logged by FLogDioInterceptor
    }
  }

  Future<void> _runHttpRequest() async {
    try {
      await _httpClient
          .get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
    } catch (_) {
      // errors are already logged by FLogHttpClient
    }
  }

  void _exportLogs() {
    final json = FLog.exportAsJson();
    logI('Exported ${FLog.history.length} log records', tag: 'Export');
    debugPrint(json);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('flutter_log_interceptor demo'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(24),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            const Text(
              'Tap the buttons below and watch your terminal\n'
              'for coloured log output.',
              style: TextStyle(fontSize: 15),
            ),
            const SizedBox(height: 24),
            _DemoButton(
              label: 'Open log overlay',
              onPressed: FLogOverlay.show,
            ),
            const SizedBox(height: 12),
            _DemoButton(
              label: 'Run demo logs (D/I/W/E/F)',
              onPressed: _runDemoLogs,
            ),
            const SizedBox(height: 12),
            _DemoButton(
              label: 'Run long logs (expandable)',
              onPressed: _runLongLogs,
            ),
            const SizedBox(height: 12),
            _DemoButton(
              label: 'Dio GET request',
              onPressed: _runDioRequest,
            ),
            const SizedBox(height: 12),
            _DemoButton(
              label: 'http.Client GET request',
              onPressed: _runHttpRequest,
            ),
            const SizedBox(height: 12),
            _DemoButton(
              label: 'Export logs (print to console)',
              onPressed: _exportLogs,
            ),
            const SizedBox(height: 12),
            _DemoButton(
              label: 'Clear history',
              onPressed: () {
                FLog.clearHistory();
                logI('History cleared', tag: 'Demo');
              },
            ),
            const SizedBox(height: 24),
            ValueListenableBuilder<int>(
              valueListenable: FLog.recordCount,
              builder: (_, __, ___) => Text(
                'History: ${FLog.history.length} records',
                style: const TextStyle(color: Colors.grey),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _DemoButton extends StatelessWidget {
  final String label;
  final VoidCallback onPressed;

  const _DemoButton({required this.label, required this.onPressed});

  @override
  Widget build(BuildContext context) => ElevatedButton(
        onPressed: onPressed,
        child: Text(label),
      );
}
1
likes
130
points
24
downloads

Documentation

API reference

Publisher

verified publishervijayrockers.com

Weekly Downloads

The smart, zero-setup logging layer for Flutter. Beautiful colored logs, HTTP interception, in-app overlay, auto-silent in release — all from one line: FLog.init()

Repository (GitHub)
View/report issues

Topics

#logging #debugging #http #dio #developer-tools

License

MIT (license)

Dependencies

dio, flutter, http

More

Packages that depend on flutter_log_interceptor