Dart / Flutter Integration
Instrument Flutter apps with one pub.dev package. Frame timing and jank detection, Dart isolate metrics, Dio HTTP tracing, symbolicated crash reports, and navigation spans across iOS, Android, and desktop.
How It Works
Add the pub.dev Package
Add tigerops_flutter: ^0.1.0 to the dependencies section of your pubspec.yaml and run flutter pub get. The package includes OpenTelemetry Dart SDK bindings, a Dio HTTP interceptor, a Flutter error handler, and Dart isolate metric collectors.
Initialize in main()
Wrap your runApp() call inside a TigerOps.runApp() call in main.dart. This installs the Flutter error widget, registers the Dart isolate error handler, sets up the OTLP exporter, and initializes the frame timing collector before the first frame renders.
Configure API Key & App Name
Pass your apiKey, serviceName, and environment to TigerOps.init(). For production apps, store the API key in a Flutter compile-time constant (--dart-define=TIGEROPS_API_KEY=...) rather than in source code. Both Android and iOS are configured identically.
Frame Timing, HTTP & Crash Data
TigerOps immediately begins collecting Flutter frame timings, jank events, Dart isolate memory usage, Dio HTTP request traces, Hive and Isar query spans, ANR detection, crash reports with symbolicated Dart stack traces, and app start latency.
What You Get Out of the Box
Flutter Frame Timing & Jank Detection
TigerOps collects frame build time and raster time for every frame via Flutter's SchedulerBinding. Frames exceeding the 16ms budget (jank) are flagged with the widget tree depth and current route name. Jank rate is tracked as a continuous metric per screen.
Dart Isolate Metrics
Dart isolate heap usage, garbage collection events, and isolate spawn/kill durations are monitored. Worker isolates created via compute() or Isolate.spawn() are individually tracked with their memory footprint and message queue depth.
HTTP Client Tracing with Dio
Register the TigerOps Dio interceptor to trace all HTTP requests. Each request span includes URL, method, response status, DNS resolution time, TLS time, and body size. W3C traceparent headers are injected into outgoing requests for backend correlation.
Crash Reporting & Symbolication
Unhandled Flutter and Dart errors are captured with the full Dart stack trace, Flutter widget tree, device model, OS version, and last 50 breadcrumb events. Dart stack traces are symbolicated using the app's debug symbols uploaded via the TigerOps CLI.
App Start & Navigation Timing
Flutter app cold start time (isolate init to first frame) and warm start time are measured. Navigator 2.0 route changes and GoRouter navigations create spans with source route, target route, and navigation duration for full user flow visibility.
Hive, Isar & SQLite Query Spans
Local database operations via Hive, Isar, or sqflite are traced as child spans with box/collection name, operation type, and execution time. Bulk put/get operations include item count. This helps identify slow local data access on constrained devices.
Install & Initialize
One pub.dev package and one runApp wrapper. Full Flutter observability on all platforms.
# pubspec.yaml
dependencies:
tigerops_flutter: ^0.1.0
dio: ^5.0.0
# Run flutter pub get
flutter pub get
// main.dart
import 'package:flutter/material.dart';
import 'package:tigerops_flutter/tigerops_flutter.dart';
import 'package:dio/dio.dart';
void main() {
TigerOps.runApp(
() => runApp(const MyApp()),
config: TigerOpsConfig(
apiKey: const String.fromEnvironment('TIGEROPS_API_KEY'),
serviceName: 'my-flutter-app',
environment: 'production',
trackFrameTiming: true,
trackNavigation: true,
crashReporting: true,
),
);
}
// Add Dio interceptor for HTTP tracing
final dio = Dio();
dio.interceptors.add(TigerOps.dioInterceptor());
// Custom span in a widget or service
Future<Order> fetchOrder(String orderId) async {
return TigerOps.span('order.fetch', (span) async {
span.setAttribute('order.id', orderId);
final response = await dio.get('/api/orders/$orderId');
span.setAttribute('order.status', response.data['status']);
return Order.fromJson(response.data);
});
}Common Questions
Which Flutter versions and platforms are supported?
Flutter 3.x (Dart 3.x) is fully supported on iOS, Android, macOS, Windows, and Linux. Web support is provided via the browser SDK using the fetch-based OTLP exporter. Flutter for Embedded (Flutter Pi) is compatible with the Linux SDK variant.
How does TigerOps handle Dart null safety?
The tigerops_flutter package is fully null-safe (sound null safety). It requires Dart SDK 3.0+ and Flutter 3.0+. All APIs use non-nullable types where possible and explicit nullable types (String?) where values may be absent, following Dart's effective null safety guidelines.
Does TigerOps collect any personal data from Flutter app users?
No. TigerOps collects only performance telemetry: timing, error messages, device model, and OS version. It does not collect user identifiers, location, or app content by default. You can optionally associate a user ID with spans using span.setUserContext() for session-level debugging.
How do I upload Dart debug symbols for crash symbolication?
Run flutter build apk --obfuscate --split-debug-info=./symbols to generate Dart debug symbols. Then run tigerops-cli upload-symbols --platform android --symbols-dir ./symbols --app-version 1.2.3. A similar process applies for iOS using the .dSYM files from the Xcode archive.
Can I trace isolate communication and message passing?
Yes. Wrap Isolate.spawn() calls with TigerOps.traceIsolate() to propagate trace context to the new isolate. For compute() calls, use TigerOps.traceCompute(). The isolate receives the parent span context and creates child spans that appear in the parent trace timeline.
Full Flutter Observability in One pub.dev Package
Frame timing, isolate metrics, Dio tracing, symbolicated crashes, and navigation spans — across iOS, Android, and desktop.