RUM Configuration¶
RUM Initialization Configuration¶
| Field | Type | Required | Description |
|---|---|---|---|
| androidAppId | String | Yes | Android platform app_id, applied for in the RUM console |
| iOSAppId | String | Yes | iOS platform app_id, applied for in the RUM console |
| sampleRate | double | No | Sampling rate, value range [0,1], 0 means no collection, 1 means full collection, default is 1. Scope is all View, Action, LongTask, Error data under the same session_id |
| sessionOnErrorSampleRate | double | No | Error collection rate. When a session is not sampled by sampleRate, if an error occurs during the session, data from the 1 minute before the error can be collected. Value range [0,1], default is 0 |
| enableUserResource | bool | No | Whether to enable automatic Flutter http Resource capture, default false. Implemented by modifying HttpOverrides.global. If the project has customization needs, inherit FTHttpOverrides |
| enableNativeUserAction | bool | No | Whether to perform Native Action tracking, default false |
| enableNativeUserView | bool | No | Whether to perform automatic Native View tracking. Recommended to turn off for pure Flutter applications, default false |
| enableNativeUserViewInFragment | bool | No | Whether to automatically track Native Fragment type page data, default false, only supports Android |
| enableNativeUserResource | bool | No | Whether to perform automatic Native Resource tracking. Recommended to turn off for pure Flutter applications, default false |
| enableAppUIBlock | bool | No | Whether to perform automatic Native Freeze tracking, default false |
| nativeUiBlockDurationMS | int | No | Sets the time range for Native Freeze, value range [100, ), unit milliseconds. iOS default 250ms, Android default 1000ms |
| enableTrackNativeAppANR | bool | No | Whether to enable Native ANR monitoring, default false |
| enableTrackNativeCrash | bool | No | Whether to enable Android Java Crash and OC/C/C++ crash monitoring, default false |
| errorMonitorType | enum ErrorMonitorType | No | Sets auxiliary monitoring information, adds additional monitoring data to RUM Error data. Default is off |
| deviceMetricsMonitorType | enum DeviceMetricsMonitorType | No | Adds performance monitoring data within the View cycle, default is off |
| detectFrequency | enum DetectFrequency | No | View performance monitoring sampling period, default DetectFrequency.normal |
| globalContext | Map | No | Custom global parameters. For adding rules, please refer to Conflict Field Description |
| rumCacheDiscard | enum | No | Discard policy: FTRUMCacheDiscard.discard discards new data (default), FTRUMCacheDiscard.discardOldest discards oldest data |
| rumCacheLimitCount | number | No | Local cache maximum RUM entry count limit [10_000, ), default 100_000 |
| isInTakeUrl | callBack | No | Sets conditions for filtering Resources. For usage, please refer to Data Collection Custom Rules |
RUM User Data Tracking¶
Action¶
Usage¶
/// Add action
/// [actionName] action name
/// [actionType] action type
/// [property] additional property parameters (optional)
Future<void> startAction(String actionName, String actionType,
{Map<String, String>? property})
Code Example¶
View¶
Automatic Collection¶
After adding FTRouteObserver to MaterialApp.navigatorObservers, the SDK can automatically collect Flutter page switches. The page 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 page 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¶
Parse the page name from the widget's runtimeType via the custom FTMaterialPageRoute, where the widget class name is the page 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 examples, please refer to here.
Method 3: Collection via RouteSettings.name¶
Customize RouteSettings.name in Route type pages. FTRouteObserver will prioritize obtaining this value. This method also applies to Dialog type pages, such as showDialog(), showTimePicker(), etc.
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 within one project.
Sleep and Wake Event Collection¶
For versions below 0.5.1-pre.1, if you need to collect application sleep and wake behaviors, add the following code:
class _HomeState extends State<HomeRoute> {
@override
void initState() {
FTLifeRecycleHandler().initObserver();
}
@override
void dispose() {
FTLifeRecycleHandler().removeObserver();
}
}
For automatic collection filtering rules, please refer to Data Collection Custom Rules.
Custom View¶
Usage¶
/// View creation, this method needs to be called before [starView]
/// [viewName] interface name
/// [duration] page load duration
Future<void> createView(String viewName, int duration)
/// View start
/// [viewName] interface name
/// [viewReferer] previous interface name
/// [property] additional property parameters (optional)
Future<void> starView(String viewName, {Map<String, String>? property})
/// View end
/// [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 automatic page collection, route filtering, sleep/wake listening rules, etc., please refer to Data Collection Custom 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 custom error
/// [stack] stack trace
/// [message] error message
/// [appState] application state
/// [errorType] custom errorType
/// [property] additional property parameters (optional)
Future<void> addCustomError(String stack, String message,
{Map<String, String>? property, String? errorType})
Code Example¶
Resource¶
Automatic Collection¶
Enabled via FTRUMManager().setConfig by turning on enableUserResource.
Custom Resource¶
Usage¶
/// Start resource request
/// [key] unique id
/// [property] additional property parameters (optional)
Future<void> startResource(String key, {Map<String, String>? property})
/// End resource request
/// [key] 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,
})
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 using the
httplibrary anddiolibrary, refer to example.