JavaScript ADK and JavaScript Ajax ADK

The Javascript ADK provides functions to extend the default behavior of the JavaScript Agent. You can use this ADK to start custom user actions, report events, or extend third-party content detection on a web page.

Both the web server and the Java Agent can handle user experience monitoring performed by the JavaScript Agent, extensible with the JavaScript ADK. To get the data, the User Experience sensor must be placed and active for the web server or the application server.

Requirements

For AppMon 6.5 and later, the JavaScript ADK is bundled with the JavaScript Agent. So if the agent is present on the page, the ADK functionality is available. Thus, the only requirement is to ensure your webpage is injected either automatically or manually.

Asynchronous injection

Enabling asynchronous injection for the JavaScript Agent makes the ADK available as soon as the rest of the code is. Use caution when attempting to use ADK functionality early in the webpage's lifecycle.

You can verify that the JavaScript Agent is injected by checking the window.dT_ property:

if(typeof window.dT_!='undefined'){
  //JavaScript agent is present
}

The namespace dynaTrace is available, which provides all ADK functions. See the Javadoc included in the samples project (see below) for a list of functions at http://<serveraddress>/samples/doc/index.html.

JavaScript ADK samples project

A samples project is available for download to help understand use cases listed below for the JavaScript ADK.

Download and unzip the package, and place the files from the samples directory on a web server where the JavaScript Agent is injected.

If, for example, you place the files in the htdocs/samples directory of an Apache server, the samples are accessible from http://<serveraddress>/samples/index.html.

If the JavaScript Agent is injected on the server, the index page appears as shown in the figure.

JavaScript ADK Index Page
JavaScript ADK Index Page

Reporting events, warnings, errors, strings, and values

The JavaScript ADK provides functions to report information to the Server. This information is displayed in the User Action PurePaths dashlet:

  • reportEvent(msg)
  • reportWarning(warning)
  • reportError(error)
  • reportValue(key, value)
  • reportString(key, string)

Example: Execute Report Functions (/report/report.html)

This example provides buttons that execute report functions. The resulting user actions are listed in the dashlet as shown in the figure.

User Actions for report function
User Actions for report function

Example: Call Report Functions (/report/report2.html)

This example calls the report functions in an onload event handler. The messages are automatically appended to the currently running onload action. The resulting user actions are listed in the dashlet as shown in the figure.

User Actions for onload event handler
User Actions for onload event handler

Visit tagging

The JavaScript ADK enables you to tag your visits with any value you want. Use tagVisit(anystring) to tag the current visit with the specified value.

Example: Tag Visits (/visittagging/report.html)

This example tags a visit with the value of an input field. Enter any string and click Tag Visit. The function uses reportString with the special key dt_visittag. The server handles this special request by tagging a non-tagged visit with the provided string.

Tagged visit
Tagged visit

End visit

Example: End Visit (/endVisit/endvisit.html)

By default a visit ends after a configurable inactivity time (default is 30 min.). Using the ADK, a visit can be ended forcibly, foe example when a user logs out from an application.

Simply call dynaTrace.endVisit() and the visit ends without waiting for the inactivity time. For correlation purposes the visit shows as active in the client for about three minutes, but actions sent after dynaTrace.endVisit() are added to a new visit.

Set the application version

The application's version can be manually set on the visit using the setAppVersion function.

Call dynaTrace.setAppVersion(version) once the ADK loads, where the version String is what you want to set for each visit. This overrides the configuration setting specified in the System Profile's UEM section.

Starting custom actions

The JavaScript ADK includes functions to start and stop custom user actions.

  • dynaTrace.enterAction(name,type,startTime,parentAction) starts a new action. If no parentAction is provided, a new root action is started. The function returns the name of the new action. This name can differ from the name given as a parameter, when multiple actions with the same name happen.
  • dynaTrace.leaveAction(actionName) stops the action with the specified name.

Example: Start and Stop an Action Within a Page (/actions/simpleaction.html)

This example provides a button that starts and stops a simple action in an onclick handler. The User Action is shown in the following figure.

onclick Handler User Action
onclick Handler User Action

Example: Start and Stop an Action, with Web Requests (/actions/advancedaction.html)

This example provides a button that loads an image dynamically. It calls enterAction before loading and leaveAction when loading is finished. The web request for the image is automatically added to the User Action in the PurePath, as shown in the following figure.

User Action with web request
User Action with web request

Example: Create an Action with a Subaction (/actions/subaction.html)

This example provides a button that creates an action with a subaction. The User Action is shown in the following figure.

User Action with Subaction

Example: Start an Action That Triggers a Page Change (/actions/pagechangeaction.html)

This example starts an action that triggers a page change, with a setTimeout call five seconds after onload. This construction is useful when no user input can be associated with an action, so that the automatic user action detection does not work. This situation can happen when an action is triggered, for example, by setTimeout or setInterval. The User Action is shown in the following figure.

Page change action
Page change action

Example: Override the Default Action Detection (/action/userinputdropdown.html)

Sometimes it is necessary to override the default action detection. In this example, the onchange event of a dropdown list is modified so that the newly selected value is added to the action name.

  1. The default action detection is disabled by dynaTrace.setAutomaticActionDetection(false);.
  2. A custom action is started. The action name contains the selected dropdown value: dynaTrace.enterAction('Select value '+value, 'select',null,null);.

The User Action is shown in the following figure.

User Action with override
User Action with override

Extending support for third-party content

The JavaScript Agent supports detection of third-party resources. The automatic detection works for images and scripts. Use the following functions to enable automatic detection of additional resources:

  • dynaTrace.startThirdParty(type,url) indicates the start of a third-party resource. The type can be i (image), s (script) or c (custom resource).
  • dynaTrace.stopThirdParty(url,success,start,stop) indicates when the third-party resource is loaded.

Example: Add Custom CSS Files (/thirdparty/simple.html)

This example demonstrates how to add custom resources. It adds a CSS file where start and stop times are set automatically, and another CSS file where start and stop time are set explicitly. The User Action is shown in the following figure.

Custom resources
Custom resources

Example: Detect When a CSS File Is Loaded (/thirdparty/advanced.html)

This example demonstrates how to detect the successful loading of a CSS file. It dynamically adds a link tag for the CSS, and then checks whether the number of styles is greater than zero, in 20-millisecond intervals. The PurePath is shown in the following figure.

CSS file detected
CSS file detected

Reporting playback of media streams

The JavaScript ADK provides a function to report information to the AppMon Server about the playback of media streams.

addStreamingNode(source, duration, userTriggered, watchedCompletely, maxPlayTime, playTime, bufferingCount, bufferingTime, type)

This function provides data for media streams that cannot be collected by the Streaming JavaScript plugin because of that plugin's reliance on HTML5 media tags. If your streams are embedded using, for example, Adobe Flash technology, the Streaming plugin cannot detect them. If you can collect the same data by using JavaScript or a plugin API that the media player offers, then you can leverage this function to send similar data to the AppMon Server.

Parameters

source URI of the media stream.
duration Duration in seconds of the media stream.
logger_name Name of the logger.
userTriggered true if the user presses a play button to start playback of the media stream; false if the video playback starts automatically, for example as soon as the page load completes.
watchedCompletely true if the user watches the video completely and playback ended automatically, false if the user stops the media stream or leaves the page before playback completes.
maxPlayTime The farthest second of the media stream that was played back.
playTime Total time (in seconds) the user spent consuming the media stream.
bufferingCount Number of times the playback was interrupted by rebuffer events.
bufferingTime Total duration (in seconds) of the rebuffer events.
type _video_ for video streams; _audio_ for audio streams

Example: Report Playback Information (/streaming/streaming.html)

This example uses the JavaScript API of the JWPlayer (http://www.longtailvideo.com/jw-player), a Flash based media player, to collect information about the playback of a media streams and report this information to the AppMon Server using the JavaScript ADK.

The resulting PurePaths are displayed in the User Action PurePaths dashlet.

Video stream PurePath
Video stream PurePath

Capturing Custom XHR calls

Example: Capture Custom XHR Calls (/xhrapi/simple.html)

This example demonstrates how to instrument a simple XMLHttpRequest in a page. Clicking the Load Data button performs an Ajax call to the URL ajax.txt is performed. The result displays in the div with ID resultDiv. The loadData function starts an XHR call through ActiveXObject in Internet Explorer and through XMLHttpRequest in all other browsers.

The following code tells the JavaScript Agent that an XHR action starts:

var action=dynaTrace.enterXhrAction();

This code tells the JavaScript Agent that the XHR action ends in the onreadystatechange callback:

dynaTrace.leaveXhrAction(action);

The JavaScript Agent automatically detects the user input that triggers the action. The generated User Action is shown in the following figure.

User Action generated by XHR call
User Action generated by XHR call

Example: Capture Cascading Custom XHR Calls (/xhrapi/cascading.html)

When an XHR call triggers a new XHR in the onreadystatechange callback, this XHR action should be added as a subaction to the first action as shown in the following code.

dynaTrace.enterXhrCallback(action); //callback code dynaTrace.leaveXhrCallback(action);

This code tells the JavaScript Agent that no extra XHR action is created when an XHR request is started within this callback. Clicking the Load Data button in the example results in the User Action shown in the following figure. There is only one Ajax action, but two requests for ajax.txt.

Cascading custom XHR calls
Cascading custom XHR calls

Example: Capture Dynamic Call to a JavaScript File (/xhrapi/scripttag.html)

Sometimes Ajax calls are performed not through XMLHttpRequest, but by dynamically appending script tags to the page. When script tags are used, the resulting script file usually tries to call a callback function to handle the result when the call is finished.

In the example, the loadData function adds a script tag to the head tag that loads the script file ajax.js. This is usually dynamically generated on the server side by a mechanism such as PHP, JSP, or servlet. The ajax.js file calls the globally defined function showResult when it is loaded. Instrumenting this call requires adding two calls to the JavaScript Agent:

In loadData:

action=dynaTrace.enterXhrAction();

In the showResult callback function:

dynaTrace.leaveXhrAction(action);

If the callback function can also start new Ajax calls, you should add the enterXhrCallback and leaveXhrCallback calls to the callback function. Clicking the Load Data button results in the User Action shown in the figure.

Dynamic call to a JavaScript file
Dynamic call to a JavaScript file

Capturing frame loads during an XHR callback

Example: Capture frame loading during an XHR callback (/xhrapi/frameloadingduringxhr.html)

This example demonstrates how to extend an XHR action to include the loading of a frame action that occurs during an XHR callback function. Without the ADK, the XHR action finishes and causes the monitor signal to be sent before the frame gets a chance to start loading. As a result, two separate actions are created, when just one would be expected. The ADK provides the ability to keep these actions unified.

Make a call to enterXhrAction before making the AJAX request, add listeners to the onload event of the frame's element, and then call leaveXhrAction here, passing the return value of the corresponding enterXhrAction call.

var xhrAction = dynaTrace.enterXhrAction("frame load xhr");
var xhr = window.XMLHttpRequest? new XMLHttpRequest(): new ActiveXObject("microsoft.xmlhttp");
xhr.open('GET', "ajax.txt", false);
xhr.onreadystatechange = function(){
	if(xhr.readyState == 4){
		var e = document.createElement("IFRAME");
		e.src = "framecontent.html";
		document.body.appendChild(e);
		if (e.addEventListener) {
			e.addEventListener("load", frameLoadedHandler, false);
		} else if (e.attachEvent) {
			e.attachEvent("onload", frameLoadedHandler);
		}
	}
}
xhr.send(null);
 
function frameLoadedHandler() {
	dynaTrace.leaveXhrAction(xhrAction);
}

After clicking the Load a Frame button that executes the preceding code, the structure should appear like this in the Client:

Adding custom user input

Example: Add Custom User Input for Automatic Action Detection (/xhrapi/userinput.html)

This example demonstrates how to add custom user input that is used by automatic action detection. When an Ajax call is started or a page change is triggered, the automatic action detection checks whether user input is currently active. If it finds active user input, it creates a User Action.

The example page contains an HTML input text box that triggers an Ajax call through jQuery. JQuery is instrumented by the JavaScript Agent by default, so you do not need to consider XHR wrapping for this example.

The Ajax call is only performed when 800 milliseconds elapses with no key pressed by the user. This delay is common for autosuggest implementations, to avoid sending XHRs when the user is still typing.

When the Ajax call is performed, no user input is active, so the call beginUserInput tells the JavaScript Agent that there is user input:

var inp=document.getElementById('inp'); var value=inp.value; var uinp=dynaTrace.beginUserInput(inp,'lookup "'+value+'"',null);

The call endUserInput ends the user input :

dynaTrace.endUserInput(uinp);

Entering the text test results in the User Action shown in the figure.

User input for automatic action detection
User input for automatic action detection

Handling framework onload behavior

Many Ajax frameworks start actions, including XHR calls and asynchronous operations, in onload handlers. Some of these actions finish after the onload event of the browser is triggered. Because these actions all belong to the onload event of the browser, it is possible to extend the onload action by using the API functions.

  • signalOnLoadStart indicates the start of onload. It can be called to indicate when onload of a framework starts.
  • incrementOnLoadEndMarkers is tells the JavaScript Agent that the end of the onload action is indicated with signalOnLoadEnd. For every call to incrementOnLoadEndMarkers, signalOnLoadEnd has to be called.
  • signalOnLoadEnd indicates that an onload end was reached. A framework can have more than one signalOnLoadEnd. The last one ends the onload action.

No new actions are created during onload. All web requests are correlated to the onload action.

Example: Extend onload Handling

The example shows how to extend the onload action. It starts an XHR call in the browser's onload callback and ends the onload action in the callback of the XHR.

The resulting PurePath is shown in the figure.

Extended onload handling
Extended onload handling

Handling redirects after the onload event

Sometimes a page may trigger a redirect after it has finished loading. If the JSAgent has time to finish processing and sends the monitor signal before the page actually begins redirecting, this appears as two separate actions when you would expect the monitor signal to be a sub-action of the first. This almost always happens when using the meta tag <meta HTTP-EQUIV="REFRESH" content="0; url=redirectedpage.html"></meta> for URL redirection, especially if the timer from "content=num" is set to a large value.

To force the signal to wait for another onload, you can call the ADK's incrementOnLoadEndMarkers() function immediately after loading the ADK script. It properly sets the monitor signal as a source action on the next page.

Setting custom metadata

Example: Custom metadata (/metadata/metadata.html)

Metadata can also be set also by the ADK's setMetaData(name,value) function. Any data set using this function is added to any subsequent actions on the same page, along with any normally detected metadata configured in the system profile's UEM settings.

$("#clickme").on("click", function() {
	var val = $("#md").val();
	dynaTrace.setMetaData("customValue at " + Date.now(),val);
});

Using the JavaScript ADK for Flash and Silverlight applications

Technologies like Adobe Flash and Microsoft Silverlight are often used for implementing complex user interfaces, animation, or video playback. Although AppMon UEM cannot automatically instrument these technologies, it provides mechanisms for these technologies to interact with the web page in which they are embedded. These mechanisms make it possible to call the JavaScript functions of the AppMon JavaScript ADK and make the technologies accessible for AppMon UEM.

To instrument a Flash or Silverlight component, include the sample project's utility classes (see below) in your Flash or Silverlight project. Similar to the Introduction for JavaScript code, the ADK classes for Flash and Silverlight are also based on actions. The utility classes provide similar methods.

Important

To correlate the defined actions to any web requests belonging to that action, it is necessary to use the utility class to prepare these web requests by adding the header x-dtReferer. This head is required by the AppMon correlation engine.

Using the ActionScript class dynaTraceFlashAdk.as

This ActionScript class contains all functions of the JavaScript ADK that delegate to the JavaScript ADK, plus a few utility functions that simplify the tagging of web requests for the correlation engine.

The following code example shows how to use the utility class:

private var action:String;

//create instrumentation object for ActionScript class
private var dynaTraceAdk:DynaTraceFlashAdk = new DynaTraceFlashAdk();
[...] protected function buttonClickHandler(event:MouseEvent):void

{
  var url:String = "ajax.jsp";
  // create a new action string for the performed click event
  action = dynaTraceAdk.enterAction("Click on Button", "click");
  urlLoader = new URLLoader();
  var request:URLRequest = new URLRequest();
  request.url = url;

  //prepares the URLRequest by adding a custom header "x-dtReferer" in order to correlate the request to the action
  request = dynatraceAdk.prepareURLRequest(request);
  urlLoader.addEventListener(Event.COMPLETE, completeLoadContent);
  try   
  {
    urlLoader.load(request);
  }
    catch (error:Error)
  {
    //if an error occurred, report to dynaTrace server
    dynaTraceAdk.reportError("Error during load of image");
  }
}
protected function completeLoadContent(event:Event):void
{
  [...]
  // mark action as completed dynatraceAdk.leaveAction(action); [...]
}
[...]

Using class DynaTrace.cs for Silverlight applications

This C# class is similar to the ActionScript utility. It also contains delegates for the JavaScript Agent ADK functions and some utilities for tagging Web requests. The following code sample shows how to use the class:

private string action;
// create the instrumentation object for SilverLight private JavaScriptAdk
javaScriptAdk = new JavaScriptAdk();
[...]
private void button1_Click(object sender, RoutedEventArgs e)
{
  WebClient client = new WebClient();
  // starts a new action
  javaScriptAdk.enterAction("Click on button","click");
  // prepares the web request by adding the custom header "x-dtReferer" in order to correlate the request to the action
  javaScriptAdk.PrepareWebClient(client);
  client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(complete);
  client.DownloadStringAsync(new Uri("ajax.jsp"));
}
private void complete(object sender, DownloadStringCompletedEventArgs args)
{
  if (args.Error != null)
  {
    //if an error occurred, report to dynaTrace server
    javaScriptAdk.reportError(args.Error);
  }
  // mark action as completed javaScriptAdk.leaveAction(action);
}
[...]

In Silverlight versions earlier than version 4, cookies were not automatically set on WebClient and HttpWebRequest objects. For these earlier versions, you have to copy cookies onto the request objects. This is also done in the PrepareWebClient and PrepareWebRequest methods.

Instrumentation result

After instrumenting your Flash or Silverlight application, you should be able to retrieve PageAction PurePaths, as shown in the following figure.

PageAction PurePath
PageAction PurePath