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

Isolate-aware Flutter logs, bounded history, safe HTTP logging and Sentry incident capture.

example/observatory_example.dart

import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:observatory/observatory.dart';

Future<void> main() async {
  return Observatory.run<void>(
    zoneName: 'main',
    config: Config(
      filter: ObservationFilter(
        enabled: true,
        excludedLogs: const ['Heartbeat tick'],
        excludedHttpUrls: [RegExp(r'/health$')],
        excludedBlocTypes: const ['HydratedBloc'],
      ),
      httpLog: const HttpLogSpec.detailed(),
      sentry: SentrySpec(
        enabled: const String.fromEnvironment('SENTRY_DSN').isNotEmpty,
        appPackageName: 'observatory_example',
        dsn: const String.fromEnvironment('SENTRY_DSN'),
        environment: kReleaseMode ? 'production' : 'development',
        release: 'observatory_example@0.1.0+1',
        dist: '1',
        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),
      ),
    ),
    body: () async {
      await Observatory.bindUser(id: 'user-42', email: 'qa@example.com');
      await Observatory.bindDevice(connectedDeviceId: 'device-7', platformDeviceId: 'pixel-8');

      final dio = Dio(BaseOptions(baseUrl: 'https://api.example.com'));
      Observatory.attachTo(dio);

      runApp(ExampleApp(dio: dio));
    },
  );
}

class ExampleApp extends StatelessWidget {
  final Dio dio;

  const ExampleApp({required this.dio, super.key});

  @override
  Widget build(BuildContext context) {
    return ObservatoryWidget(
      child: MaterialApp(
        navigatorObservers: Observatory.navigatorObservers,
        home: ExampleHome(dio: dio),
      ),
    );
  }
}

class ExampleHome extends StatelessWidget {
  final Dio dio;

  const ExampleHome({required this.dio, super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Observatory example'),
        actions: [
          IconButton(
            onPressed: () {
              Navigator.of(context)
                  .push(MaterialPageRoute<void>(builder: (context) => const ObservatoryLogScreen(appBarTitle: 'Logs')));
            },
            icon: const Icon(Icons.bug_report_outlined),
          ),
        ],
      ),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          FilledButton(
            onPressed: () {
              Observatory.record(LogLevel.info, 'Home opened');
            },
            child: const Text('Record info'),
          ),
          const SizedBox(height: 8),
          FilledButton(onPressed: _syncProfile, child: const Text('Catch and capture')),
          const SizedBox(height: 8),
          FilledButton(onPressed: _pingBackend, child: const Text('HTTP with capture')),
        ],
      ),
    );
  }

  Future<void> _syncProfile() async {
    try {
      throw const FormatException('invalid profile payload');
    } on Object catch (error, stackTrace) {
      await Observatory.capture(LogLevel.error, 'Profile sync failed', error: error, stackTrace: stackTrace);
    }
  }

  Future<void> _pingBackend() async {
    try {
      await dio.get<void>('/v1/profile');
    } on Object catch (error, stackTrace) {
      await Observatory.capture(LogLevel.error, 'Profile request failed', error: error, stackTrace: stackTrace);
    }
  }
}
1
likes
140
points
115
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Isolate-aware Flutter logs, bounded history, safe HTTP logging and Sentry incident capture.

Repository (GitHub)
View/report issues

Topics

#observability #logging #diagnostics #isolates #monitoring

License

MIT (license)

Dependencies

bloc_effects, dio, domain_error, flutter, flutter_bloc, launch_mode, package_context, sentry_dio, sentry_flutter, talker, talker_bloc_effects, talker_flutter

More

Packages that depend on observatory