31 Jan 2025 11:19 AM - edited 03 Feb 2025 06:10 AM
Monitoring Flutter apps with Dynatrace using the default/automatic setup provides basic features such as user actions (For Startup Mobile App Page Only), user session (Anonymous) and connected services (Always Showing Zero Connected Services). For comprehensive end-to-end monitoring—including user sessions with API calls, user tagging, waterfall analysis, web requests, service flow, reporting values or errors, user actions, and API tracking, follow the below guide.
1) Create a Mobile App in Dynatrace:
Navigate to the "Mobile App" section in Dynatrace using the search menu.
Click on "Create Mobile App."
Name your mobile app.
2) Select Flutter as the Technology:
In the Instrumentation Wizard, choose Flutter as the technology.
Follow the instructions provided, such as adding packages, updating the pubspec.yaml file, and inserting a code snippet to initialize the Flutter plugin when the app starts.
Important Notes:
The package version mentioned in Dynatrace might be outdated. Visit the official Dynatrace Flutter plugin page to get the latest version (currently dynatrace_flutter_plugin 3.305.2).
Add the package to your pubspec.yaml as shown below file and run flutter pub get to fetch it.
3) Download and Configure dynatrace.config.yaml:
Download the dynatrace.config.yaml file from Dynatrace and place it in the root folder of your Flutter project.
Modify the main() function in your Flutter app to initialize the Dynatrace plugin.
Below is the image that shows the code to modify the main() function.
4) Apply Configuration:
Run the command dart run dynatrace_flutter_plugin to apply the configuration.
Once completed, you should start seeing data in your Dynatrace tenant.
1) Track User Actions and Web Requests:
Refer to the official Dynatrace Flutter plugin documentation for advanced configurations like tracking user actions, web requests, reporting values, and handling errors.
Avoid modifying the dynatrace.config.yaml file; make changes directly in your code.
2) Update the main() Function:
Modify the main() function to include additional configurations like crash reporting, log levels, and certificate validation.
void main() => Dynatrace().start(const MyApp(),
configuration: const Configuration(
reportCrash: true,
logLevel: LogLevel.Info,
certificateValidation: false,
userOptIn: false,
));
3) Track Navigation Changes:
Add a DynatraceNavigationObserver to the MaterialApp widget to track page navigation changes dart.
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Mobile',
home: const SomeWidget(),
navigatorObservers: [
DynatraceNavigationObserver(),
],
);
}
Add the Dio Plugin:
Use the dynatrace_flutter_plugin_dio package (version 3.305.2) to monitor REST API calls.
Add the package to your pubspec.yaml file and run flutter pub get.
Create a Dynatrace HTTP Client:
Create a Dynatrace HTTP client and an action to track API calls.
var client = Dynatrace().createHttpClient();
DynatraceRootAction? webAction = Dynatrace().enterAction(endPoint);
Make API Calls:
Use the Dynatrace client to make API calls and close the action and client after the request is complete, according to your design patterns.
final response = await client.get(Uri.parse(url));
webAction?.leaveAction();
client.close();
Complete Example Of the API Call is shown below.
Future<Map<String, dynamic>> fetchProducts() async {
const String url = 'http://52.90.50.12:8080/api/products';
try {
final response = await client.get(Uri.parse(url));
print(response.headers);
if (response.statusCode == 200) {
final Map<String, dynamic> data = jsonDecode(response.body);
return data;
} else {
throw Exception('Failed to load products');
}
} catch (e) {
throw Exception('Failed to load products');
} finally {
webAction?.leaveAction();
client.close();
}
}
Once You finish this all custom configurations, restart the App and hit the API Calls from the Flutter Mobile App and after 2 or 3 minutes, you will see Web Requests & Connected Services .
Also You can see the service flow as well as shown below.
Use DynatraceRootAction and DynatraceAction:
Track interactions with parent and child widgets using DynatraceRootAction and DynatraceAction.
DynatraceRootAction myAction = Dynatrace().enterAction("MyButton tapped");
DynatraceAction mySubAction = myAction.enterAction("MyButton Sub Action");
mySubAction.leaveAction();
myAction.leaveAction();
Example Implementation:
Here’s an example of tracking actions in a CheckoutPage widget:
class CheckoutPage extends StatefulWidget {
const CheckoutPage({super.key});
@override
State<CheckoutPage> createState() => _CheckoutPageState();
}
class _CheckoutPageState extends State<CheckoutPage> {
DynatraceRootAction? parentAction;
@override
void initState() {
super.initState();
parentAction =
Dynatrace().enterAction("Checkout Page Initialised");
}
@override
void dispose() {
super.dispose();
parentAction!.leaveAction();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Checkout"),
centerTitle: true,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: MediaQuery.of(context).size.width * 0.7,
height: 60,
margin: const EdgeInsets.symmetric(vertical: 10),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.black,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8), // Rounded corners
),
),
onPressed: () {
DynatraceAction childAction = parentAction!.enterAction("Pay Online Button Clicked");
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const ProductListScreen()));
childAction.leaveAction();
},
child: const Text(
"Pay Online",
style: TextStyle(
fontSize: 16,
),
),
),
),
],
),
),
);
}
}
Report Values:
Use methods like reportStringValue, reportIntValue, and reportDoubleValue to report values during user interactions to dynatrace.
myAction.reportStringValue("totalPrice", "${price}");
There are also other values that we can report while using App as shown below to Dynatrace.
void reportError(String errorName, int errorCode, {Platform platform})
void reportErrorStacktrace(
String errorName, String errorValue, String reason, String stacktrace,
{Platform platform});
void reportEvent(String eventName, {Platform platform})
void reportIntValue(String valueName, int value, {Platform platform})
void reportDoubleValue(String valueName, double value, {Platform platform})
User Tagging:
User tagging allows you to track and identify individual users or user sessions by assigning custom tags (username,email,user_id), which will help you to recognize which session is related to which user.
Below is the code snippet given which you will put inside the login functionality or AutoLogin Functionality based on JWT Token Expired Or not.
String userName = "Zaid Bashir";
Dynatrace().identifyUser(userName);
Exit Session:
To Exit the current session, just add below code snippet in your logout functionality in the App.
Dynatrace().endSession();
Thank you for reading this guide on monitoring Flutter apps with Dynatrace! We hope it helps you achieve seamless end-to-end observability for your applications. Happy monitoring! 🚀.