Flutter 应用程序的移动 APM
Site24x7 Flutter 插件使用户能够监控其 Flutter 移动应用程序的 HTTP 请求、崩溃、屏幕加载时间和自定义数据。这可以通过添加事务并基于组件、单个用户及其会话进行分组来实现,从而提升应用程序的性能。
入门
按照以下步骤在您的 Flutter 应用程序中安装 site24x7_flutter_plugin。
- 要安装插件,请运行以下命令。
flutter pub add site24x7_flutter_plugin
- 打开位于应用程序文件夹中的 pubspec.yaml 文件,您将看到 site24x7_flutter_plugin: 已添加到依赖项部分,如下所示。
dependencies:
site24x7_flutter_plugin: ^1.0.0
iOS 安装步骤
- 将 pod 添加到 project_directory/ios/ 中的 Podfile。
target 'Your_Project_Name' do
pod 'Site24x7APM'
end - 在同一目录中运行以下命令。
pod install
Android 安装步骤
将 Zoho Maven URL 添加到位于应用程序项目级 android 文件夹中的 build.gradle 文件。
allprojects {
repositories {
...
maven { url 'https://maven.zohodl.com' }
...
}
}
在 Flutter 应用程序中的用法
从 site24x7_flutter.dart 文件中导入 ApmMobileapmFlutterPlugin,如下所示:
import 'package:site24x7_flutter_plugin/site24x7_flutter_plugin.dart';
捕获其他参数的 API
自定义 API 用于监控用户操作、捕获屏幕、追踪错误和异常以及执行其他相关任务。本文档概述了 Site24x7 提供的不同类型自定义 API 及其对应的使用语法。
初始化代理
您可以使用以下 API 启动 Site24x7 Flutter 代理,该代理将无缝捕获 Flutter 错误和异常,从而增强对 Flutter 应用程序的监控。
import 'package:site24x7_flutter_plugin/site24x7_flutter_plugin.dart'; Futuremain() async { WidgetsFlutterBinding.ensureInitialized(); //assign the Site24x7 error callbacks //for non-async exceptions FlutterError.onError = ApmMobileapmFlutterPlugin.instance.captureFlutterError; //site24x7 custom callback //for async exceptions PlatformDispatcher.instance.onError = (error, stack) { ApmMobileapmFlutterPlugin.instance.captureException(error, stack, false, type: "uncaughtexception"); //site24x7 custom api return true; }; //starting the agent ApmMobileapmFlutterPlugin.instance.startMonitoring("appKey", uploadInterval); //site24x7 custom api ... runApp(MyHomePage(title: 'Flutter Demo Home Page')); ... }
其中,
appKey:用于在 Site24x7 中标识您的应用程序的唯一应用程序密钥。
要从 Site24x7 客户端获取 appKey,请前往 APM > 移动 APM,点击应用程序名称旁边的汉堡菜单图标,然后从菜单中选择复制应用程序密钥。

uploadInterval:向 Site24x7 服务器发送数据的时间间隔(以秒为单位)。
理想的上传间隔为 18 到 30 秒,以获得最佳性能。
请确保在 main 方法中赋值错误回调之前调用 WidgetsFlutterBinding.ensureInitialized();。
配置屏幕追踪
您可以使用以下机制来确定屏幕加载所需的时间。这些数据会推送到 Site24x7 服务器,可用于会话追踪和崩溃报告。
对于无状态 widget:
import 'package:site24x7_flutter_plugin/site24x7_flutter_plugin.dart';
class FirstScreen extends StatelessWidget {
FirstScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Sample Widget'),
),
body: Center(
child: ElevatedButton(
child: const Text('Go To Stateless Widget'),
onPressed: () {
var initialTimeStamp = DateTime.now();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SampleStatelessWidget()
),
).then((value) {
var loadTime = DateTime.now().difference(initialTimeStamp).inMilliseconds;
ApmMobileapmFlutterPlugin.instance.addScreen("SampleStatelessWidget", loadTime.toDouble(), initialTimeStamp.millisecondsSinceEpoch); //site24x7 custom api
});
},
),
),
);
}
}
对于有状态 widget:
import 'package:site24x7_flutter_plugin/site24x7_flutter_plugin.dart';
class SampleWidget extends StatefulWidget {
const SampleWidget({super.key});
@override
State createState() => _SampleWidgetState();
}
class _SampleWidgetState extends State {
late var _initialTimeStamp, _finalTimeStamp;
@override
void initState() {
super.initState();
_initialTimeStamp = DateTime.now();
}
void site24x7AfterBuildCallback(BuildContext context) {
var finalTimeStamp = DateTime.now();
}
@override
Widget build(BuildContext context) {
WidgetsBinding.instance!.addPostFrameCallback((_) => site24x7AfterBuildCallback(context));
return Scaffold(
appBar: AppBar(
title: const Text('Sample Widget'),
),
body: Center(
child: const Text('Hello Sample Widget');
),
);
}
@override
void didUpdateWidget(Fetch oldWidget) {
super.didUpdateWidget(oldWidget);
//send the widget loading time, i.e., difference between initial and final timestamp should be sent to the server using addScreen API
var loadTime = _finalTimeStamp.difference(_initialTimeStamp).inMilliseconds;
ApmMobileapmFlutterPlugin.instance.addScreen("Fetch", loadTime.toDouble(), _initialTimeStamp.millisecondsSinceEpoch); //site24x7 custom api
//assign final timestamp to initial timestamp
_initialTimeStamp = DateTime.now();
}
@override
void dispose() {
super.dispose();
//send the widget loading time, i.e., difference between initial and final timestamp should be sent to the server using addScreen API
var loadTime = _finalTimeStamp.difference(_initialTimeStamp).inMilliseconds;
ApmMobileapmFlutterPlugin.instance.addScreen("Fetch", loadTime.toDouble(), _initialTimeStamp.millisecondsSinceEpoch); //site24x7 custom api
}
}
要在路由期间自动捕获面包屑,请按以下方式使用 Site24x7NavigatorObserver() 函数:
class MyHomePage extends StatefulWidget {
@override
State createState() => _MyHomePageState();
}
class _MyHomePageState extends State with WidgetsBindingObserver {
@override
Widget build(BuildContext context){
return MaterialApp(
routes: {
'/first': (context) => FirstScreen(),
'/second': (context) => SecondScreen(),
'/fetch': (context) => FetchScreen()
},
navigatorObservers: [
Site24x7NavigatorObserver() //site24x7 custom navigator observer
]
);
}
}
网络监控
网络监控功能支持 HTTP 和 Dio 包,允许捕获使用这些包发出的 API 调用。
HTTP 包:
import 'package:http/http.dart' as http;
import 'package:site24x7_flutter_plugin/site24x7_flutter.dart';
...
//site24x7 custom components
var client = Site24x7HttpClient();
(or)
var client = Site24x7HttpClient(client: http.Client());
var dataURL = Uri.parse('https://jsonplaceholder.typicode.com/posts?userId=1&_limit=5');
http.Response response = await client.get(dataURL);
...
Dio 包:
import 'package:dio/dio.dart'; import 'package:site24x7_flutter_plugin/site24x7_flutter_plugin.dart'; ... var dio = Dio(); dio.enableSite24x7(); //site24x7 dio extension var dataURL = 'https://jsonplaceholder.typicode.com/posts?userId=1_limit=5'; final response = await dio.get(dataURL); ...
错误监控
您可以使用以下 API 手动捕获 catch 块中发生的异常。
捕获非异步异常:
Futuremain() async { WidgetsFlutterBinding.ensureInitialized(); FlutterError.onError = ApmMobileapmFlutterPlugin.instance.captureFlutterError; //site24x7 custom callback runApp(MyHomePage()); }
捕获异步异常:
Futuremain() async { WidgetsFlutterBinding.ensureInitialized(); PlatformDispatcher.instance.onError = (error, stack){ ApmMobileapmFlutterPlugin.instance.platformDispatcherErrorCallback(error, stack); //site24x7 custom api }; runApp(MyHomePage()); }
建议在调用 runApp() 之前使用错误监控自定义 API。
捕获已捕获的异常:
try {
//code which might generate exceptions
} catch (exception, stack){
ApmMobileapmFlutterPlugin.instance.captureException(exception, stack);
}
管理事务和组件
您可以在事务中启动和停止唯一的组件。您还可以在单个事务中启动多个组件。
ApmMobileapmFlutterPlugin.instance.startTransaction("listing_blogs");
//Grouping various operations using components.
ApmMobileapmFlutterPlugin.instance.startComponent("listing_blogs", "http_request");
//your code/logic
ApmMobileapmFlutterPlugin.instance.stopComponent("listing_blogs", "http_request");
ApmMobileapmFlutterPlugin.instance.startComponent("listing_blogs", "view_data_onto_screen");
//your code/logic
ApmMobileapmFlutterPlugin.instance.stopComponent("listing_blogs", "view_data_onto_screen");
ApmMobileapmFlutterPlugin.instance.stopTransaction("listing_blogs");
用户追踪
您可以通过设置唯一的用户标识符来追踪特定用户。如果未提供唯一 ID,Site24x7 将生成一个随机 GUID 并将其分配为用户 ID。
ApmMobileapmFlutterPlugin.instance.setUserId("user@example.com");
添加面包屑
使用以下函数手动添加面包屑。
ApmMobileapmFlutterPlugin.instance.addBreadcrumb(event, message);
ex: ApmMobileapmFlutterPlugin.instance.addBreadcrumb("Info", "download completed");
手动刷新
您可以使用以下 API 立即向 Site24x7 服务器发送数据,而无需等待下一个上传间隔。
ApmMobileapmFlutterPlugin.instance.flush();
强制应用程序崩溃
您可以强制您的应用程序崩溃,并显示错误信息:This is a site24x7 crash。
ApmMobileapmFlutterPlugin.instance.crashApplication();
发布说明
版本 1.0.0
2024 年 2 月 5 日
增强功能:
- 支持使用请求方法、响应时间、吞吐量、状态码、平台和屏幕追踪 HTTP 调用。
- 支持基于响应时间、吞吐量和计数追踪屏幕。
- 支持自动追踪导航。
- 支持手动追踪视图。
- 启用会话超时为 15 分钟的用户会话追踪。
- 支持手动添加用户 ID。
- 支持使用代理提供的回调追踪异步和非异步崩溃。
- 支持手动添加面包屑。
- 支持 HTTP 和 Dio 等包。
