After completing the Flutter Monitoring Setup, use this guide to configure additional agent capabilities. Each section is independent and can be enabled as needed.
Control the Sampling Rate
To manage the volume of data sent to Atatus, set a session sampling rate. The value is a percentage between 0.0 and 100.0. For example, the following configuration retains 80% of sessions:
final configuration = AtatusConfiguration(
licenseKey: '<LICENSE_KEY>',
env: '<ENV_NAME>',
appNmae: 'release',
rumConfiguration: AtatusRumConfiguration(
sessionSamplingRate: 80.0,
),
);
Manual Initialization and Error Tracking
By default, the SDK is initialized using the AtatusSdk.runApp wrapper which wraps the Flutter runApp execution. Alternatively, you can initialize the SDK manually. This is useful if you need to run custom asynchronous initialization logic before starting the SDK, or if you want to set up custom error boundaries.
To initialize Atatus manually:
- Call
WidgetsFlutterBinding.ensureInitialized()first. - Initialize the SDK using
AtatusSdk.instance.initialize(...). - Capture unhandled Flutter framework errors using
FlutterError.onError. - Capture asynchronous platform errors using
PlatformDispatcher.instance.onError.
import 'dart:ui';
import 'package:atatus_flutter_plugin/atatus_flutter_plugin.dart';
import 'package:flutter/material.dart';
void main() async {
// 1. Ensure Flutter bindings are initialized
WidgetsFlutterBinding.ensureInitialized();
final configuration = AtatusConfiguration(
licenseKey: '<LICENSE_KEY>',
env: '<ENV_NAME>',
appName: 'release',
nativeCrashReportEnabled: true,
rumConfiguration: AtatusRumConfiguration(),
);
// 2. Initialize the Atatus SDK manually
await AtatusSdk.instance.initialize(configuration, TrackingConsent.granted);
// 3. Capture Flutter framework errors
FlutterError.onError = (FlutterErrorDetails details) {
FlutterError.presentError(details);
AtatusSdk.instance.rum?.handleFlutterError(details);
};
// 4. Capture asynchronous platform-level errors
PlatformDispatcher.instance.onError = (Object error, StackTrace stackTrace) {
AtatusSdk.instance.rum?.addErrorInfo(
error.toString(),
RumErrorSource.source,
stackTrace: stackTrace,
);
return false; // Return false to allow the default platform handler to run
};
runApp(const MyApp());
}
Customizing Route and View Names
To customize screen names as they appear in the RUM dashboard, or to assign custom attributes to specific routes, use a custom ViewInfoExtractor callback. This is especially helpful if routes use obfuscated class names or dynamic parameters that you wish to standardize.
Using ViewInfoExtractor
Define a route extractor function that inspects the dynamic route and returns a customized RumViewInfo object. You can fall back to the default behavior using defaultViewInfoExtractor(route) for other routes:
import 'package:atatus_flutter_plugin/atatus_flutter_plugin.dart';
import 'package:flutter/material.dart';
RumViewInfo? customViewInfoExtractor(Route<dynamic> route) {
final name = route.settings.name;
if (name == '/product_detail') {
return RumViewInfo(
name: 'Product Details Screen',
attributes: {
'page_type': 'e-commerce',
},
);
}
// Fall back to default name extraction for other routes
return defaultViewInfoExtractor(route);
}
// Pass the extractor to AtatusNavigationObserver
final observer = AtatusNavigationObserver(
atatusSdk: AtatusSdk.instance,
viewInfoExtractor: customViewInfoExtractor,
);
Overriding View Info with RouteAware Mixins
For widgets that implement the standard Flutter RouteAware observer lifecycle, you can mix in the AtatusRouteAwareMixin on the widget's State to override the reported name directly inside the view code:
import 'package:atatus_flutter_plugin/atatus_flutter_plugin.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> with RouteAware, AtatusRouteAwareMixin {
// Override rumViewInfo to specify a custom name and extra attributes
@override
RumViewInfo get rumViewInfo => RumViewInfo(
name: 'Home Dashboard Screen',
attributes: {'source': 'main_nav'},
);
@override
Widget build(BuildContext context) {
return const Scaffold(
body: Center(child: Text('Home')),
);
}
}
Custom Action Labels
For custom widgets where the RumUserActionDetector cannot infer a meaningful label, annotate the widget with a description using RumUserActionAnnotation. This ensures the action appears with a human-readable name in the Atatus dashboard:
RumUserActionAnnotation(
description: 'Favorite button',
child: InkWell(
onTap: onTap,
child: const Icon(Icons.favorite),
),
);
Manually Track User Actions
The RumUserActionDetector widget captures common tap interactions automatically. For interactions it cannot detect — such as programmatic triggers, long presses, or scroll events — use manual action tracking.
Instantaneous Actions
For discrete actions (taps, clicks), use addAction:
void _onDownloadTapped(String resourceName) {
AtatusSdk.instance.rum?.addAction(
RumActionType.tap,
resourceName,
);
}
Continuous Actions
For time-bound actions (scrolls, swipes), use startAction and stopAction:
void _onScrollStart() {
AtatusSdk.instance.rum?.startAction(
RumActionType.scroll,
'Product List Scroll',
);
}
void _onScrollEnd() {
AtatusSdk.instance.rum?.stopAction(
RumActionType.scroll,
'Product List Scroll',
);
}
startAction and stopAction, the type parameter must be the same in both calls for the SDK to match the start and end of the action.
Manually Track Custom Resources
In addition to the automatic resource tracking provided by the Dio interceptor and the Atatus Tracking HTTP Client, you can manually track network requests or third-party API calls that are not covered by automatic instrumentation.
// Start tracking a resource
AtatusSdk.instance.rum?.startResource(
'resource-key',
RumHttpMethod.get,
'https://api.example.com/data',
);
// On successful completion
AtatusSdk.instance.rum?.stopResource(
'resource-key',
200,
RumResourceType.fetch,
);
If the resource request fails, report the error using stopResourceWithError:
AtatusSdk.instance.rum?.stopResourceWithError(
'resource-key',
'Connection timed out',
'network',
);
resourceKey string must be unique for each resource and must be the same in the startResource and corresponding stopResource or stopResourceWithError calls.
Custom Performance Timings
Measure custom performance milestones within a view using addTiming. The timing is recorded relative to the start of the current RUM view, making it ideal for tracking content render times, hero image loads, or any application-specific milestone.
void _onHeroImageLoaded() {
AtatusSdk.instance.rum?.addTiming('hero_image');
}
void _onContentRendered() {
AtatusSdk.instance.rum?.addTiming('content_rendered');
}
After the timing is set, it is accessible as @view.custom_timings.<timing_name> (for example, @view.custom_timings.hero_image). Use these values to create custom measures and visualizations in the Atatus dashboard.
Modify or Drop RUM Events
To modify the attributes of a RUM event before it is sent to Atatus, or to drop an event entirely, use Event Mappers during SDK configuration. Each mapper is a function with the signature (T) → T? where T is a concrete RUM event type. Returning null from a mapper drops the event.
final configuration = AtatusConfiguration(
licenseKey: '<LICENSE_KEY>',
env: '<ENV_NAME>',
appName: 'release',
rumConfiguration: AtatusRumConfiguration(
rumViewEventMapper: (event) => event,
rumActionEventMapper: (event) => event,
rumResourceEventMapper: (event) {
// Redact sensitive URL segments before sending
event.resource.url = redactUrl(event.resource.url);
return event;
},
rumErrorEventMapper: (event) => event,
rumLongTaskEventMapper: (event) => event,
),
);
null. Returning null from the error, resource, or action mappers drops the event entirely — it is not sent to Atatus.
The following event properties can be modified:
| Event Type | Modifiable Properties |
|---|---|
| View | view.url, view.referrer |
| Action | action.target.name, view.referrer, view.url |
| Error | error.message, error.stack, error.resource.url, view.referrer, view.url |
| Resource | resource.url, view.referrer, view.url |
Retrieve the RUM Session ID
Retrieving the current RUM session ID is helpful for troubleshooting. You can attach it to support tickets, bug reports, or internal logs to correlate user-reported issues with the corresponding session in the Atatus dashboard.
final sessionId = await AtatusSdk.instance.rum?.getCurrentSessionId();
Clear All Data
Use clearAllData to wipe all locally queued data that has not yet been transmitted to Atatus. This is useful for implementing user data deletion requests or clearing state after a user logs out.
AtatusSdk.instance.clearAllData();
Flutter-Specific Performance Metrics
To enable the collection of Flutter-specific rendering metrics — widget build times and raster (frame render) times — set reportFlutterPerformance to true on AtatusRumConfiguration. These metrics are displayed in the Mobile Vitals section of the Atatus dashboard.
final configuration = AtatusConfiguration(
licenseKey: '<LICENSE_KEY>',
env: '<ENV_NAME>',
appName: 'release',
rumConfiguration: AtatusRumConfiguration(
reportFlutterPerformance: true,
),
);
Log Correlation
The Atatus SDK supports sending structured log messages from your Flutter application and correlating them with RUM sessions. When log correlation is enabled, each log entry is automatically linked to the active RUM view and session, providing full context during incident investigation.
For detailed setup instructions, see Flutter Log Collection.
Set Tracking Consent (GDPR)
To comply with GDPR and similar data protection regulations, the SDK requires a tracking consent value at initialization. Three values are available:
TrackingConsent.pending— the SDK collects and batches data locally but does not transmit it until consent is updated.TrackingConsent.granted— the SDK collects data and transmits it to Atatus.TrackingConsent.notGranted— the SDK does not collect any data.
Update the consent value at any time after initialization:
AtatusSdk.instance.setTrackingConsent(TrackingConsent.granted);
Sending Data When the Device Is Offline
RUM data is batched and stored locally on the device when no network connection is available. The SDK uploads all stored data automatically once connectivity is restored. No additional configuration is required. This ensures complete data capture regardless of network conditions.
+1-415-800-4104