Flutter monitoring API

Note: Flutter monitoring is currently in open beta.

Instana Flutter agent API

The following section describes the usage of the Instana Flutter agent. Instana's Flutter agent can be used by using the InstanaAgent class methods explained as follows:

Setup

It's recommended to initialize Instana in initState() of app state class as early as possible:

static Future<void> setup({@required String key, @required String reportingUrl}) async

Parameters

Parameter
Description
key (String) Instana monitoring configuration key
reportingURL (String) URL pointing to the Instana instance to which to the send monitoring data to
options (SetupOptions, optional) Configuration options (such as collectionEnabled)

Example

@override
void initState() {
  super.initState();
  setupInstana();
}
Future<void> setupInstana() async {
    await InstanaAgent.setup(key: 'Your-Instana-Key', reportingUrl: 'Your-Instana-Reporting-URL', null);

    // Alternatively with configuration options
    var options = SetupOptions();
    options.collectionEnabled = false;
    await InstanaAgent.setup(key: 'Your-Instana-Key', reportingUrl: 'Your-Instana-Reporting-URL', options: options);
}

Supported Dart and Flutter version

Currently, all Dart SDK with version 2.12.0 or higher and all Flutter versions beginning from 1.20.0 is supported.

Enabled or Disable Collection

You can enable or disable the data collection at any time during the runtime. This enables the delayed start of the data collection (e.g. after user consent).

| <div style="width:230px">Property</div>                              | Description                               |

| --------------------------------- | --------------------------------------------- | | setCollectionEnabled (Bool) | Flag to enable or disable data collection |

Example

InstanaAgent.setCollectionEnabled(true);

Error handling

All of the agent's interfaces return an asynchronous Future. Errors are wrapped in an exception of the PlatformException type.

You are advised to follow the common error-handling techniques for Futures and to log possible errors.

For example:

InstanaAgent.setup(key: 'KEY', reportingUrl: 'REPORTING_URL')
    .catchError((e) => 
            log("Captured PlatformException during Instana setup: $e")
        );

Or similarly in async functions:

try {
  var result = await InstanaAgent.setup(key: 'KEY', reportingUrl: 'REPORTING_URL');
} catch (e) {
  log("Captured PlatformException during Instana setup: $e");
}

Session Identifier

Each Instana agent instance has a unique session identifier that you can use for other purposes in your app.

static Future<String> getSessionID() async

Return

Future<String>

Example

var sessionID = await Instana.getSessionID();

Manual HTTP monitoring

With Flutter HTTP sessions must be be captured manually. Please refer to the documentation specific to each platform for more details.

static Future<Marker> startCapture({@required String url, @required String method, String viewName}) async

Parameters

Parameter
Description
url (URL) The URL to capture.
method (String) The HTTP method of the request.
viewName (String, optional) Optional name of the visible view related to this request

Return

Future<Marker>

Example

final url = 'http://www.example.com/album'
var marker = await InstanaAgent.startCapture(url: url, method: 'GET', viewName: 'Album');

Set response details

Once the reponse has been finished you can set the response size and the http response status code on the Marker.

Set response size

marker.responseSizeHeader = 50; // Size of the HTTP header
marker.responseSizeBody = 1000; // Size of the http body
marker.responseSizeBodyDecoded = 2400; // // Size of the decoded http body

Set http response status code

marker.responseStatusCode = 200; // The http status code 

Set response headers

Note that the headers that are provided here will be filtered by Instana based on your setCaptureHeaders setting.

marker.responseHeaders = response.headers;

Set Instana's backend tracing ID

Identifier to create a backend trace for the http request & response. This identifier is provided in the http header field server-timing like: server-timing: intid;desc=be01a91da80e33.

marker.backendTracingID = 'be01a91da80e33'; // the backend tracing id

For the sake of convenience, we provide you with the BackendTracingIDParser helper class which will you can use to extract a response's backend tracing ID:

var Map<String,String> headers = getResponseHeaders(); // You need to get this map from your `response` object
var backendTracingID = BackendTracingIDParser.fromHeadersMap(headers);

Set error message

For failing http request you can set an arbitrary error message.

marker.errorMessage = 'Download of album failed'; // the backend tracing id

Finish HTTP Capture

After setting the response details you must call finish on the Marker to finalize the capture.

marker.finish();

Cancel HTTP Capture

You can also cancel pending Marker

marker.cancel();

Views

Instana can segment mobile app insights by logical views. To do so, set the view name via the InstanaAgent.setView(String) method. The view will then be associated to all monitored beacons until the view changes once setView is called again.

We recommend not to use technical or generic names like the Class (e.g. WebViewActivity) to define views. We recommend the usage of readable names for views, for example product detail page or payment selection. Focusing on what users are experience will allow team members without intimate knowledge of the codebase to understand the insights provided.

Note: InstanaAgent.setView(String) should be called when a screen is presented to the user, rather than when a screen is created (as in a Fragment which could be created once but shown multiple times). Setting the view name will also enable Instana to track page transitions in addition to page loads.

static Future<void> setView(String name) async

Parameters

Parameter
Description
name (String) The name of the view.

Example

await InstanaAgent.setView('Webview: FitBit authorization');

Identifying users

User-specific information can optionally be sent with data transmitted to Instana. This information can then be used to unlock additional capabilities such as:

  • calculate the number of users affected by errors,
  • to filter data for specific users and
  • to see which user initiated a view change or HTTP request.

By default, Instana will not associate any user-identifiable information to beacons. Please be aware of the respective data protection laws when choosing to do so. We generally recommend identification of users via a user ID. For Instana this is a completely transparent String that is only used to calculate certain metrics. userName and userEmail can also be used to have access to more filters and a more pleasant presentation of user information.

In cases in which you are handling anonymous users and thus don't have access to user IDs you could alternatively use session IDs. Session IDs are not as helpful as user IDs when filtering data but they are a good indicator to calculate affected/unique user metrics. We recommend setting a user name such as Anonymous to have a clear differentiation between authenticated and unauthenticated users. Session IDs can be sensitive data (depending on the framework/platform used). Please consider hashing session IDs to avoid transmitting data to Instana that can grant access.

It is important to note that data already transmitted to Instana's server cannot be retroactively updated. For this reason it is important to call this API as early as possible in the app launch process.

static Future<void> setUserID(String userID) async
static Future<void> setUserName(String name) async
static Future<void> setUserEmail(String email) async

Parameters

Parameter
Description
id (String) An identifier for the user.
email (String) The user's email address.
name (String) The user's name.

Example

@override
void initState() {
  super.initState();

  await InstanaAgent.setup(key: 'Your-Instana-Key', reportingUrl: 'Your-Instana-Reporting-URL');
  await InstanaAgent.setUserID('1234567890');
  await InstanaAgent.setUserName('John Appleseed');
  await InstanaAgent.setUserEmail('john@appleseed.com');
}

Metadata

Arbitrary meta data can optionally be attached to all data transmitted to Instana. Consider using this to track UI configuration values, settings, feature flags… any additional context that might be useful for analysis.

Note: we currently support up to 50 meta key/value pairs.

static Future<void> setMeta({@required String key, @required String value}) async

Parameters

Parameter
Description
value (String) The value of the key-value pair you want to add as meta data.
key (String) The key of the key-value pair you want to add as meta data.

Example

await InstanaAgent.setMeta(key: 'exampleKey', value: 'Some Value');

Report custom events

Custom events enable reporting about non-standard activities, important interactions and custom timings to Instana. This can be especially helpful when analyzing uncaught errors (breadcrumbs) and to track additional performance metrics.

static Future<void> reportEvent({@required String name, EventOptions options}) async

Parameters

Parameter
Description
name (String) Defines what kind of event has happened in your app that should result in the transmission of a custom beacon.
options (EventOptions, optional) A timestamp in milliseconds since Epoch indicating at which time the event started. Falls back to now() - duration when not defined.

EventOptions

Parameter
Description
startTime (int) A timestamp in milliseconds since Epoch indicating at which time the event started. Falls back to now() - duration when not defined.
duration (int) The duration in milliseconds of how long the event lasted. Default is zero
viewName (String) You can pass a String to group the request to a view. If you send explicitly nil, the viewName will be ignored. Alternatively you can leave out the parameter viewName to use the current view name you did set in setView(String))
meta (Map<String, String>) A JavaScript object with string values which can be used to send metadata to Instana just for this singular event. In contrast to the usage of the metadata API, this metadata is not included in subsequent beacons.
backendTracingID (String) Identifier to create a backend trace for this event.

Example

await InstanaAgent.reportEvent(
      name: 'advancedCustomEvent',
      options: EventOptions()
        ..viewName = 'customViewName'
        ..startTime = DateTime.now().millisecondsSinceEpoch
        ..duration = 3 * 1000
        ..meta = {
          'customKey1': 'customValue1',
          'customKey2': 'customValue2'
        });

Capture HTTP headers

Optionally, the Instana agent can capture the HTTP headers of every tracked request/response.

A list of regex patterns can be defined to determine which headers will be captured.

If the same header name is present in both a request and its response, only the response's header value will be kept.

static Future<void> setCaptureHeaders({@required List<String> regex}) async

Example

InstanaAgent.setCaptureHeaders(regex: [
      'x-ratelimit-limit',
      'x-ratelimit-remaining',
      'x-ratelimit-reset'
    ]);

Redact URL Query parameters

Query parameters in collected URLs might contain sensitive data. Therefore, the Instana agent supports the specification of regex patterns for query parameter keys whose values need to be redacted. Any value that needs to be redacted will be replaced with the string <redacted>. The redaction happens within the Instana agent before the agent reports to the Instana server. Consequently, secrets will not reach the Instana servers for processing and will not be available for analysis in the Instana UI or retrieval by using Instana API.

By default, the Instana agent is configured with a list of three regex patterns to automatically redact query parameter values for the keys "password", "key" and "secret".

static Future<void> redactHTTPQuery({@required List<String> regex}) async

Example

InstanaAgent.redactHTTPQuery(regex: [
      'user',
      'id',
      'key'
    ]);

Native HTTP monitoring

Though by default HTTP monitoring is disabled, you can capture the HTTP calls made inside the iOS platform (in Swift or Objective C language) and Android platform (in Kotlin or Java language).

Example

@override
void initState() {
  super.initState();
  setupInstana();
}
Future<void> setupInstana() async {
  var options = SetupOptions(captureNativeHttp: true);
  await InstanaAgent.setup(key: 'Your-Instana-Key', reportingUrl: 'Your-Instana-Reporting-URL', options: options);
  if (!ret) {
    // Error handling here
    if (kDebugMode) {
      print("InstanaAgent setup failed");
    }
  }
}

Automatic HTTP monitoring

HTTP sessions made in the Dart language can be captured automatically. Set your HttpOverrides.global property as shown in the following example:

Example

@override
void main() {
  HttpOverrides.global = InstanaHttpOverrides();
  runApp(const MyApp());
}

If you already have your own version of HttpOverrides for other purposes, then merge the InstanaHttpOverrides class function to your class and maintain the combined class yourself. Combining multiple HttpOverrides causes an error. You can also analyze the InstanaHttpOverrides class, and create your HttpOverrides class similar to InstanaHttpOverrides class instead of using the InstanaHttpOverrides() function.

Slow sending mode

The slow sending mode feature is disabled by default. If required, you can enable this feature.

By default, if a beacon sending fails, the Instana agent tries to resend the beacon until the sending is successful. This doesn't work well with some cellular networks. By enabling the slow sending mode feature, the beacon sending interval is changed to the time value that is assigned to the slowSendIntervalMillis parameter. Each beacon sending consists of only one beacon instead of a batch (maximum 100 beacons in a batch). The Instana agent stays in slow sending mode until one beacon is sent successfully.

The valid time range for slowSendIntervalMillis is 2–3600 seconds.

Example

@override
void initState() {
  super.initState();
  setupInstana();
}
Future<void> setupInstana() async {
  var options = SetupOptions();
  options.slowSendInterval = 60.0;
  await InstanaAgent.setup(key: 'Your-Instana-Key', reportingUrl: 'Your-Instana-Reporting-URL', options: options);
  if (!ret) {
    // Error handling here
    if (kDebugMode) {
      print("InstanaAgent setup failed");
    }
  }
}