Mobile APM for Flutter applications
The Site24x7 Flutter plugin enables users to monitor HTTP requests, crashes, screen loading times, and custom data of their Flutter mobile applications. This can be achieved by adding transactions and grouping them based on components, individual users, and their sessions, thereby enhancing the performance of the application.
Getting started
Follow the steps outlined below to install site24x7_flutter_plugin in your Flutter application.
- To install the plugin, run the following command.
flutter pub add site24x7_flutter_plugin
- Open the pubspec.yaml file located in the app folder, and you will find that a line site24x7_flutter_plugin: has been added to the dependencies section, as shown below.
dependencies:
site24x7_flutter_plugin: ^1.0.0
Installation steps for iOS
- Add pod to the Podfile in the project_directory/ios/.
target 'Your_Project_Name' do
pod 'Site24x7APM'
end - Run the following command in the same directory.
pod install
Installation steps for Android
Add the Zoho Maven URL to the build.gradle file located in the android folder of the applications project level.
allprojects {
repositories {
...
maven { url 'https://maven.zohodl.com' }
...
}
}
Usage in Flutter applications
Import ApmMobileapmFlutterPlugin from the site24x7_flutter.dart file as follows:
import 'package:site24x7_flutter_plugin/site24x7_flutter_plugin.dart';
APIs to capture other parameters
Custom APIs are utilized for monitoring user actions, capturing screens, tracking errors and exceptions, and performing other related tasks. This document provides an overview of the different types of custom APIs offered in Site24x7 and the corresponding syntax for their usage.
- Initialize the agent
- Configure screen tracking
- Network monitoring
- Error monitoring
- Managing transactions and components
- User tracking
- Adding breadcrumbs
- Manual flush
- Forced application crash
Initialize the agent
You can use the API below to start the Site24x7 Flutter agent, which will capture Flutter errors and exceptions seamlessly for enhanced monitoring in your Flutter application.
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')); ... }
Configure screen tracking
You can use the following mechanism to determine how long it takes for a screen to load. This data is pushed to the Site24x7 servers and can be used for session tracking and crash reporting.
For stateless 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 }); }, ), ), ); } }
For stateful widget:
import 'package:site24x7_flutter_plugin/site24x7_flutter_plugin.dart'; class SampleWidget extends StatefulWidget { const SampleWidget({super.key}); @override StatecreateState() => _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 } }
To capture breadcrumbs during routing automatically, utilize the Site24x7NavigatorObserver() function in the following manner:
class MyHomePage extends StatefulWidget { @override StatecreateState() => _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 ] ); } }
Network monitoring
Network monitoring capabilities include support for HTTP and Dio packages, allowing for the capture of API calls made using these packages.
HTTP package:
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 package:
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); ...
Error monitoring
You can manually capture exceptions that occur in catch blocks by using the API mentioned below.
To capture non-async exceptions:
Futuremain() async { WidgetsFlutterBinding.ensureInitialized(); FlutterError.onError = ApmMobileapmFlutterPlugin.instance.captureFlutterError; //site24x7 custom callback runApp(MyHomePage()); }
To capture async exceptions:
Futuremain() async { WidgetsFlutterBinding.ensureInitialized(); PlatformDispatcher.instance.onError = (error, stack){ ApmMobileapmFlutterPlugin.instance.platformDispatcherErrorCallback(error, stack); //site24x7 custom api }; runApp(MyHomePage()); }
To capture caught exceptions:
try { //code which might generate exceptions } catch (exception, stack){ ApmMobileapmFlutterPlugin.instance.captureException(exception, stack); }
Managing transactions and components
You can start and stop a unique component within a transaction. You can also begin more than one component in a single transaction.
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");
User tracking
You can track a specific user by setting up a unique user identifier. In case a unique ID is not provided, Site24x7 will generate a random GUID and assign it as the user ID.
ApmMobileapmFlutterPlugin.instance.setUserId("user@example.com");
Adding breadcrumbs
Use the function below to add breadcrumbs manually.
ApmMobileapmFlutterPlugin.instance.addBreadcrumb(event, message); ex: ApmMobileapmFlutterPlugin.instance.addBreadcrumb("Info", "download completed");
Manual flush
You can use the API provided below to promptly send data to the Site24x7 servers instead of waiting for the next upload interval.
ApmMobileapmFlutterPlugin.instance.flush();
Forced application crash
You can force your application to crash and display an error message: This is a site24x7 crash.
ApmMobileapmFlutterPlugin.instance.crashApplication();
Release notes
Version 1.0.0
05 February 2024
Enhancements:
- Support for tracking HTTP calls with the request method, response time, throughput, status codes, platform, and screens.
- Support for tracking screens based on the response time, throughput, and count.
- Support for automatic tracking of navigations.
- Support for manually tracking views.
- Enabled user sessions tracking with a session timeout of 15 minutes.
- Support for manually adding user IDs.
- Support for tracking async and non-async crashes using agent-provided callbacks.
- Support for manually adding breadcrumbs.
- Support for packages such as HTTP and Dio.