dynatrace_flutter_plugin 1.202.0

Flutter Android iOS

The Dynatrace Flutter plugin helps auto-instrument your Flutter app with Dynatrace OneAgent for Android and iOS. It also provides an API to add manual instrumentation.

N|Solid

Dynatrace Flutter Plugin #

The Dynatrace Flutter plugin helps auto-instrument your Flutter app with Dynatrace OneAgent for Android and iOS. It also provides an API to add manual instrumentation.

Requirements #

  • Dart Version: >= 2.4.0
  • Flutter Version >= 1.12.0
  • Gradle: >= 5.x
  • Supported Webrequest Framework: Dart HttpClient

Agent Versions #

  • Android Agent: 8.201.1.1004
  • iOS Agent: 8.201.1.1002

Quick Setup #

  1. Install plugin
  2. Setup configuration
  3. Start Flutter plugin
  4. Build and run your app

Startup #

Advanced topics #

Troubleshooting #

Quick Setup #

1. Install the plugin #

Open the pubspec.yaml file located inside the app folder, and add dynatrace_flutter_plugin: under dependencies:

dynatrace_flutter_plugin: ^1.202.0

After adding the dependency, resolve any dependencies if it hasn't happened automatically.

  • From the terminal, run flutter pub get.
  • From Android Studio/IntelliJ, click Packages get in the action ribbon at the top of pubspec.yaml.
  • From VS Code, click Get Packages located to the right of the action ribbon at the top of pubspec.yaml.

2. Set up dynatrace.config.yaml #

  • Create a mobile app in Dynatrace and open Mobile app settings. Go to Flutter configuration and download the configuration dynatrace.config.yaml. Store it in the root folder of your application.

Data collection #

By default, the user opt-in mode is activated in the configuration. This means that OneAgent only sends a limited number of actions until you change the privacy mode.

3. Start the Flutter plugin #

The Flutter plugin starts only when you directly call it via start(). You should see the following in your application:

void main() => runApp(MyApp());

replace it with the following statement:

import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';

void main() => Dynatrace().start(MyApp());

start({Configuration configuration}) takes an optional configuration object to customize the behaviour of the plugin. This configuration parameter can also be used for a manual startup. You can provide values such as beaconUrl or applicationId at runtime. runApp() is called internally.

4. Build and run your app #

Run flutter pub run dynatrace_flutter_plugin in the root of your Flutter project. This configures both Android and iOS projects with settings from dynatrace.config.yaml. If you want to see more logging, append or customize some paths via custom arguments while executing the command.

Call flutter run and the application starts including Dynatrace OneAgent.

Startup #

Plugin startup #

The startup of the plugin is triggered via the start(Widget _topLevelWidget, {Configuration configuration}) method. Without the start-up call, the plugin doesn't send data that is coming from the Flutter app part. The optional configuration parameters should only be used when doing a manual startup. The available options which are offered by the Configuration constructor are listed in the following table:

Configuration(
  reportCrash: true,
  monitorWebRequest : true,
  logLevel: LogLevel.Info,
  beaconUrl,
  applicationId,
  certificateValidation: true;
  userOptIn: false;
)
Property nameTypeDefaultDescription
reportCrashbooltrueReports Dart and Flutter crashes.
monitorWebRequestbooltrueMonitors web requests in your Flutter application.
logLevelLogLevelLogLevel.InfoAllows you to choose between LogLevel.Info and LogLevel.Debug. Debug returns more logs. This is especially important when something is not functioning correctly.
beaconUrlStringnullIdentifies your environment within Dynatrace. This property is mandatory for manual startup. OneAgent issues an error when the key isn't present.
applicationIdStringnullIdentifies your mobile app. This property is mandatory for manual startup. OneAgent issues an error when the key isn't present.
certificateValidationbooltrueAllows the use of self-signed certificates. By default, it is set to false. When set to true, OneAgent accepts self-signed certificates that are not signed by a root-CA. This configuration key doesn't impact mobile app connections. It's only used for OneAgent communication, but doesn't overrule the host-name validation.
userOptInboolfalseActivates the privacy mode when set to true. User consent must be queried and set. The privacy settings for data collection and crash reporting can be changed via OneAgent SDK for Mobile as described under Data privacy. The default value is false.

Note: The values used for the parameters are their default value.

Attention: Please use those parameters only when doing a manual startup. If you want to do an automated startup, please configure the properties via the auto startup configuration. You will find a list which explains all the counterparts for the available options here.

An example could look like the following:

import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';

void main() => Dynatrace().start(MyApp(), Configuration: Configuration(logLevel: LogLevel.Debug));

Manual OneAgent startup #

If you can't do a automated startup through the dynatrace.config.yaml, you can always perform a manual startup and decide values such as beaconUrl and applicationId at runtime.

Note: An automated startup usually provides you with a lifecycle application start-up event. A manual startup on the other hand occurs later, thereby causing you to miss everything, including this application startup event, until the startup occurs.

A manual startup requires the following two steps:

  1. Deactivate the automated startup in dynatrace.config.yaml:
android:
  config: 
    "dynatrace {
      configurations {
        defaultConfig {
          autoStart.enabled false
        }
      }
    }"
  
ios:
  config: 
    "<key>DTXAutoStart</key>
    <false/>"
  1. Make the start-up call with at least beaconUrl and applicationId:

Example of a startup call:

import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';

void main() => Dynatrace().start(MyApp(), Configuration: Configuration(beaconUrl: "..", applicationId: ".."));

Note: If you don't deactivate the automated startup with the dynatrace.config.yaml file, the beaconUrl and applicationId values have no impact and are thrown away.

Advanced topics #

Navigation observer #

To track navigations in your application, add DynatraceNavigationObserver to your MaterialApp:

MaterialApp(
  home: MyAppHome(),
  navigatorObservers: [
    DynatraceNavigationObserver(),
  ],
);

Manual instrumentation #

To use the API of the Flutter plugin, add the following import at the top of your dart file:

import 'package:dynatrace_flutter_plugin/dynatrace_flutter_plugin.dart';

Create manual actions #

To create a manual action named "MyButton tapped", use the following code:

DynatraceRootAction myAction = Dynatrace().enterAction("MyButton tapped");
//Perform the action and whatever else is needed.
myAction.leaveAction();

Note: leaveAction closes the action again. To report values for this action before closing, see Report values.

Create manual sub-actions #

You can create a single manual action and several sub-actions. MyButton Sub Action is automatically put under MyButton tapped. Only one sub-action level is allowed; you can't create a sub sub-action.

DynatraceRootAction myAction = Dynatrace().enterAction("MyButton tapped");
DynatraceAction mySubAction = myAction.enterAction("MyButton Sub Action");

//Perform the action and whatever else is needed.
mySubAction.leaveAction();
myAction.leaveAction();

Report values #

You can report certain values for any open action. The following API is available for DynatraceRootAction and DynatraceAction:

void reportError(String errorName, int errorCode, {Platform platform})
void reportEvent(String eventName, {Platform platform})
void reportStringValue(String valueName, String value, {Platform platform})
void reportIntValue(String valueName, int value, {Platform platform})
void reportDoubleValue(String valueName, int value, {Platform platform})

To report a string value, use the following code:

DynatraceRootAction myAction = Dynatrace().enterAction("MyButton tapped");
myAction.reportStringValue("ValueName", "ImportantValue");
myAction.leaveAction();

The {Platform platform} optional parameter is available for API calls. This parameter offers the possibility to report values only for a specific platform. For more information, see platform independent reporting.

Identify a user #

You can identify a user and tag the current session with a name by making the following call:

Dynatrace().identifyUser("User XY");

Crash reporting #

Crash reporting is enabled by default. Mobile OneAgent captures all unhandled exceptions and errors, and then, it immediately sends the crash report to the server. With this API, you can activate and deactivate crash reporting. To change this behaviour via the API, enable user opt-in and set the privacy settings.

Future<bool> isCrashReportingOptedIn({Platform platform})
void setCrashReportingOptedIn(bool crashReporting, {Platform platform})

To report a crash manually, use the following API on a Dynatrace() instance:

void reportCrash(String errorName, String errorMessage, String stacktrace, {Platform platform});

Examples for the parameters are:

Dynatrace().reportCrash("FormatException", "Invalid Double", "WHOLE_STACKTRACE_AS_STRING");

Data collection #

The privacy API methods allow you to dynamically change the data-collection level based on the individual preferences of your end users. Each end user can select from three data-privacy levels:

enum DataCollectionLevel {
    Off,
    Performance,
    User
}
  • Off: Mobile OneAgent doesn't capture any monitoring data.
  • Performance: Mobile OneAgent captures only anonymous performance data. Monitoring data that can be used to identify individual users, such as user tags and custom values, isn't captured.
  • User: Mobile OneAgent captures both performance and user data. In this mode, Mobile OneAgent recognizes and reports users who re-visit in future sessions.

The API to get and set the current level looks like this:

Future<DataCollectionLevel> getDataCollectionLevel({Platform platform})
void setDataCollectionLevel(DataCollectionLevel dataCollectionLevel, {Platform platform})

Report GPS location #

You can report latitude and longitude and specify an optional platform.

void setGPSLocation(double latitude, double longitude, {Platform platform})

Platform independent reporting #

Each method has an additional optional parameter named platform of type Platform. Use this parameter to only trigger manual instrumentation for a specific OS. The available values are: Platform.iOS and Platform.Android. By default, it will work on any platform. Otherwise it is passed only to the relevant OS. For example:

  • Passing to iOS only:
DynatraceAction myAction = Dynatrace().enterAction("MyButton tapped", Platform.iOS);
//Perform the action and whatever else is needed.
myAction.leaveAction("ios"); 
  • Passing to Android only:
DynatraceAction myAction = Dynatrace().enterAction("MyButton tapped", Platform.Android);
//Perform the action and whatever else is needed.
myAction.leaveAction("android"); 
  • Passing to both:
DynatraceAction myAction = Dynatrace().enterAction("MyButton tapped");
//Perform the action and whatever else is needed.
myAction.leaveAction(); 

Webrequest behaviour #

Currently the Dynatrace Flutter plugin supports the default Dart HTTPClient:

await HttpClient()
  .getUrl(Uri.parse('http://TestUrl.com')) 
  .then((request) => request.close()) 
  .then((response) => print("Request Done"));

This block is the standard implementation for a web request and doesn't need any further modification. It is tracked automatically. The following rules for action linking are applicable:

  • Root Action available: When you open a manual DynatraceRootAction before the request because the request is part of some user action, such as clicking a log-in button, the web request is linked to this DynatraceRootAction. If there are several DynatraceRootActions active, the request is linked to the newest one.
  • Root Action not available: When you trigger a request and don't have any open DynatraceRootAction, the request is tagged without any action information. The only exception for this tagging is if there are Android or iOS native auto user actions available. In such a case, we take this one for linking. The amount of native auto user actions is rare for Flutter as they are only fired from native components. Therefore, the request usually stands on its own. It is linked to the session but as a root web request. It isn't directly visible in the user session view in the web UI but is associated and visible within the Network performance tile.

Custom arguments #

Our scripts assume that the usual Flutter project structure is standard. The following arguments can be specified for our instrumentation script if the project structure is different.

  • --debug: Displays more log lines for the instrumentation script. Might be important if you have problems and want to get more information.
  • --gradle=C:\MyFlutterAndroidProject\build.gradle: The location of the root build.gradle file. We assume that the other gradle file resides in /app/build.gradle. This adds OneAgent dependencies automatically for you and updates the configuration.
  • --plist=C:\MyFlutterIOSProject\projectName\info.plist: Indicates the location of the info.plist file. The plist file is used for updating the configuration for the OneAgent.
  • --config=C:\SpecialFolderForDynatrace\dynatrace.config.js: Indicates that the config file isn't in the root folder of the Flutter project.

Example:

flutter pub run dynatrace_flutter_plugin --config=C:\SpecialFolderForDynatrace\dynatrace.config.yaml

Structure of the dynatrace.config.yaml file #

The configuration is structured in the following way:

android:
  // Configuration for Android auto instrumentation

ios:
  // Configuration for iOS auto instrumentation

Manual Startup Counterparts #

Here is a list of all the counterparts for the options that can be used with a manual startup. Below the counterparts table you will find an example configuration block for both Android and iOS.

Property NameDefaultAndroidiOS
reportCrashtruecrashReportingDTXCrashReporting
monitorWebRequesttruewebRequests.enabledDTXInstrumentWebRequestTiming
logLevelLogLevel.Infodebug.agentLoggingDTXLogLevel
beaconUrlnullautoStart.beaconUrlDTXBeaconURL
applicationIdnullautoStart.applicationIdDTXApplicationId
certificateValidationfalsedebug.certificateValidationDTXAllowAnyCert
userOptInfalseuserOptInDTXUserOptIn

Android Block #

The Android block is a wrapper for the Android configuration. You can find it under Mobile app settings in the web UI. Copy the content into the following block:

android:
  config: "CONTENT_OF_ANDROID_CONFIG"

The content of the config block is directly copied to the gradle file. To know more about the possible configuration options, see the DSL documentation of our gradle plugin.

The following block shows similar properties that can be used with manual startup but are used in auto startup configuration:

android:
  config: "dynatrace {
      configurations {
        defaultConfig {
          autoStart{
            applicationId 'xxx'
            beaconUrl 'xxx'
          }
          userOptIn false
          crashReporting true
          debug.agentLogging true
          debug.certificateValidation true
          webRequests.enabled true
        }
      }
    }"

iOS Block #

The iOS block is a wrapper for the iOS configuration. You can find it under Mobile app settings in the web UI. Copy the content into the following block:

ios:
  config: "CONTENT_OF_IOS_CONFIG"
};

The content of the config block is directly copied to the plist file, so you can use all the settings and properties listed in our official iOS Agent documentation.

The following block shows similar properties that can be used with manual startup but are used in auto startup configuration:

ios:
  config: "
    <key>DTXBeaconURL</key>
    <string>xxx</string>
    <key>DTXApplicationId</key>
    <string>xxx</string>
    <key>DTXLogLevel</key>
    <string>ALL</string>
    <key>DTXUserOptIn</key>
    </true>
    <key>DTXCrashReporting</key>
    </true>
    <key>DTXAllowAnyCert</key>
    </true>
    <key>DTXInstrumentWebRequestTiming</key>
    </false>"
};

Define build stages in dynatrace.config.yaml #

If you have several stages like debug, QA, and production, use a different configuration to separate them and have each stage report into different applications in the web UI.

Android #

In Android, you can enter all the information in the config file. So the following dynatrace {} block must be inserted into the android config variable in your dynatrace.config.js file.

android:
  config: "
    dynatrace {
      configurations {
        dev {
            variantFilter "Debug" // build type name is upper case because a product flavor is used
            // other variant-specific properties
        }
        demo {
            variantFilter "demo" // the first product flavor name is always lower case
            // other variant-specific properties
        }
        prod {
            variantFilter "Release" // build type name is upper case because a product flavor is used
            // other variant-specific properties
        }
      }
    }
  "
}

This results into the following:

> Task :app:printVariantAffiliation
Variant 'demoDebug' will use configuration 'dev'
Variant 'demoRelease' will use configuration 'demo'
Variant 'paidDebug' will use configuration 'dev'
Variant 'paidRelease' will use configuration 'prod'

In all these blocks, you can define your different application IDs. You can even use a different environment.

iOS #

In iOS, you can define some variables in the dynatrace.config.yaml file. These variables must then be inserted into a prebuild script. The following properties must be inserted into the iOS config variable in your dynatrace.config.yaml file.

ios:
  config: "
  <key>DTXApplicationID</key>
  <string>${APPLICATION_ID}</string>
  <key>DTXBeaconURL</key>
  <string>Your Beacon URL</string>
  "
}

The ${APPLICATION_ID} variable must then be inserted with a prebuild script. For more information on this, read https://medium.com/@andersongusmao/xcode-targets-with-multiples-build-configuration-90a575ddc687.

User opt-in mode #

Allows the user to opt in for monitoring. When enabled, specify the privacy settings. For more information, see the API section.

Android #

android:
  config: "
    dynatrace {
      configurations {
        defaultConfig {
          autoStart{
            ...
          }
          userOptIn true
        }
      }
    }
  "
}

iOS #

ios:
  config: "
  <key>DTXUserOptIn</key>
  </true>
  "
}

Mobile OneAgent debug logs #

If the instrumentation runs through and your application starts but you see no data, you must investigate and find out the reason the mobile agents are not sending any data. You can always open a support ticket, but we strongly recommend that you first collect logs.

The whole structure is visible, so you can see where the config belongs.

Android #

Add the following configuration snippet to your other configuration in dynatrace.config.yaml and run flutter pub run dynatrace_flutter_plugin in the root of your Flutter project:

android:
  config: "
    dynatrace {
      configurations {
        defaultConfig {
          autoStart{
            ...
          }
          debug.agentLogging true
        }
      }
    }
  "
}

iOS #

Add the following configuration snippet to your other configuration in dynatrace.config.yaml and run flutter pub run dynatrace_flutter_plugin in the root of your Flutter project:

ios:
  config: "
  <key>DTXLogLevel</key>
  <string>ALL</string>
  "
}

Known issues #

  • OneAgent SDK version X does not match Dynatrace Android Gradle plugin version X: You've probably upgraded the Flutter package. Call flutter pub run dynatrace_flutter_plugin again so that the dependencies in the gradle are updated.

Dynatrace documentation #

The documentation for OneAgent for Android and iOS is available at the following locations:

Report a bug or open a support case #

For issues, open a support ticket at support.dynatrace.com and provide us with the following details:

1
likes
90
pub points
50%
popularity

The Dynatrace Flutter plugin helps auto-instrument your Flutter app with Dynatrace OneAgent for Android and iOS. It also provides an API to add manual instrumentation.

Homepage

Documentation

API reference

Uploader

flutter.dynatrace@gmail.com

License

unknown (LICENSE)

Dependencies

flutter, path, xml, yaml

More

Packages that depend on dynatrace_flutter_plugin