scout_flutter 0.1.6 copy "scout_flutter: ^0.1.6" to clipboard
scout_flutter: ^0.1.6 copied to clipboard

Zero-config OpenTelemetry RUM for Flutter. Auto-captures taps, navigation, errors, lifecycle, crashes, performance metrics, network requests, and structured logs.

Scout Flutter #

Zero-config OpenTelemetry RUM (Real User Monitoring) for Flutter. Install the package, call initialize() — that's it.

Quick Start #

1. Add dependency #

dependencies:
  scout_flutter:
    git:
      url: https://github.com/base-14/scout-flutter.git
      ref: v0.1.6

2. Initialize in main() #

import 'package:scout_flutter/scout_flutter.dart';

Future<void> main() async {
  await ScoutFlutter.initialize(
    config: ScoutFlutterConfig(
      serviceName: 'my-app',
      endpoint: 'https://your-otel-endpoint:4318',
    ),
  );
  runApp(const MyApp());
}

3. (Optional) Add navigation tracking #

MaterialApp(
  navigatorObservers: [ScoutFlutter.navigatorObserver],
  // ...
)

That's it. Everything else is automatic.

What's Captured #

Auto-captured (zero code changes) #

Signal Span/Metric Details
Taps user_interaction Buttons, GestureDetectors, InkWells, Switches, Tabs
Lifecycle app_paused, app_resumed Background/foreground transitions
Errors error.count metric FlutterError + uncaught async exceptions
Device info Resource attributes Model, manufacturer, battery level, connectivity
App startup app_startup Cold start and warm start duration
Long tasks long_task Main isolate jank detection (configurable threshold)
ANR anr Native watchdog thread detects unresponsive main thread
Frame metrics flutter.frame.build_time, flutter.frame.raster_time Per-frame build and raster histograms
Frozen frames frozen_frame Frames exceeding 700ms
Memory flutter.memory.usage Periodic native memory gauge
CPU flutter.cpu.usage Periodic CPU usage percentage gauge
Crash detection app_crash Detects OOM/SIGKILL/exit crashes via session marker
Native crashes native_crash JVM exceptions, NDK signals (SIGSEGV, SIGABRT, etc.) with full stack trace, registers, memory map

With navigator observer #

Signal Span Details
Screen views screen_view Auto-named from route settings or widget type
Screen load time screen_load Time from push to first frame rendered
View sessions view_session Time spent on each screen

With network tracking (enabled by default) #

Signal Span Details
HTTP requests http.request Method, URL, status, duration, response size
Distributed tracing W3C traceparent Injected for first-party hosts

Structured logging #

Signal Export Details
Logs OTLP logs Debug, info, warning, error severity levels
Print capture OTLP logs Optional debugPrint() capture as info-level logs

Crash Detection #

Scout detects three categories of crashes:

Session marker crashes (app_crash span) — Detects OOM kills, exit() calls, and SIGKILL by persisting a session marker file. If the app was in the foreground and never paused before terminating, the next launch emits a crash span with the previous session's breadcrumbs.

JVM/NSException crashes (native_crash span) — Catches uncaught JVM exceptions on Android and NSExceptions on iOS. Written to disk before the process dies and reported on next launch.

Native signal crashes (native_crash span) — Catches SIGSEGV, SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGTRAP on Android via a C signal handler. Captures:

  • Full stack trace via frame pointer walk (not just signal handler frames)
  • Register dump (PC, LR, SP, FP + general purpose registers)
  • Signal code name (e.g. SEGV_MAPERR)
  • Process/thread IDs and thread name
  • Memory map (/proc/self/maps) for offline symbolication
  • ABI, build fingerprint, kernel version, process uptime

Breadcrumb persistence — Breadcrumbs are written to disk on every record, so they survive crashes. Both app_crash and native_crash spans include the full breadcrumb trail from the crashed session.

SDK Crash Safety #

The SDK is designed to never crash your app. Every telemetry callback, error handler, and export path is wrapped in try/catch. If any telemetry operation fails, it silently degrades — your app continues running normally.

Custom Events #

// Log a business event
ScoutFlutter.logEvent('purchase', attributes: {'item': 'widget'});

// Add breadcrumb for error context
ScoutFlutter.addBreadcrumb('checkout', 'added item to cart');

// Report error manually
ScoutFlutter.reportError(error, stackTrace);

// Set user identity (attached to all subsequent spans)
ScoutFlutter.setUser(id: 'user-123', email: 'user@example.com');

Structured Logging #

ScoutFlutter.logDebug('Cache hit for product list');
ScoutFlutter.logInfo('User completed checkout');
ScoutFlutter.logWarning('Retry attempt 2 for API call');
ScoutFlutter.logError('Payment gateway timeout');

Dio Support #

For apps using Dio instead of dart:io HttpClient:

final dio = Dio();
dio.interceptors.add(ScoutFlutter.dioInterceptor);

Annotate Widgets #

For custom tap labels on widgets the SDK can't auto-label:

RumUserActionAnnotation(
  description: 'Add to cart',
  child: MyCustomWidget(),
)

Event Filtering #

Drop or modify events before export:

ScoutFlutterConfig(
  serviceName: 'my-app',
  endpoint: 'https://...',
  beforeSend: (event) {
    // Drop health check requests
    if (event['http.url']?.toString().contains('/health') == true) {
      return null;
    }
    // Scrub PII
    event.remove('enduser.email');
    return event;
  },
)

Sampling #

By default Scout samples 1% of sessions to keep telemetry volume low at scale. Sampling decisions are made per session — when a session is sampled, every span in it is recorded; otherwise the whole session is dropped (so traces stay coherent).

Errors and crashes bypass the session sample rate by default — error, native_crash, app_crash, anr, and ui_hang spans are always exported regardless of whether the session was sampled. Set alwaysCaptureErrors: false to make error-class spans respect the same gate.

Adjust the rate with sessionSampleRate (0.0–100.0). Sampling is enforced at the OpenTelemetry layer, so it also applies to spans emitted by auto-instrumentation and direct tracer.startSpan calls.

Configuration #

ScoutFlutterConfig(
  // Required
  serviceName: 'my-app',
  endpoint: 'https://your-otel-endpoint:4318',

  // App identity
  serviceVersion: '1.0.0',
  environment: 'production',
  secure: true,                          // HTTPS (default: true)
  headers: {'Authorization': 'Bearer ...'}, // OTLP export headers

  // Auto-instrumentation (all default to true)
  enableAutoTapTracking: true,
  enableErrorTracking: true,
  enableLifecycleTracking: true,
  enableStartupTracking: true,
  enableConnectivityTracking: true,
  enablePerformanceMetrics: true,        // FPS, memory, CPU, frame times
  enableLongTaskDetection: true,
  enableAnrDetection: true,
  enableNetworkTracking: true,           // HTTP request tracking
  enableLogging: true,                   // Structured log export

  // Thresholds
  longTaskThresholdMs: 100,              // Min 20ms
  anrThresholdMs: 5000,                  // Min 1000ms

  // Sessions
  sessionSampleRate: 1.0,               // 0.0-100.0 (default: 1.0 = 1% of sessions)
  alwaysCaptureErrors: true,            // Errors/crashes bypass sampleRate (default: true)
  sessionTimeoutMinutes: 30,            // Rotate after inactivity

  // Network
  firstPartyHosts: ['api.example.com'], // Receive traceparent headers
  ignoreUrlPatterns: [RegExp(r'/health')],

  // Logging
  capturePrintStatements: false,        // Capture debugPrint() as logs

  // Storage
  maxOfflineStorageMb: 5,              // Offline queue cap

  // Filtering
  beforeSend: (event) => event,        // Modify/drop events

  // Custom
  resourceAttributes: {'deployment.region': 'us-east-1'},
  customGestureDetector: (widget) => null,

  // Diagnostics
  debugLogging: false,                  // Verbose [scout] logs to debugPrint
)

Debug Logging #

Set debugLogging: true to print a [scout] line for every init, session rotation, sampling decision, export batch, and log entry. Useful while integrating; noisy in production.

[scout] init ok (service=my-app endpoint=http://localhost:4318 v=1.0.0 sampleRate=1.0 alwaysCaptureErrors=true)
[scout] session a1b2c3 sampled=true
[scout] span screen_view → recordAndSample
[scout] span http.request → drop
[scout] export batch: 8 spans (212ms) ok
[scout] log [warn] Retry attempt 2

Architecture #

Scout Flutter exports telemetry via OpenTelemetry Protocol (OTLP) over HTTP:

  • Traces — Spans for user interactions, navigation, crashes, HTTP requests
  • Metrics — Histograms and gauges for frame times, memory, CPU
  • Logs — Structured log records with severity levels

Data flows through a beforeSend filter, then to the OTLP collector. Failed exports are queued offline and retried when connectivity returns.

Platform Support #

Platform Taps Lifecycle Errors Navigation Crashes ANR Native Vitals
Android Yes Yes Yes Yes Yes Yes Yes
iOS Yes Yes Yes Yes Partial Yes Yes

iOS crash detection covers session marker crashes and NSExceptions. Native signal handling (SIGSEGV etc.) is Android-only currently.

License #

MIT

1
likes
120
points
0
downloads

Documentation

API reference

Publisher

verified publisherbase14.io

Weekly Downloads

Zero-config OpenTelemetry RUM for Flutter. Auto-captures taps, navigation, errors, lifecycle, crashes, performance metrics, network requests, and structured logs.

Homepage
Repository (GitHub)
View/report issues

Topics

#opentelemetry #observability #rum #monitoring #telemetry

License

MIT (license)

Dependencies

battery_plus, connectivity_plus, dartastic_opentelemetry, device_info_plus, dio, fixnum, flutter, flutterrific_opentelemetry, http, meta, path_provider

More

Packages that depend on scout_flutter

Packages that implement scout_flutter