fractalup 1.0.0 copy "fractalup: ^1.0.0" to clipboard
fractalup: ^1.0.0 copied to clipboard

Flutter SDK for FractalUp Radar, FractalUp's observability service for frontend, backend, infrastructure, AI agents, and team workflows.

FractalUp Radar #

fractalup is the Flutter SDK for FractalUp Radar, the FractalUp observability service that brings frontend, backend, infrastructure, and AI-agent telemetry into one operational view.

Radar correlates application signals with your team's work in FractalUp. This helps engineering and product teams investigate incidents, coordinate responses, assign ownership and tickets, and follow issues through resolution.

flutter pub add fractalup

1. Install and Initialize #

Configure FractalUp once in main.dart before runApp.

import 'package:flutter/material.dart';
import 'package:fractalup/fractalup.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await FractalUp.init((options) {
    options.ingestionKey = const String.fromEnvironment(
      'FRACTALUP_INGESTION_KEY',
    );
    options.endpoint = Uri.parse(
      const String.fromEnvironment('FRACTALUP_ENDPOINT'),
    );
    options.environment = const String.fromEnvironment('FRACTALUP_ENV');
    options.serviceName = 'my-flutter-app';
    options.autoInstrumentation = true;
    options.firstPartyHosts = {'api.example.com'};
  }, appRunner: () => runApp(const MyApp()));
}

autoInstrumentation enables Flutter and platform error capture, async appRunner zone error capture, lifecycle events, durable queued delivery, and runtime, app, and device context. Pass runApp through appRunner to capture uncaught asynchronous errors from the application zone.

Flutter apps still need one-time wiring for navigation and HTTP clients:

MaterialApp(
  navigatorObservers: [FractalUp.navigatorObserver],
  home: const AppHome(),
);

final api = FractalUp.httpClient();

firstPartyHosts limits distributed trace-header injection to your APIs. requestHeadersProvider is optional. When used, connect it to your existing API client so events can include safe request context. Authorization headers, cookies, API keys, session tokens, secrets, and passwords are redacted before delivery.

2. Configure an Environment #

Create an app/project in FractalUp Radar, then copy its client ingestion key and ingestion URL from the FractalUp platform. Do not use an administrative or server credential in a Flutter application.

Pass the values to any flutter run or flutter build command:

flutter run \
  --dart-define=FRACTALUP_ENDPOINT=your_fractalup_ingestion_url \
  --dart-define=FRACTALUP_INGESTION_KEY=your_client_ingestion_key \
  --dart-define=FRACTALUP_ENV=preview-us

FRACTALUP_ENV is a free-form environment label, not a fixed enum. Common values include dev, stage, and prod, but names such as qa, customer-demo, preview-42, and production-eu are also supported. Create as many ingestion keys and environment labels in FractalUp as your deployment model requires.

Use the same environment label consistently across frontend, backend, infrastructure, and AI-agent telemetry when those signals belong to the same deployment. This allows Radar to correlate them correctly.

Required build-time values:

  • FRACTALUP_ENDPOINT: ingestion URL provided by the FractalUp platform
  • FRACTALUP_INGESTION_KEY: client ingestion key for the app/project

Recommended build-time values:

  • FRACTALUP_ENV: deployment label; defaults to prod when omitted
  • FRACTALUP_SERVICE_NAME: stable service name, such as checkout-flutter
  • FRACTALUP_SOURCE_ID: optional source override from the FractalUp platform
  • FRACTALUP_RELEASE: application version or release identifier
  • FRACTALUP_APP_NAME: human-readable application name

3. Send Manual Events #

await FractalUp.debug('debug.panel.opened', data: {
  'screen': 'settings',
});

await FractalUp.info('profile.opened', data: {
  'screen': 'profile',
});

await FractalUp.warning('network.retry', data: {
  'attempt': 2,
});

await FractalUp.error('payment.failed', data: {
  'provider': 'stripe',
  'status_code': 402,
});

await FractalUp.fatal('checkout.unrecoverable', data: {
  'step': 'payment_confirmation',
});

Use tags for low-cardinality filters:

await FractalUp.error(
  'payment.failed',
  data: {'status_code': 402},
  tags: {'feature': 'checkout'},
);

Use requestHeaders only when overriding the configured provider for one specific failed request:

await FractalUp.error(
  'api.request.failed',
  data: {'status_code': response.statusCode},
  tags: {'feature': 'checkout'},
  requestHeaders: response.request?.headers ?? const {},
);

4. Capture Exceptions #

try {
  await submitPayment();
} catch (error, stackTrace) {
  await FractalUp.captureException(
    error,
    stackTrace: stackTrace,
    data: {'screen': 'checkout'},
    tags: {'feature': 'payments'},
  );
}

With installErrorHooks: true, uncaught Flutter framework and platform dispatcher errors are captured automatically.

5. Fast Migration #

For existing exception/event instrumentation, keep the call shape and use FractalUp names after a mass replacement.

await FractalUp.init((options) {
  options.ingestionKey = const String.fromEnvironment(
    'FRACTALUP_INGESTION_KEY',
  );
  options.endpoint = Uri.parse(
    const String.fromEnvironment('FRACTALUP_ENDPOINT'),
  );
  options.environment = const String.fromEnvironment('FRACTALUP_ENV');
  options.serviceName = 'my-flutter-app';
}, appRunner: () => runApp(const MyApp()));

await FractalUp.configureScope((scope) {
  scope.setTag('feature', 'checkout');
  scope.setExtra('screen', 'checkout');
  scope.setUser(FractalUpUser(id: user.id, email: user.email));
});

await FractalUp.captureException(
  error,
  stackTrace: stackTrace,
);

await FractalUp.captureMessage(
  'Checkout opened',
  level: FractalUpLevel.info,
);

The visible API stays FractalUp while preserving the familiar migration concepts: scope, tags, extras, user, breadcrumbs, exception capture, messages, and levels.

Setup-only exception-monitoring migration #

Existing application instrumentation can keep its call shapes after replacing the previous SDK namespace with FractalUp. Only initialization must be changed to provide the FractalUp ingestion key and service configuration.

The compatibility contract includes:

  • FractalUp.init and common Flutter options
  • FractalUp.captureEvent, captureException, captureMessage, and feedback
  • scope, users, tags, contexts, breadcrumbs, attributes, and attachments
  • FractalUpWidget and FractalUpNavigatorObserver
  • transactions, child spans, callback spans, and trace identifiers
  • structured logger, formatted logger, metrics, and feature flags
  • lifecycle methods, screenshot request API, and app-hang control API
await FractalUp.init((options) {
  options.ingestionKey = const String.fromEnvironment(
    'FRACTALUP_INGESTION_KEY',
  );
  options.endpoint = Uri.parse(
    const String.fromEnvironment('FRACTALUP_ENDPOINT'),
  );
  options.environment = const String.fromEnvironment('FRACTALUP_ENV');
  options.serviceName = 'my-flutter-app';
  options.tracesSampleRate = 0.2;
  options.enableLogs = true;
  options.enableMetrics = true;
}, appRunner: () {
  runApp(const FractalUpWidget(child: MyApp()));
});

This is source compatibility for application-facing Dart and Flutter APIs. Native crash engines, native symbol processing, continuous profiling, real screenshot/view-hierarchy attachments, app-hang/ANR engines, frame tracking, and session replay require dedicated platform implementations and are not silently emulated.

6. Logs, Metrics, Sessions, and Mobile-Agent Style Calls #

Global attributes are attached to future events, logs, metrics, and compatibility-facade calls:

FractalUp.startSession(id: sessionId);
FractalUp.setAttribute('screen', 'checkout');
FractalUp.incrementAttribute('retry_count');

await FractalUp.logger.warn(
  'Payment latency high',
  event: 'checkout.payment.latency',
  attributes: {'duration_ms': 1250},
  tags: {'feature': 'payments'},
);

await FractalUp.metric(
  'checkout.duration',
  category: 'Checkout',
  value: 321,
);

For mobile-agent style migrations, keep the call shape and replace the visible SDK name with FractalUp:

await FractalUpMobile.instance.startAgent(Config(
  accessToken: const String.fromEnvironment('FRACTALUP_INGESTION_KEY'),
  endpoint: Uri.parse(const String.fromEnvironment('FRACTALUP_ENDPOINT')),
  environment: const String.fromEnvironment('FRACTALUP_ENV'),
  serviceName: 'my-flutter-app',
));

await FractalUpMobile.instance.setUserId(user.id);
await FractalUpMobile.instance.setAttribute('cart_value', 99.5);

await FractalUpMobile.instance.recordCustomEvent(
  'Checkout',
  eventName: 'Payment Failed',
  eventAttributes: {'provider': 'stripe'},
);

await FractalUpMobile.instance.recordMetric(
  'checkout.duration',
  'Checkout',
  value: 321,
  valueUnit: MetricUnit.MILLISECONDS,
);

All of these APIs normalize into the same FractalUp ingestion payload with session, trace, service, environment, user, tags, attributes, and safe request context.

The FractalUp.metrics facade aggregates counters, gauges, and distributions locally for ten seconds by default. FractalUp.flush() sends pending metric aggregations and queued events. Use FractalUp.metric(...) when an individual metric event must be sent immediately.

7. Setup-Only Mobile-Agent Migration #

For an existing mobile-agent integration, replace the dependency/imports and agent class once. Existing calls such as recordError, recordCustomEvent, recordMetric, setUserId, attributes, breadcrumbs, interactions, network notices, and logging keep the same method and parameter shapes.

Use these FractalUp imports:

import 'package:fractalup/config.dart';
import 'package:fractalup/fractalup_mobile.dart';
import 'package:fractalup/loglevel.dart';
import 'package:fractalup/metricunit.dart';
import 'package:fractalup/network_failure.dart';

Initialize once:

final config = Config(
  accessToken: const String.fromEnvironment(
    'FRACTALUP_INGESTION_KEY',
  ),
  endpoint: Uri.parse(const String.fromEnvironment('FRACTALUP_ENDPOINT')),
  environment: const String.fromEnvironment('FRACTALUP_ENV'),
  serviceName: 'my-flutter-app',
  crashReportingEnabled: true,
  httpInstrumentationEnabled: true,
  offlineStorageEnabled: true,
  distributedTracingEnabled: true,
);

await FractalUpMobile.instance.start(
  config,
  () => runApp(const MyApp()),
);

After that setup, existing instrumentation keeps its call shape:

FractalUpMobile.instance.recordError(error, stackTrace);

await FractalUpMobile.instance.recordCustomEvent(
  'Checkout',
  eventName: 'Payment Failed',
  eventAttributes: {'provider': 'stripe'},
);

await FractalUpMobile.instance.recordMetric(
  'checkout.duration',
  'Checkout',
  value: 321,
  valueUnit: MetricUnit.MILLISECONDS,
);

Optional compatibility imports are also available for navigation, raw dart:io HTTP clients, global HTTP overrides, trace constants, and version metadata:

import 'package:fractalup/fractalup_navigation_observer.dart';
import 'package:fractalup/fractalup_http_client.dart';
import 'package:fractalup/fractalup_http_overrides.dart';
import 'package:fractalup/fractalup_dt_trace.dart';
import 'package:fractalup/version.dart';

8. RUM Views, Actions, and HTTP Tracking #

Track screens automatically with the navigation observer:

MaterialApp(
  navigatorObservers: [
    FractalUp.navigatorObserver,
  ],
  home: const AppHome(),
);

Track RUM views and user actions manually when needed:

await FractalUp.rum.startView('/checkout', 'Checkout');

await FractalUp.rum.addAction(
  RumActionType.tap,
  'Pay button',
  {'button.id': 'pay'},
);

await FractalUp.rum.stopView('/checkout');

Wrap package:http clients to capture resources and inject W3C trace headers:

final client = FractalUp.httpClient();

final response = await client.get(
  Uri.parse('https://api.example.com/pay'),
);

Each tracked request emits resource start/finish events with method, URL, status code, duration, response size, session id, and trace context. Use FractalUpHttpClient directly only when a specific client needs custom attributes or its own first-party host list.

9. Offline Queue #

Enable persisted queued events when mobile delivery should survive process restarts:

FractalUp.configureFromEnvironment(
  endpoint: const String.fromEnvironment('FRACTALUP_ENDPOINT'),
  serviceName: 'my-flutter-app',
  persistQueuedEvents: true,
  maxPersistedQueuedEvents: 500,
  maxPersistedQueueBytes: 2 * 1024 * 1024,
);

Mobile-agent style setup enables offline storage by default. Set offlineStorageEnabled: false to disable it.

await FractalUpMobile.instance.startAgent(Config(
  accessToken: const String.fromEnvironment('FRACTALUP_INGESTION_KEY'),
  endpoint: Uri.parse(const String.fromEnvironment('FRACTALUP_ENDPOINT')),
  offlineStorageEnabled: true,
));

10. Sampling and Privacy Hooks #

Use sampling to control event volume and beforeSend for final payload filtering:

FractalUp.configureFromEnvironment(
  endpoint: const String.fromEnvironment('FRACTALUP_ENDPOINT'),
  serviceName: 'my-flutter-app',
  sampleRate: 1.0,
  logSampleRate: 0.25,
  rumSampleRate: 0.5,
  networkSampleRate: 0.5,
  beforeSend: (payload) {
    if (payload['event'] == 'debug.noisy_event') {
      return null;
    }

    return payload;
  },
);

URL query values are redacted by default in event attributes, contexts, RUM resources, and persisted queue records.

FractalUp.configureFromEnvironment(
  endpoint: const String.fromEnvironment('FRACTALUP_ENDPOINT'),
  serviceName: 'my-flutter-app',
  redactUrlQueryParameters: true,
);

11. Attach Current User #

After login:

FractalUp.setUser(userId: user.id);

After logout:

FractalUp.clearUser();

Optional customer-side account grouping:

FractalUp.setUser(
  userId: user.id,
  tenantId: account.id,
);

tenantId is observability metadata only. The ingestion key already identifies the FractalUp customer/project on the backend.

12. Production Delivery Controls #

The defaults are designed to protect the host app and control ingestion cost:

  • Error deduplication uses a bounded 30-second window.
  • The client permits 600 total events and 120 error events per minute.
  • Transient failures use up to three attempts with capped exponential jitter.
  • HTTP 429 responses honor Retry-After.
  • Queues, persisted storage, payload depth, collection size, strings, and total payload bytes are bounded.
  • Dropped, deduplicated, and rate-limited totals are attached as client reports.
  • Fatal unhandled errors mark the active session as crashed for crash-free session reporting.

Every limit is configurable through FractalupRadarOptions, FractalUp.configureHosted, FractalUp.configureFromEnvironment, or the matching FractalUpOptions fields.

13. Platform Wiring #

Automatic Flutter/framework errors, platform dispatcher errors, async appRunner zone errors, startup timing, lifecycle, sessions, context, privacy, sampling, queueing, and delivery controls require only initialization.

Flutter does not expose a reliable global hook for every router or every HTTP client. Add these once:

MaterialApp(
  navigatorObservers: [FractalUp.navigatorObserver],
);

final httpClient = FractalUp.httpClient();

Raw dart:io global HTTP overrides are available for compatible VM platforms. Browser requests, custom networking stacks, native crashes, native symbols, continuous profiling, screenshots/view hierarchy, ANR engines, frame tracking, and session replay require platform-specific integration and are not reported as active unless a real implementation is installed.

14. Package Documentation and License #

pub.dev generates the package page and API reference from this repository; no separate documentation website is required.

This package is licensed under the Elastic License 2.0. See LICENSE and NOTICE. Security reports should follow SECURITY.md.

8
likes
155
points
70
downloads

Documentation

API reference

Publisher

verified publisherfractalup.com

Weekly Downloads

Flutter SDK for FractalUp Radar, FractalUp's observability service for frontend, backend, infrastructure, AI agents, and team workflows.

Homepage

Topics

#observability #monitoring #logging #tracing #rum

License

Elastic-2.0 (license)

Dependencies

flutter, http

More

Packages that depend on fractalup