<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Monitoring Flutter Apps End To End With Dynatrace in Dynatrace tips</title>
    <link>https://community.dynatrace.com/t5/Dynatrace-tips/Monitoring-Flutter-Apps-End-To-End-With-Dynatrace/m-p/268935#M1565</link>
    <description>&lt;P&gt;&lt;SPAN&gt;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 (&lt;STRONG&gt;Always Showing Zero Connected Services&lt;/STRONG&gt;). 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.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Step 1: Setting Up Mobile App Monitoring in Dynatrace&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;1) Create a Mobile App in Dynatrace&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Navigate to the "Mobile App" section in Dynatrace using the search menu.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Click on "Create Mobile App."&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Name your mobile app.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_1-1738311565946.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26104i4E884D69FFB2B382/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_1-1738311565946.png" alt="zaidbashir_1-1738311565946.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_2-1738311648826.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26105iD17922648394F39C/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_2-1738311648826.png" alt="zaidbashir_2-1738311648826.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_3-1738311749991.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26106iCD29D15A80DC8261/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_3-1738311749991.png" alt="zaidbashir_3-1738311749991.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;2) Select Flutter as the Technology&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;In the Instrumentation Wizard, choose&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Flutter&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;as the technology.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Follow the instructions provided, such as adding packages, updating the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;pubspec.yaml&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;file, and inserting a code snippet to initialize the Flutter plugin when the app starts.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_4-1738311840789.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26107iA07FF039A7084151/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_4-1738311840789.png" alt="zaidbashir_4-1738311840789.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Important Notes&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;The package version mentioned in Dynatrace might be outdated. Visit the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://pub.dev/packages/dynatrace_flutter_plugin" target="_blank" rel="noopener noreferrer"&gt;official Dynatrace Flutter plugin page&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to get the latest version (currently&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;dynatrace_flutter_plugin 3.305.2).&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Add the package to your&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;pubspec.yaml&lt;SPAN&gt;&amp;nbsp;as shown below&amp;nbsp;&lt;/SPAN&gt;file and run&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;flutter pub get&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to fetch it.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_5-1738312484926.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26109i641580B1C6766EE9/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_5-1738312484926.png" alt="zaidbashir_5-1738312484926.png" /&gt;&lt;/span&gt;&lt;STRONG&gt;3)&amp;nbsp;Download and Configure&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;dynatrace.config.yaml&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Download the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;dynatrace.config.yaml&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;file from Dynatrace and place it in the root folder of your Flutter project.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Modify the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;main()&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;function in your Flutter app to initialize the Dynatrace plugin.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_6-1738312714470.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26110i45DE5704608EF89D/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_6-1738312714470.png" alt="zaidbashir_6-1738312714470.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Below is the image that shows the code to modify the main() function.&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_7-1738312874383.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26111iA03899BC8115B39C/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_7-1738312874383.png" alt="zaidbashir_7-1738312874383.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;4) Apply Configuration&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Run the command&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;dart run dynatrace_flutter_plugin&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to apply the configuration.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Once completed, you should start seeing data in your Dynatrace tenant.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_8-1738312948997.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26112iA0A76C360924368F/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_8-1738312948997.png" alt="zaidbashir_8-1738312948997.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_9-1738317117221.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26113iE0DFFD8337E609D1/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_9-1738317117221.png" alt="zaidbashir_9-1738317117221.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Step 2: Advanced Configurations&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;1) Track User Actions and Web Requests&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Refer to the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://pub.dev/packages/dynatrace_flutter_plugin" target="_blank" rel="noopener noreferrer"&gt;official Dynatrace Flutter plugin documentation&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;for advanced configurations like tracking user actions, web requests, reporting values, and handling errors.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Avoid modifying the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;dynatrace.config.yaml&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;file; make changes directly in your code.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-left" image-alt="Screenshot 2025-01-31 121317.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26098i39162B823A2AAE0E/image-size/large?v=v2&amp;amp;px=999" role="button" title="Screenshot 2025-01-31 121317.png" alt="Screenshot 2025-01-31 121317.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;2) Update the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;main()&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Function&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Modify the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;main()&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;function to include additional configurations like crash reporting, log levels, and certificate validation.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;void main() =&amp;gt; Dynatrace().start(const MyApp(),
    configuration: const Configuration(
      reportCrash: true,
      logLevel: LogLevel.Info,
      certificateValidation: false,
      userOptIn: false,
    ));&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;3) Track Navigation Changes&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Add a&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;DynatraceNavigationObserver&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;MaterialApp&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;widget to track page navigation changes&amp;nbsp;&lt;SPAN&gt;dart.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Mobile',
      home: const SomeWidget(),
      navigatorObservers: [
        DynatraceNavigationObserver(),
      ],
    );
  }&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Step 3: Monitoring REST APIs&lt;/STRONG&gt;&lt;/H3&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;Add the Dio Plugin&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Use the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;dynatrace_flutter_plugin_dio&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;package (version&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;3.305.2) to monitor REST API calls.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Add the package to your&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;pubspec.yaml&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;file and run&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;flutter pub get.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;Create a Dynatrace HTTP Client&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Create a Dynatrace HTTP client and an action to track API calls.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;  var client = Dynatrace().createHttpClient();&lt;/LI-CODE&gt;&lt;LI-CODE lang="java"&gt;DynatraceRootAction? webAction = Dynatrace().enterAction(endPoint);&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Make API Calls&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Use the Dynatrace client to make API calls and close the action and client after the request is complete, according to your design patterns.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;final response = await client.get(Uri.parse(url));&lt;/LI-CODE&gt;&lt;LI-CODE lang="java"&gt;webAction?.leaveAction();
client.close();&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Complete Example Of the API Call is shown below.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;  Future&amp;lt;Map&amp;lt;String, dynamic&amp;gt;&amp;gt; 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&amp;lt;String, dynamic&amp;gt; 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();
    }
  }&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;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 &lt;STRONG&gt;Web Requests&lt;/STRONG&gt; &amp;amp; &lt;STRONG&gt;Connected Services&lt;/STRONG&gt;&amp;nbsp;.&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_10-1738318874566.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26114i11E43C8EBB8B1636/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_10-1738318874566.png" alt="zaidbashir_10-1738318874566.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Also You can see the service flow as well as shown below.&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_11-1738319009548.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26115i85D4D6A41E1EE27C/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_11-1738319009548.png" alt="zaidbashir_11-1738319009548.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Step 4: Tracking Parent and Child Widgets&lt;/STRONG&gt;&lt;/H3&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;Use&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;DynatraceRootAction&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;DynatraceAction&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Track interactions with parent and child widgets using&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;DynatraceRootAction&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;DynatraceAction.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;DynatraceRootAction myAction = Dynatrace().enterAction("MyButton tapped");
DynatraceAction mySubAction = myAction.enterAction("MyButton Sub Action");


mySubAction.leaveAction();
myAction.leaveAction();&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Example Implementation&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Here’s an example of tracking actions in a&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;CheckoutPage&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;widget:&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;class CheckoutPage extends StatefulWidget {
  const CheckoutPage({super.key});

  @override
  State&amp;lt;CheckoutPage&amp;gt; createState() =&amp;gt; _CheckoutPageState();
}

class _CheckoutPageState extends State&amp;lt;CheckoutPage&amp;gt; {
  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) =&amp;gt; const ProductListScreen()));
                  childAction.leaveAction();
                },
                child: const Text(
                  "Pay Online",
                  style: TextStyle(
                    fontSize: 16,
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Step 5: Reporting Values and Errors&lt;/STRONG&gt;&lt;/H3&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;Report Values&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Use methods like&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;reportStringValue,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;reportIntValue, and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;reportDoubleValue&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to report values during user interactions to dynatrace.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;DIV class=""&gt;
&lt;DIV class=""&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;myAction.reportStringValue("totalPrice", "${price}");&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;BR /&gt;There are also other values that we can report while using App as shown below to Dynatrace.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;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})&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Step 6: User Tagging &amp;amp; Exiting Sessions&lt;/STRONG&gt;&lt;/H3&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;User Tagging&lt;/STRONG&gt;:&lt;/P&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; User tagging allows you to track and identify individual users or user sessions by assigning custom tags&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (username,email,user_id), which will help you to recognize which session is related to which user.&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Below is the code snippet given which you will put inside the login functionality or AutoLogin Functionality&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; based&amp;nbsp; on JWT Token Expired Or not.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;String userName = "Zaid Bashir";
Dynatrace().identifyUser(userName);&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;Exit Session&lt;/STRONG&gt;:&lt;/P&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;To Exit the current session, just add below code snippet in your logout functionality in the App.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;Dynatrace().endSession();&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;T&lt;SPAN&gt;hank 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! &lt;span class="lia-unicode-emoji" title=":rocket:"&gt;🚀&lt;/span&gt;.&lt;/SPAN&gt;&lt;/P&gt;</description>
    <pubDate>Mon, 10 Feb 2025 08:19:37 GMT</pubDate>
    <dc:creator>zaid-bashir</dc:creator>
    <dc:date>2025-02-10T08:19:37Z</dc:date>
    <item>
      <title>Monitoring Flutter Apps End To End With Dynatrace</title>
      <link>https://community.dynatrace.com/t5/Dynatrace-tips/Monitoring-Flutter-Apps-End-To-End-With-Dynatrace/m-p/268935#M1565</link>
      <description>&lt;P&gt;&lt;SPAN&gt;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 (&lt;STRONG&gt;Always Showing Zero Connected Services&lt;/STRONG&gt;). 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.&lt;/SPAN&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Step 1: Setting Up Mobile App Monitoring in Dynatrace&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;1) Create a Mobile App in Dynatrace&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Navigate to the "Mobile App" section in Dynatrace using the search menu.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Click on "Create Mobile App."&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Name your mobile app.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_1-1738311565946.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26104i4E884D69FFB2B382/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_1-1738311565946.png" alt="zaidbashir_1-1738311565946.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_2-1738311648826.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26105iD17922648394F39C/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_2-1738311648826.png" alt="zaidbashir_2-1738311648826.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_3-1738311749991.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26106iCD29D15A80DC8261/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_3-1738311749991.png" alt="zaidbashir_3-1738311749991.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;2) Select Flutter as the Technology&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;In the Instrumentation Wizard, choose&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Flutter&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;as the technology.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Follow the instructions provided, such as adding packages, updating the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;pubspec.yaml&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;file, and inserting a code snippet to initialize the Flutter plugin when the app starts.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_4-1738311840789.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26107iA07FF039A7084151/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_4-1738311840789.png" alt="zaidbashir_4-1738311840789.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Important Notes&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;The package version mentioned in Dynatrace might be outdated. Visit the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://pub.dev/packages/dynatrace_flutter_plugin" target="_blank" rel="noopener noreferrer"&gt;official Dynatrace Flutter plugin page&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to get the latest version (currently&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;dynatrace_flutter_plugin 3.305.2).&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Add the package to your&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;pubspec.yaml&lt;SPAN&gt;&amp;nbsp;as shown below&amp;nbsp;&lt;/SPAN&gt;file and run&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;flutter pub get&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to fetch it.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_5-1738312484926.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26109i641580B1C6766EE9/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_5-1738312484926.png" alt="zaidbashir_5-1738312484926.png" /&gt;&lt;/span&gt;&lt;STRONG&gt;3)&amp;nbsp;Download and Configure&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;dynatrace.config.yaml&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Download the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;dynatrace.config.yaml&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;file from Dynatrace and place it in the root folder of your Flutter project.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Modify the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;main()&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;function in your Flutter app to initialize the Dynatrace plugin.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_6-1738312714470.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26110i45DE5704608EF89D/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_6-1738312714470.png" alt="zaidbashir_6-1738312714470.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Below is the image that shows the code to modify the main() function.&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_7-1738312874383.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26111iA03899BC8115B39C/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_7-1738312874383.png" alt="zaidbashir_7-1738312874383.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;4) Apply Configuration&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Run the command&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;dart run dynatrace_flutter_plugin&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to apply the configuration.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Once completed, you should start seeing data in your Dynatrace tenant.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_8-1738312948997.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26112iA0A76C360924368F/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_8-1738312948997.png" alt="zaidbashir_8-1738312948997.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_9-1738317117221.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26113iE0DFFD8337E609D1/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_9-1738317117221.png" alt="zaidbashir_9-1738317117221.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Step 2: Advanced Configurations&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;1) Track User Actions and Web Requests&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Refer to the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://pub.dev/packages/dynatrace_flutter_plugin" target="_blank" rel="noopener noreferrer"&gt;official Dynatrace Flutter plugin documentation&lt;/A&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;for advanced configurations like tracking user actions, web requests, reporting values, and handling errors.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Avoid modifying the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;dynatrace.config.yaml&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;file; make changes directly in your code.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-left" image-alt="Screenshot 2025-01-31 121317.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26098i39162B823A2AAE0E/image-size/large?v=v2&amp;amp;px=999" role="button" title="Screenshot 2025-01-31 121317.png" alt="Screenshot 2025-01-31 121317.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;2) Update the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;main()&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Function&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Modify the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;main()&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;function to include additional configurations like crash reporting, log levels, and certificate validation.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;void main() =&amp;gt; Dynatrace().start(const MyApp(),
    configuration: const Configuration(
      reportCrash: true,
      logLevel: LogLevel.Info,
      certificateValidation: false,
      userOptIn: false,
    ));&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;3) Track Navigation Changes&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Add a&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;DynatraceNavigationObserver&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;MaterialApp&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;widget to track page navigation changes&amp;nbsp;&lt;SPAN&gt;dart.&lt;/SPAN&gt;&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Mobile',
      home: const SomeWidget(),
      navigatorObservers: [
        DynatraceNavigationObserver(),
      ],
    );
  }&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Step 3: Monitoring REST APIs&lt;/STRONG&gt;&lt;/H3&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;Add the Dio Plugin&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Use the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;dynatrace_flutter_plugin_dio&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;package (version&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;3.305.2) to monitor REST API calls.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Add the package to your&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;pubspec.yaml&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;file and run&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;flutter pub get.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;Create a Dynatrace HTTP Client&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Create a Dynatrace HTTP client and an action to track API calls.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;  var client = Dynatrace().createHttpClient();&lt;/LI-CODE&gt;&lt;LI-CODE lang="java"&gt;DynatraceRootAction? webAction = Dynatrace().enterAction(endPoint);&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Make API Calls&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Use the Dynatrace client to make API calls and close the action and client after the request is complete, according to your design patterns.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;final response = await client.get(Uri.parse(url));&lt;/LI-CODE&gt;&lt;LI-CODE lang="java"&gt;webAction?.leaveAction();
client.close();&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Complete Example Of the API Call is shown below.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;  Future&amp;lt;Map&amp;lt;String, dynamic&amp;gt;&amp;gt; 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&amp;lt;String, dynamic&amp;gt; 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();
    }
  }&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;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 &lt;STRONG&gt;Web Requests&lt;/STRONG&gt; &amp;amp; &lt;STRONG&gt;Connected Services&lt;/STRONG&gt;&amp;nbsp;.&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_10-1738318874566.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26114i11E43C8EBB8B1636/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_10-1738318874566.png" alt="zaidbashir_10-1738318874566.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Also You can see the service flow as well as shown below.&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="zaidbashir_11-1738319009548.png" style="width: 999px;"&gt;&lt;img src="https://community.dynatrace.com/t5/image/serverpage/image-id/26115i85D4D6A41E1EE27C/image-size/large?v=v2&amp;amp;px=999" role="button" title="zaidbashir_11-1738319009548.png" alt="zaidbashir_11-1738319009548.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Step 4: Tracking Parent and Child Widgets&lt;/STRONG&gt;&lt;/H3&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;Use&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;DynatraceRootAction&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;DynatraceAction&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Track interactions with parent and child widgets using&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;DynatraceRootAction&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;DynatraceAction.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;DynatraceRootAction myAction = Dynatrace().enterAction("MyButton tapped");
DynatraceAction mySubAction = myAction.enterAction("MyButton Sub Action");


mySubAction.leaveAction();
myAction.leaveAction();&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Example Implementation&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Here’s an example of tracking actions in a&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;CheckoutPage&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;widget:&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;class CheckoutPage extends StatefulWidget {
  const CheckoutPage({super.key});

  @override
  State&amp;lt;CheckoutPage&amp;gt; createState() =&amp;gt; _CheckoutPageState();
}

class _CheckoutPageState extends State&amp;lt;CheckoutPage&amp;gt; {
  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) =&amp;gt; const ProductListScreen()));
                  childAction.leaveAction();
                },
                child: const Text(
                  "Pay Online",
                  style: TextStyle(
                    fontSize: 16,
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Step 5: Reporting Values and Errors&lt;/STRONG&gt;&lt;/H3&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;Report Values&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;P&gt;Use methods like&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;reportStringValue,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;reportIntValue, and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;reportDoubleValue&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to report values during user interactions to dynatrace.&lt;/P&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;DIV class=""&gt;
&lt;DIV class=""&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;myAction.reportStringValue("totalPrice", "${price}");&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;BR /&gt;There are also other values that we can report while using App as shown below to Dynatrace.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;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})&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Step 6: User Tagging &amp;amp; Exiting Sessions&lt;/STRONG&gt;&lt;/H3&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;User Tagging&lt;/STRONG&gt;:&lt;/P&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; User tagging allows you to track and identify individual users or user sessions by assigning custom tags&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (username,email,user_id), which will help you to recognize which session is related to which user.&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Below is the code snippet given which you will put inside the login functionality or AutoLogin Functionality&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; based&amp;nbsp; on JWT Token Expired Or not.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;String userName = "Zaid Bashir";
Dynatrace().identifyUser(userName);&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;Exit Session&lt;/STRONG&gt;:&lt;/P&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;To Exit the current session, just add below code snippet in your logout functionality in the App.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;Dynatrace().endSession();&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;T&lt;SPAN&gt;hank 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! &lt;span class="lia-unicode-emoji" title=":rocket:"&gt;🚀&lt;/span&gt;.&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 10 Feb 2025 08:19:37 GMT</pubDate>
      <guid>https://community.dynatrace.com/t5/Dynatrace-tips/Monitoring-Flutter-Apps-End-To-End-With-Dynatrace/m-p/268935#M1565</guid>
      <dc:creator>zaid-bashir</dc:creator>
      <dc:date>2025-02-10T08:19:37Z</dc:date>
    </item>
  </channel>
</rss>

