Skip to content

RUM Configuration

RUM Initialization Configuration

await FTRUMManager().setConfig(
  androidAppId: appAndroidId,
  iOSAppId: appIOSId,
);
Field Type Required Description
androidAppId String Required on Android The app_id for the Android platform, applied for in the RUM console; read only at Android runtime
iOSAppId String Required on iOS The app_id for the iOS platform, applied for in the RUM console; read only at iOS runtime
sampleRate double No Sampling rate, value range [0,1]; 0 means no collection, 1 means full collection. Defaults to 1. Scoped to all View, Action, LongTask, and Error data under the same session_id
sessionOnErrorSampleRate double No Error sampling rate. When a session is not sampled by sampleRate, if an error occurs during the session, data within 1 minute before the error can be collected. Value range [0,1], defaults to 0
enableUserResource bool No Whether to enable automatic collection of Flutter http Resource. Defaults to false. This is implemented by modifying HttpOverrides.global; if the project has custom requirements, you need to inherit FTHttpOverrides
enableNativeUserAction bool No Whether to automatically track native-side Action events, including Android/iOS native control clicks and app launch events. Defaults to false. On Android, ft-plugin must be configured; collecting launch events also requires a custom Application
enableNativeUserView bool No Whether to automatically collect native pages. Android collects Activity, iOS collects UIViewController. Defaults to false
enableNativeSwiftUIUserView bool No iOS: Whether to enable automatic tracking of native SwiftUI Views. enableNativeUserView must also be enabled
enableNativeUserViewInFragment bool No Whether to automatically collect Android Fragment pages. ft-plugin must be configured. Defaults to false. Android only
enableNativeUserResource bool No Whether to enable automatic collection of native network Resource data. Android automatically collects OkHttp requests, iOS automatically collects native network requests. Defaults to false. This parameter and enableUserResource, which collects Flutter HttpClient requests, are two independent capabilities
enableNativeAppUIBlock bool No Whether to enable automatic detection of native main-thread jank (UI Block/Freeze). Defaults to false
nativeUiBlockDurationMS int No Native main-thread jank detection threshold, in milliseconds. Effective only when enableNativeAppUIBlock is enabled. Value range [100, ). iOS defaults to 250 ms, Android defaults to 1000 ms
enableLongTask bool No Whether to enable automatic detection of Long Tasks on the Flutter Dart main isolate. Defaults to false
dartLongTaskThreshold double No Flutter Dart Long Task detection threshold, in seconds. Defaults to 0.1
enableTrackNativeAppANR bool No Whether to enable native ANR monitoring. Defaults to false. ANR detects when the app remains unresponsive, unlike the single main-thread jank collected by enableNativeAppUIBlock; on iOS, unresponsiveness is detected through the main-thread RunLoop
enableTrackNativeCrash bool No Whether to enable native crash monitoring. Defaults to false. Android collects Java Crash and Native C/C++ Crash; iOS collects Crash, and the monitoring type can be configured via iosCrashMonitoringType
errorMonitorType int No Sets auxiliary monitoring information attached to RUM Error data. Supports ErrorMonitorType.battery, memory, cpu, and all; when calling, pass the corresponding .value, e.g., ErrorMonitorType.all.value. Disabled by default
deviceMetricsMonitorType int No Sets performance monitoring information attached to RUM View data. Supports DeviceMetricsMonitorType.battery, memory, cpu, fps, and all; when calling, pass the corresponding .value, e.g., DeviceMetricsMonitorType.all.value. Disabled by default
detectFrequency enum DetectFrequency No View performance monitoring sampling interval: DetectFrequency.normal is 500 ms, frequent is 100 ms, rare is 1000 ms. Defaults to normal. Only meaningful when deviceMetricsMonitorType is configured
globalContext Map No Custom global parameters. For rules on adding, see Conflict Field Notes
rumCacheDiscard enum No Discard policy: FTRUMCacheDiscard.discard discards new data (default), FTRUMCacheDiscard.discardOldest discards old data
rumCacheLimitCount int No Maximum number of RUM entries in the local cache, range [10_000, ). Defaults to 100_000
isInTakeUrl bool Function(String url) No Flutter http Resource URL filtering callback. Returning true filters out and does not collect; returning false collects. For usage, see Custom Data Collection Rules
enableTraceWebView bool No Whether to enable WebView data collection through the native SDK. Supports Android/iOS. Defaults to true
allowWebViewHost List No Configures the list of hosts allowed for WebView data collection. Must be used together with enableTraceWebView. Supports Android/iOS. If not set or null, all hosts are allowed
enableResourceHostIP bool No Whether to collect the host IP of native Resource requests. Defaults to false. Only affects the native network automatic collection of enableNativeUserResource; does not apply to Flutter HttpClient Resources collected by enableUserResource. iOS 13 or later is required
iosCrashMonitoringType enum IOSCrashMonitoringType No iOS crash monitoring type. Effective only on iOS and requires enableTrackNativeCrash to be enabled. Options: machException, signal, cppException, nsException, system, applicationState, all, highCompatibility. Defaults to IOSCrashMonitoringType.highCompatibility

RUM User Data Tracking

Action

Difference between startAction and addAction
  • startAction automatically calculates the Action duration internally. During calculation, it tries to associate with nearby Resource, LongTask, and Error data, and has a 100 ms frequent-trigger protection. It is recommended for user action data.
  • If you need to call frequently, use addAction. Actions reported via addAction do not conflict with startAction and are not associated with the current Resource, LongTask, or Error data.

Usage

/// Add an action
/// [actionName] The action name
/// [actionType] The action type
/// [property] Additional property parameters (optional)
Future<void> startAction(String actionName, String actionType,
  {Map<String, Object?>? property})

/// Add an action at high frequency, without associating with the current Resource, LongTask, or Error events
Future<void> addAction(String actionName, String actionType,
  {Map<String, Object?>? property})

Code Example

FTRUMManager().startAction("action name", "action type");

FTRUMManager().addAction("action name", "action type");

View

Automatic Collection

After adding FTRouteObserver to MaterialApp.navigatorObservers, the SDK can automatically collect Flutter page transitions. The view name (view_name) can be configured in the following ways.

Method 1: Collection via routes

Set the pages to navigate to in MaterialApp.routes; the key in routes is the view name (view_name).

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeRoute(),
      navigatorObservers: [
        FTRouteObserver(),
      ],
      routes: <String, WidgetBuilder>{
        'logging': (BuildContext context) => Logging(),
        'rum': (BuildContext context) => RUM(),
        'tracing_custom': (BuildContext context) => CustomTracing(),
        'tracing_auto': (BuildContext context) => AutoTracing(),
      },
    );
  }
}

Navigator.pushNamed(context, "logging");
Method 2: Collection via FTMaterialPageRoute

By using a custom FTMaterialPageRoute, the view name is parsed from the widget's runtimeType, where the widget class name is the view name (view_name).

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeRoute(),
      navigatorObservers: [
        FTRouteObserver(),
      ],
    );
  }
}

Navigator.of(context).push(
  FTMaterialPageRoute(builder: (context) => new NoRouteNamePage()),
);

For an example, see here.

Method 3: Collection via RouteSettings.name

Customize RouteSettings.name on Route-type pages, and FTRouteObserver prioritizes this value. This method also applies to Dialog-type pages, such as showDialog(), showTimePicker(), and so on.

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeRoute(),
      navigatorObservers: [
        FTRouteObserver(),
      ],
    );
  }
}

Navigator.of(context).push(
  MaterialPageRoute(
    builder: (context) => new NoRouteNamePage(),
    settings: RouteSettings(name: "RouteSettingName"),
  ),
);

The above three methods can be mixed and used in one project.

Sleep and Wake Event Collection

For versions earlier than 0.5.1-pre.1, if you need to collect app sleep and wake behavior, add the following code:

class _HomeState extends State<HomeRoute> {
  @override
  void initState() {
    FTLifeRecycleHandler().initObserver();
  }

  @override
  void dispose() {
    FTLifeRecycleHandler().removeObserver();
  }
}

For automatic collection filtering rules, see Custom Data Collection Rules.

Custom View

Usage
/// Create a view, this method must be called before [starView]
/// [viewName] The view name
/// [duration] The page load duration
Future<void> createView(String viewName, int duration)

/// Start a view
/// [viewName] The view name
/// [viewReferer] The previous view name
/// [property] Additional property parameters (optional)
Future<void> starView(String viewName, {Map<String, String>? property})

/// Stop a view
/// [property] Additional property parameters (optional)
Future<void> stopView({Map<String, String>? property})
Code Example
FTRUMManager().createView("Current Page Name", 100000000);

FTRUMManager().starView("Current Page Name");

FTRUMManager().stopView();

For rules on automatic view collection, route filtering, and sleep/wake monitoring, see Custom Data Collection Rules.

Error

Automatic Collection

void main() async {
  runZonedGuarded(() async {
    WidgetsFlutterBinding.ensureInitialized();
    await FTMobileFlutter.sdkConfig(
      datakitUrl: serverUrl,
      debug: true,
    );
    await FTRUMManager().setConfig(
      androidAppId: appAndroidId,
      iOSAppId: appIOSId,
    );

    // Flutter exception capture
    FlutterError.onError = FTRUMManager().addFlutterError;
    runApp(MyApp());
  }, (Object error, StackTrace stack) {
    // Add Error data
    FTRUMManager().addError(error, stack);
  });
}

Custom Error

Usage
/// Add a custom error
/// [stack] The stack trace
/// [message] The error message
/// [appState] The app state
/// [errorType] Custom errorType
/// [property] Additional property parameters (optional)
Future<void> addCustomError(String stack, String message,
  {Map<String, String>? property, String? errorType})
Code Example
FTRUMManager().addCustomError("error stack", "error message");

LongTask

Automatic Collection

After enabling enableLongTask via FTRUMManager().setConfig, the SDK detects whether blocking tasks exceeding the threshold occur on the Flutter Dart main isolate and generates LongTask data. The default threshold is 0.1 seconds and can be adjusted via dartLongTaskThreshold.

await FTRUMManager().setConfig(
  androidAppId: appAndroidId,
  iOSAppId: appIOSId,
  enableLongTask: true,
  dartLongTaskThreshold: 0.1,
);

Custom LongTask

Usage
/// Report a LongTask; duration is in nanoseconds
Future<void> addLongTask(String stack, int duration,
  {Map<String, String>? property})
Code Example
FTRUMManager().addLongTask(
  "flutter_manual_long_task",
  250000000,
  property: {"long_task_source": "manual_report"},
);

Automatically detected LongTasks identify event loop delays on the Dart main isolate. The collected value is the blocking duration, and it does not necessarily mean that the business code stack causing the blocking can be obtained.

Resource

Automatic Collection

This is implemented by enabling enableUserResource via FTRUMManager().setConfig.

Custom Resource

Usage
/// Start a resource request
/// [key] The unique id
/// [property] Additional property parameters (optional)
Future<void> startResource(String key, {Map<String, String>? property})

/// Stop a resource request
/// [key] The unique id
/// [property] Additional property parameters (optional)
Future<void> stopResource(String key, {Map<String, String>? property})

/// Send resource data metrics
Future<void> addResource({
  required String key,
  required String url,
  required String httpMethod,
  required Map<String, dynamic> requestHeader,
  Map<String, dynamic>? responseHeader,
  String? responseBody = "",
  int? resourceStatus,
  int? resourceSize,
  String? resourceType,
  FTRUMResourceMetrics? metrics,
})
Field Type Description
resourceSize int Response body size, in bytes
resourceType String Resource type, e.g., native, image, media, font, css, js
metrics.requestSize num Request size, including request headers and body, in bytes
metrics.resourceHttpProtocol String The HTTP protocol used by the Resource, e.g., http/1.1
metrics.reusedConnection bool Whether the connection is reused

When enableUserResource automatic collection is enabled, the SDK automatically populates fields such as resourceType, requestSize, resourceHttpProtocol, and reusedConnection based on the request method, response headers, and connection status.

Code Example
void httpClientGetHttp(String url) async {
  var httpClient = HttpClient();
  String key = Uuid().v4();
  HttpClientResponse? response;
  HttpClientRequest? request;
  try {
    request = await httpClient
        .getUrl(Uri.parse(url))
        .timeout(Duration(seconds: 10));
    FTRUMManager().startResource(key);
    response = await request.close();
  } finally {
    Map<String, dynamic> requestHeader = {};
    Map<String, dynamic> responseHeader = {};

    request!.headers.forEach((name, values) {
      requestHeader[name] = values;
    });
    var responseBody = "";
    if (response != null) {
      response.headers.forEach((name, values) {
        responseHeader[name] = values;
      });
      responseBody = await response.transform(Utf8Decoder()).join();
    }
    FTRUMManager().stopResource(key);
    FTRUMManager().addResource(
      key: key,
      url: request.uri.toString(),
      requestHeader: requestHeader,
      httpMethod: request.method,
      responseHeader: responseHeader,
      resourceStatus: response?.statusCode,
      responseBody: responseBody,
    );
  }
}

For usage with the http and dio libraries, see example.

Feedback

Is this page helpful?