Pain-Point SEO

Real-time logging for Flutter apps without a backend

March 18, 2025 BunnyLogs Team

When a Flutter app misbehaves in production you have limited options. Crash reporting tools capture unhandled exceptions, but they miss the flow leading up to the crash — the API call that returned an unexpected payload, the auth state that went wrong, the navigation sequence that never completed.

The bunnylogs_flutter package gives every Flutter app a live log stream: a URL you can open on any device and watch log lines appear in real time as the app runs, from any platform, with no backend to set up.

Installation

flutter pub add bunnylogs_flutter

Or add it manually to pubspec.yaml:

dependencies:
  bunnylogs_flutter: ^0.1.0

Basic usage

Create a log stream at bunnylogs.com and copy the UUID. Then:

import 'package:bunnylogs_flutter/bunnylogs_flutter.dart';

final logger = BunnyLogger(uuid: 'your-uuid-here');

logger.info('User signed in: $userId');
logger.warning('Cache miss — fetching from network');
logger.error('Payment failed: $error');

Open bunnylogs.com/live/your-uuid in a browser and you'll see each call appear as a timestamped, colour-coded log line.

Integrating with the logger package

If you already use the popular logger package, use BunnyLogsOutput as a LogOutput alongside ConsoleOutput to keep terminal output while also shipping to BunnyLogs:

import 'package:flutter/foundation.dart';
import 'package:logger/logger.dart';
import 'package:bunnylogs_flutter/bunnylogs_flutter.dart';

final log = Logger(
  filter: kDebugMode ? DevelopmentFilter() : ProductionFilter(),
  output: MultiOutput([
    ConsoleOutput(),
    BunnyLogsOutput(uuid: 'your-uuid-here'),
  ]),
  printer: SimplePrinter(printTime: false),
);

log.i('Server connected');
log.w('Slow network response: ${ms}ms');
log.e('Checkout error', error: e, stackTrace: s);

ProductionFilter suppresses trace and debug messages in release builds, so you won't ship noisy debug output to production.

Per-feature loggers

Create separate logger instances per feature area so the program field in each log entry identifies the source:

final networkLog = BunnyLogger(uuid: 'your-uuid', program: 'flutter/network');
final authLog    = BunnyLogger(uuid: 'your-uuid', program: 'flutter/auth');
final cartLog    = BunnyLogger(uuid: 'your-uuid', program: 'flutter/cart');

The live view lets you filter by program, so you can watch only the auth subsystem during a login debugging session.

Production settings

In production you probably want to ship warnings and errors but not verbose debug output:

final logger = BunnyLogger(
  uuid: 'your-uuid',
  minLevel: BunnyLevel.warning,
  enabled: !kDebugMode,
);

Store the UUID in a --dart-define build variable rather than hardcoding it:

# Build command
flutter build apk --dart-define=BUNNY_UUID=your-uuid

# Access in code
const uuid = String.fromEnvironment('BUNNY_UUID');
final logger = BunnyLogger(uuid: uuid, enabled: uuid.isNotEmpty);

No backend required

All HTTP calls are fire-and-forget — they never block the UI thread. The http package works on Android, iOS, macOS, Linux, Windows, and web with no extra configuration. For Flutter Web, BunnyLogs serves a permissive CORS policy on /live/<uuid> so browser POSTs work out of the box.

Start streaming Flutter logs →


Related posts