observatory 1.0.1 copy "observatory: ^1.0.1" to clipboard
observatory: ^1.0.1 copied to clipboard

Helps Dart applications reach 100% observability coverage. Built for incident investigation and isolate-aware workloads.

observatory #

A Flutter package for incident investigation: isolate-aware Talker logs, Sentry capture, and safe Dio redaction. After Observatory.start, call record and capture from anywhere in the isolate.

Observatory architecture, initialization sequence, error sources, and integrations

Features #

  • Talker logs with isolate prefixes (foreground(main))
  • Sentry capture with stable titles, dedupe, and log breadcrumbs
  • Safe Dio logging with header/body redaction
  • Uncaught errors from runZoned, Flutter, and platform hooks
  • Bloc observer and an in-app log screen

Getting started #

dependencies:
  observatory: ^1.0.1
flutter pub get

Initialize #

The host creates Talker and passes Sentry values in Config. Then start the singleton once per isolate.

final talker = TalkerFlutter.init();

await initPackage(
  config: Config(
    filter: const ObservationFilter.disabled(),
    httpLog: const HttpLogSpec.detailed(),
    sentry: SentrySpec(
      enabled: sentryDsn.isNotEmpty,
      appPackageName: 'mobile',
      dsn: sentryDsn,
      environment: kReleaseMode ? 'production' : 'development',
      release: 'mobile@1.0.0+42',
      dist: '42',
      sampleRate: 1,
      attachScreenshot: true,
      attachLogs: true,
      logsMaxBreadcrumbs: 50,
      logsLevel: LogLevel.warning,
      maxBreadcrumbs: 100,
      dedupeTtl: const Duration(minutes: 2),
      dedupeMaxEntries: 200,
      anrEnabled: true,
      anrTimeoutInterval: const Duration(seconds: 5),
      enableAppHangTracking: true,
      appHangTimeoutInterval: const Duration(seconds: 2),
    ),
  ),
  dependencies: Dependencies(
    talker: talker,
  ),
);

Observatory.start(
  thread: ObservatoryThread.foreground,
  zoneName: 'main',
);

return Observatory.runZoned(() async {
  Observatory.attachTo(dio);
  runApp(
    ObservatoryWidget(
      child: MaterialApp(
        navigatorObservers: Observatory.navigatorObservers,
        home: const HomePage(),
      ),
    ),
  );
});

zoneName is trimmed, empty becomes unspecified, longer than 20 characters is truncated.

Record vs capture #

Call these from any library after start. Do not keep an Observatory instance.

Observatory.record(LogLevel.info, 'Session restored');

try {
  await syncProfile();
} on Object catch (error, stackTrace) {
  await Observatory.capture(
    LogLevel.error,
    'Profile sync failed',
    error: error,
    stackTrace: stackTrace,
  );
  rethrow;
}
  • record writes a Talker line. Use it for expected flow.
  • capture writes the same log, then sends the incident to Sentry when Sentry is enabled.

Do not call both for the same failure. Messages listed in Config.filter are dropped on record only.

Unhandled errors in runZoned, FlutterError.onError, and PlatformDispatcher.instance.onError go to capture.

Observatory record and capture paths, safe Dio redaction, and Sentry enrichment

User, device, HTTP #

await Observatory.bindUser(id: user.id, email: user.email);
await Observatory.bindDevice(
  connectedDeviceId: session.deviceId,
  platformDeviceId: platformId,
);

Observatory.attachTo(dio);

await Observatory.clearUser();
await Observatory.clearDevice();
Navigator.of(context).push(
  MaterialPageRoute<void>(
    builder: (context) => const ObservatoryLogScreen(
      appBarTitle: 'Logs',
    ),
  ),
);

Background isolate #

Each isolate has its own singleton. Call start again in the worker.

Observatory foreground and background isolates, observation model, and in-app log screen

Observatory.start(
  thread: ObservatoryThread.background,
  zoneName: 'downloads',
);

await Observatory.runZoned(() async {
  Observatory.record(LogLevel.info, 'Worker ready');
});

Additional information #

A runnable sample is in example/observatory_example.dart.

1
likes
150
points
249
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Helps Dart applications reach 100% observability coverage. Built for incident investigation and isolate-aware workloads.

Repository (GitHub)
View/report issues

Topics

#observability #logging #diagnostics #isolates #monitoring

License

MIT (license)

Dependencies

dio, domain_error, flutter, flutter_bloc, package_context, sentry_dio, sentry_flutter, talker, talker_bloc_logger, talker_flutter

More

Packages that depend on observatory