How to instrument a hybrid app

AppMon supports instrumenting Cordova based applications or applications that use WebViews to display HTML content. There are three components which can be used for hybrid application instrumentation: the mobile agent, the JavaScript agent and the JavaScript bridge. When instrumented with all of these, resulting visits can consist of user actions from the mobile agent (including the JavaScript bridge) and/or the JavaScript agent.

The mobile agent delivers device information and OS lifecycle events. The JavaScript agent gathers network actions. You can extend this behavior through the JavaScript bridge. The bridge lets you manually instrument your JavaScript code by calling mobile agent native functions.

Instrumentation

To instrument your Hybrid Application you can:

  • Use the Dynatrace-Cordova-Plugin, which supports Cordova based applications only, such as Ionic.
  • Include the files manually.

Use the Dynatrace-Cordova-Plugin

Install the Dynatrace-Cordova-Plugin in your Cordova based application. It automates each step you have to perform to successfully instrument your hybrid application. Click here to download the plugin and for installation instructions.

Include files manually

If you use hybrid platforms other than Cordova such as KonyOne, or don't want to instrument your Cordova based application using the plugin, you can instrument manually.

Not all of the steps for including files manually apply to other platforms. Some steps are not feasible if your hybrid application is not WebView based. For instance, Xamarin can only be instrumented by the Mobile Agent. The manual procedure lets you decide which components you want to include, but you may miss important actions or events if you leave a component out.

Mobile Agent: Use the mobile agent to instrument the native parts of your application. See Android agent setup and instrumentation or iOS agent setup and instrumentation for more Android and iOS Mobile Agent instrumentation information.

JavaScript Agent: Manually inject the JavaScript agent into your HTML5 content for example into index.html. The JavaScript agent detects the Ajax (XHR) calls.

JavaScript Bridge: Use the JavaScript bridge (Dynatrace.js) to manually create user actions in your JavaScript code. If you are using this component, be sure to also use the mobile agent. This is mandatory because the bridge calls the mobile agent to create user actions. The bridge does not work without the mobile agent.

The following sections detail each of these steps.

Step 1 - Mobile Agent

Important Android Auto Instrumentation Properties

Android Auto-Instrumentation is using a configuration file which contains different properties. There are several properties which are important for hybrid applications:

Key Key Type Description
DTXSetCookiesForDomain String For hybrid applications using the JavaScript agent or JavaScript bridge, cookies need to be set for each instrumented domain or server the application communicates with. You can specify domains, host or IP addresses. Domains (or sub domains) have to start with a dot. Separate the list elements with a comma.
DTXAllowFileCookies boolean The default value is false. Set to true to use file cookies.

Android WebView registration and AppMon startup

Note

Manual WebView registration and startup are only needed for manual instrumentation. Android Auto-Instrumentation performs these tasks automatically.

To instrument the JavaScript code in a WebView, register the WebView within the mobile agent native code by calling Dynatrace.registerWebView(WebView). If you have more than one WebView, you must register each single WebView instance. You must also include the Dynatrace.startup mobile agent call within the native code, and the Dynatrace.shutdown call if desired.

In Cordova-based applications, the WebView is created in the MainActivity which is automatically created by Cordova. The MainActivity is a CordovaActivity subclass and contains the calls to super.onCreate(savedInstanceState); and loadUrl(url) in the onCreate(savedInstanceState). After those two calls the WebView is initialized. Once initialized, instrument it by calling the Dynatrace.registerWebView(WebView) method.

The following example shows how the instrumentation may look:

public class MainActivity extends CordovaActivity {
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		..
		loadUrl(this.launchUrl);
	}

	@Override
	public void init() {
		super.init();
		Dynatrace.registerWebView((WebView)super.appView.getView());
		// For older version of Cordova use:
		// Dynatrace.registerWebView(super.appView);
	}
}

The loadUrl(url) function internally calls the init() method.

iOS WebView registration and AppMon startup

For iOS, the web view registration is automatic if the App is instrumented with the the mobile agent.

Step 2 - JavaScript Agent

There are several ways to manually inject the Agent. For hybrid applications, including the JavaScript agent code within the app and the WebViews is recommended and described in this section. See the Manual injection details section in JavaScript Agent for alternate ways to manually inject the JavaScript Agent, such as using the bootstrapped agent. The following steps describe how you configure the JavaScript Agent:

In the AppMon Client, Use the System Profile Preferences to edit System Profile settings for the app. Choose System Profile > <System Profile> > User Experience > <application>.

Scroll to the Web Applications section.

Under Ajax (XHR) detection and Additional packs, select the check boxes for each technology to be supported. For example, to support network calls within Ionic 2, select the AngularJS (Angular 2 requires initialization code) check box.

JavaScript agent configuration in AppMon client.

Note

Ionic 2 uses the Angular 2 framework supported by the JavaScript agent. However, you must insert the following initialization code everywhere you use Angular HTTP. This initialization code is not needed for Angular 1.

if(typeof dT_!='undefined' && dT_.initAngularNg){
	dT_.initAngularNg(http,Headers);
}

See Manual XHR framework instrumentation for more initialization code details.

In the Advanced Configuration section of the <application> tab, specify the path used by the JavaScript agent to communicate with the instrumented server in the Monitor Request Path field, as shown in the following.

Monitor Request Path (must include protocol; see resulting path below the entry field)
Monitor Request Path (must include protocol; see resulting path below the entry field)

Select the Send the Dynatrace monitor request to a foreign domain (CORS) check box, if the AppMon monitor request is going to a different domain.

If the instrumented web server delivering the Agent is at a separate address, specify it in the Agent Location field.

You can retrieve the initialization tag and it's contained code using the Server REST Interfaces API with https://AppMon-Server:8021/api/v1/profiles/systemprofile/applications/application/javascriptagent/initcode. The initcode dynamically generates the agent at application runtime and serves it based on the previously mentioned settings.

Use https://AppMon-Server:8021/api/v1/profiles/systemprofile/applications/application/javascriptagent to include the entire JavaScript agent code. When changing the JavaScript Agent version or configuration, ensure you download the agent again and update it if using the full agent code. Settings are based on agent filename, so don't change the agent name to prevent unintended behavior.

Step 3 - JavaScript Bridge

The mobile agent includes the JavaScript bridge file Javascript/Dynatrace.js, which can be loaded where applicable. The JavaScript functions mirror the native Dynatrace and DTXAction methods. See the corresponding native methods in Android Agent Setup and Instrumentation and iOS Agent Setup and Instrumentation for more information.

Return code definition

Return codes are available in addition to those defined for native methods. See the Android or iOS native method return codes for details.

Value Description
-3 Not supported on the running platform.

Basic instrumentation methods

Use the Dynatrace.js functions for JavaScript instrumentation, as described below.

enterAction(actionName)

Parameter Description
actionName The name assigned to the action to be created.
Return Value Description
Action identifier The identifier needed for subsequent operations on the newly created action.

Create a new action with the given name.

enterActionParentId(actionName, parentId)

Parameter Description
actionName The name assigned to the child action to be created.
parentId The identifier of the parent action.
Return Value Description
Action identifier The identifier needed for subsequent operations on the newly created child action.

Create a child action with the given name, using the specified parent action. leaveAction(actionId)

Parameter Description
actionId The identifier of the action to be closed
Return Value Description
DTX_CaptureOn DTX_CaptureOff DTX_ActionEnded DTX_Error_NotInitialized Refer to the Android or iOS native method return codes for details.

Close the action that has the given identifier. reportEvent(eventName, actionId)

Parameter Description
eventName The name assigned to the event to be reported.
actionId The identifier of the action to contain the event.
Return Value Description
DTX_CaptureOn DTX_CaptureOff DTX_InvalidParameter DTX_ActionEnded DTX_Error_NotInitialized Refer to the Android or iOS native method return codes for details.

Report an event in the context of the action that has the given identifier. reportValueInt(valueName, value, actionId) reportValueDouble(valueName, value, actionId) reportValueString(valueName, value, actionId)

Parameter Description
valueName The name assigned to the value to be reported.
value The integer, double, or string value.
actionId The identifier of the action to contain the value.
Return Value Description
DTX_CaptureOn DTX_CaptureOff DTX_Error_InvalidRange DTX_ActionEnded DTX_Error_NotInitialized DTX_Error_InvalidParameter Refer to the Android or iOS native method return codes for details.

Report an integer, double, or string value in the context of the action that has the given identifier.

reportErrorIntegerWithAction(errorName, errorValue, actionId) reportErrorStringWithAction(errorName, errorValue, actionId)

Parameter Description
errorName The name assigned to the error to be reported.
errorValue The integer or string (not supported on Android) value.
actionId The identifier of the action to contain the error.
Return Value Description
DTX_CaptureOn DTX_CaptureOff DTX_Error_InvalidParameter DTX_ActionEnded DTX_Error_NotInitialized DTX_ReportErrorOff Refer to the Android or iOS native method return codes for details.
-3 Not supported.

Report an integer or string error in the context of the action that has the given identifier.

reportErrorInteger(errorName, errorValue, actionId) reportErrorString(errorName, errorValue, actionId)

Parameter Description
errorName The name assigned to the error to be reported.
errorValue The integer or string (not supported on Android) value.
actionId The identifier of the action to contain the value.
Return Value Description
DTX_CaptureOn DTX_CaptureOff DTX_Error_InvalidParameter DTX_ActionEnded DTX_Error_NotInitialized DTX_ReportErrorOff Refer to the Android or iOS native method return codes for details.
-3 Not supported.

Report an integer or string error not in the context of an action.

setGpsLocation(longitude, latitude)

Parameter Description
longitude The location longitude, for example -82.937.
latitude The location latitude, for example 42.710.
Return Value Description
DTX_CaptureOn Successful.

Save the given GPS location for reporting along with the captured data.

flushEvents()

Send the collected data immediately.

startTaggingRequests(actionId)

Parameter Description
actionId The identifier of the action that contains web requests.

Signal that any web requests created while an action is open should be assigned to that action.

Return Value Description
DTX_CaptureOn DTX_CaptureOff DTX_Error_InvalidParameter DTX_ActionEnded DTX_Error_NotInitialized Refer to the Android or iOS native method return codes for details.

Debugging

Use the Dynatrace debugOn and debugOff JavaScript functions to turn debugging on or off.

Kony One

You must use Auto-Instrumentation for Android for KonyOne apps. Be sure to define the necessary instrumentation properties (for example, DTXNameUseValueOf=serviceID). If reporting the specific values, events, and actions are necessary, manually instrument the events by using the Kony Foreign Function Interface, and then apply Auto-Instrumentation on the resulting APK.

For example, to report a check-out amount:

// Android native code to report an event/value:

// DTXAction action = DTXAction.enterAction("Transaction Amount");
// action.reportValue("Total", 10.99);
// action.leaveAction();

// In Kony development studio create an FFI function and equivalent code:
 
package com.sample;
import com.dynatrace.android.agent.DTXAction;

public class DtIntegration {
	public DtIntergration() {}
 
	public static void reportTransAmount(String actionName, String eventName, double amount) {
		DTXAction action = Dynatrace.enterAction(actionName);
		action.reportValue(eventName, amount);
		action.leaveAction();
	}
}

// Invocation from javascript: DtIntegration.reportTransAmount("Transaction Amount", "Total", 10.99);

Run the resulting APK through Auto-Instrumentation for Android to implement this code.

Known issues

  • Android 2.3.x has a critical problem with the JavaScript interface. The issue is reported here: https://code.google.com/p/android/issues/detail?id=12987.
  • JavaScript Agent injection does not capture load resources for this release. Only XHRs made to your instrumented server are captured.