Dynatrace 6.3 Documentation

Other Doc Versions & KB

Skip to end of metadata
Go to start of metadata

Overview

The JavaScript Agent is a small JavaScript script that can be automatically injected into web pages (of mime type text/html) via Java or Web Server Agents – or manually at design time if not otherwise possible.

Agent Injection

Automatic Injection

Here is a sample tag automatically injected by the Agent as first of script tags in <head> at delivery of the web page – with settings according to the configuration in <System Profile> settings > User Experience vertical tab:

<script type="text/javascript" src="/dtagent630_db3_1305.js" data-dtconfig="rid=RID_4261487263"></script>

Quick dissection:
rid is the Dynatrace-internal request ID.
src:

  • dtagent is the JavaScript Agent Name configured in <System Profile> > User Experience vertical tab > Global Settings horizontal tab.
  • 630 is the Dynatrace Agent version. (major, minor, revision)
    The revision (here 0) has been added as of 6.2, because beginning with that version there may be new features on the revision level. (as opposed to just bug fixes on the build level)
    1305 is the Agent build number, untypically separated from the other version part.
  • db3 in src is the so called feature hash, telling what is captured by the Agent and data-dtconfig could contain further settings. See Configuration below.

Manual Injection Quick Overview

If the preferable auto-injection is not possible (e.g. some HTML / CSS / JS app) you need to put the tag manually at design time – as first script tag in <head> –  to bootstrap the Agent, take the configuration from the <System Profile> > User Experience vertical tab and monitor client-side data.

The <System Profile> > User Experience vertical tab > Manual Injection sample tag (<script src='/dtagent_bootstrap.js'></script>) is dependent on the content of JavaScript Agent > Agent Location. (defaults to "/" – root directory of the web / app server providing the Agent)

In the case of an app the tag will need to be an absolute address1) of the format

<script src='http://<instrumentedWebOrAppServer>[/path]/dtagent_bootstrap.js'></script>

1) An app can be anywhere on a different machine, independent of / not relative to a server serving a page

Also, if the server providing the Agent and the one getting the monitoring data are different (domains), you must set the <System Profile> > User Experience vertical tab > JavaScript Agent > Monitor Request Path and check CORS.
And you can / must set the injection type (auto (default) or manual) per <System Profile> > Agent Group / tier in Sensor Configuration > User Experience sensor > Properties.

For more (background) info see Manual Injection Details.

Analysis Performed by the JS Agent

  • Detection of page loads
  • Detection of user actions: A user action can be a page load or an Ajax call that the user initiates by a mouse click, key press, etc. Cascading calls are correlated into one single user action, for example a page load that performs several Ajax calls during load.
  • Browser errors
  • The client's bandwidth

See details about features and configuration below.

The JavaScript Agent analyzes the above browser and user behavior on the client side and captures actions if the corresponding event handler is registered.
It sends this information to the instrumented web server2) via several parameters in the monitor signal / simple XHR / Ajax request.
2) By default named dynaTraceMonitor – resulting in a path relative to the instrumented server. Set the two items in <System Profile> > User Experience vertical tab. Set the

  • monitor request name in  > Global Settings horizontal tab.
  • monitor request path in > <applicationName> horizontal tab.

By default the signal is sent five seconds after a page was successfully loaded or an Ajax action is finished. If a user navigates to another page before the five seconds are over, the signal is sent immediately (beforeunload or unload event).
If the information is too long for one signal request (for example, IE limits URLs to 2048 characters), the signal is split into multiple parts and sent with separate XHRs.

Action Name Detection

The JavaScript Agent tries to find a meaningful name for an action. To do this, it checks several properties of the HTML element (button, link, etc.) that triggers the action. (inner HTML, caption, hint, etc.)
It also tries to get the caption if there is a more complex HTML structure with multiple nested tags.

Set Action Name with Custom Attribute data-dtName

If the standard action name detection does not suffice you can set the custom attribute data-dtName within the HTML tags and use it as a caption, e.g.

<label for="txtFirstname">Firstname</label> <input data-dtName="Firstname Text Input" type="text" value="firstname" name="firstname" title="Firstname" id="txtFirstname" />

The above leads to the following caption:

click on "Firstname Text Input"

Resolving Captions for Actions

As mentioned above, there are several mechanisms how the JavaScript Agent decides which name fits an action best.
It starts with the innermost HTML node that's clicked (e.g. a button, image tag, link...) and checks the following things (Mind the precedence!):

  1. attribute named data-dtName
  2. nodeName (e.g. image, anchor, input, ...), returns if html, body or head tag or the document element was found
  3. innerText / textContent

If none of these return any reasonable result, the Agent starts a recursive algorithm that checks different things depending on the nodeName of the currently checked HTML node. If nothing is found, the parent node is checked.

Configuration

The script tag that is injected depends on the application configuration set in <System Profile> - User Experience vertical tab, generically:

<script type="text/javascript" src="/dtagent<AgentMajorMinorVersionAndRevision>_<featurehash>_<AgentBuildNr>.js" data-dtconfig="<configparams>"></script>

Dissection:

  • <featurehash>: Set of characters that identifies which Agent modules to include and activate.
    When only the basic Agent is activated, the feature hash is empty resulting in two adjacent underscores in dtagent<ver>__<build>.js.
    A set of modules is delivered with Dynatrace by default, but you can add your own.
    Feature hashes of the included modules:
    • a: Action capturing
    • b: Bandwidth detection
    • 2: Third-party sending module ***
    • 3: Third-party content detection
    • d: Dojo support
    • e: ExtJS support *
    • g: AngularJS support
    • i: ICEfaces support
    • j: jQuery support
    • m: mooTools support
    • n: W3C Navigation Timings
    • o: Prototype support
    • p: Perceived Render Time
    • q: As of 6.2: Error detection
    • r: W3C Resource Timings
    • s: Streaming Media
    • t: Timed Action support *
    • v: ActiveXObject detection **
    • x: Basic XMLHttpRequest detection **
    • z: Gomez Page ID integration
  • <configparams>: Set of configuration parameters / properties in the format key=value[,value]. The parameters are separated by pipes (|).

* Some ExtJs-Functions use deferred callbacks when they send XHRs. Dynatrace does not capture these requests because it can't create a link to a user action. (e.g. form submits) To avoid this, activate the Timed Action support. It extends user actions to track deferred functions.

** As of 6.1 the support for ActiveXObjects (required by IE 6, supported by IE 7 and later) has been split from the basic XMLHttpRequest module to reduce file size and performance overhead. This module is only needed if the instrumented application utilizes ActiveXObjects to send requests from the JavaScript side that have to be captured. Every Dynatrace supported browser is capable of XMLHttpRequests, but not Internet Explorer 6, therefore most applications only need basic XMLHttpRequest detection. In case of uncertainty about utilization of ActiveXObjects, both modules can be enabled.

*** The third-party sending module gets automatically activated if either third-party content detection or W3C resource timings are enabled.
Ext.FormPanel is a known ExtJs function that must have Timed Action (t) support.

Here is a configuration example with activated Dojo and jQuery JavaScript packs and bandwidth check set to every 10 minutes (600 seconds):

<script type="text/javascript" src="/dtagent630_dj_1305.js" data-dtconfig="bandwidth=600"></script>

Automatic Injection Agent Tag Placement Rules

The following set of rules specifies the criteria that determine a suitable location within an HTML document to inject the JavaScript Agent:

  • (<?xml?> rule) If an <?xml ...?> specification is encountered:

    • Ignore it and continue to scan the document
    • Overrules (non-<meta> tag rule), (non-<head> tag rule) and (initial tag rule)
  • (initial tag rule) If a tag appears before <html> that is not <!DOCTYPE ...>, <html>, <link>, <meta>, <script>, or <style>:

    • Abort without injecting
  • (<html> tag rule) When <html> is encountered:
    • If a (potential) injection point is found earlier, inject there, and do not scan further (if there are multiples the earliest wins)
    • Otherwise continue to scan the document
  • (<!DOCTYPE> rule) If <!DOCTYPE ...> doesn't specify an HTML (isn't <!DOCTYPE HTML ...>):
    • Abort and do not inject
  • (comment rule) If a  <!- comment -> is encountered:
    • Ignore it and continue to scan the document
    • Overrules (non-<meta> tag rule) and (non-<head> tag rule)
  • (<title> tag rule) If <title> is encountered:
    • Ignore everything until </title>, then continue to scan the document
    • Overrules (<body> tag rule)
  • (<body> tag rule) If <body> is encountered:
    • Document scan stops
    • Any potential injection point found earlier is used (in case there were multiple, the earliest one wins)
    • If no rule provided an injection point earlier, inject after <body>
  • (<script src> tag rule) If a <script ...> tag is found within <head> that has an src="..." attribute:

    • If a (potential) injection point is found earlier, inject there, and do not scan further (if there are multiples, the earliest one wins)
    • Otherwise, inject before this <script> and do not scan further
    • Overrules (non-<meta> tag rule), (<base> tag rule)
  • (<link> tag rule) If a <link ...> tag is found within <head> that is not inline (doesn't have an href="data:..." attribute):

    • If a (potential) injection point is found earlier, inject there, and do not scan further (if there are multiples the earliest wins)
    • Otherwise, inject before this <link> and do not scan further
    • Overrules (non-<meta> tag rule), (<base> tag rule)
  • (flush rule) (Java only) when flush is called on the injecting stream/writer outside of <head>...</head> and a conditional injection awaits confirmation:

    • Discard the conditional injection point, propagate the flush and continue to scan the document for a new injection point
    • Overrules any conditional injection point found before by the (non-<head> tag rule)
  • (flush in <head> rule) (Java only) when flush is called on the injecting stream/writer within <head>...</head> and conditional injection awaits confirmation:

    • Keep the injection point and continue to scan the document
    • Disregard the flush (don't propagate it)
  • (<base> tag rule) If <base ...> is encountered:

    • Inject after the <base ...> tag
    • Overrules any conditional injection point found before by the (non-<meta> tag rule), (unclosed <meta> rule), (non-<head> tag rule)
  • (non-<meta> tag rule) If a tag is found within <head> that is neither <meta> nor <title>:

    • Inject before it (conditional injection)
    • Continue to scan the document, in case this injection choice gets overruled
  • (non-<head> tag rule) If a tag is found after <html> but before <head> that is neither <head> nor <body>

    • Inject before it (conditional injection)
    • Continue to scan the document, in case this injection choice gets overruled
  • (unclosed <meta> rule) If a </head> arrives after a <meta> that doesn't get closed (either by a closing </meta> tag or by the XML-style <meta ... /> tag):

    • Add </meta> followed by the injection, both before the </head> (conditional injection)
    • Continue to scan the document, in case this injection choice gets overruled
  • (</head> tag rule) on </head>:
    • If a (potential) injection point is found earlier, inject there, and do not scan further (if there are multiples the earliest wins)
    • Otherwise, continue to scan the document
  • (end of file rule) When end of file is reached (and scanning did not terminate before that):
    • Do not perform an injection
    • Overrules any conditional injection point found before by the (non-<meta> tag rule), (unclosed <meta> rule), (non-<head> tag rule)
  • (parse error rule) When the document's contents doesn't appear to exhibit the basic structure expected from HTML tags and attributes, it makes further parsing futile:

    • Document scan stops
    • Any potential injection point found earlier is used (in case there were multiple, the earliest one wins)
    • If no rule provided an injection point earlier, do not perform an injection

Manual Injection Details

If it is not possible that the JavaScript Agent is auto-injected by the Java or Web Server Agent at page delivery, you can still put the Agent script tag manually at design time.

As mentioned as other essentials in the overview above:

  • If the server providing the Agent and the one getting the monitoring data are different (domains), you must set the Monitor Request Path and check CORS.
    For Cordova / PhoneGap make sure this reference resolves via the domain whitelist. See PhoneGap Whitelist Guide.
  • You must also switch the Injection Point to manual in the respective <System Profile> > Agent Group / tier > Sensor Configuration > User Experience sensor > Properties.

Dynamically Served Agent

As of 6.2 the Java and Web Server Agents are capable of providing a bootstrapped JavaScript Agent, meaning:
You put the generic bootstrap script tag on the page as first script tag inside <head> and the bootstrapper assembles the JS Agent according to the settings in the <active System Profile> > User Experience, which is then injected in the web page.

The sample script tag in <System Profile> > User Experience vertical tab > <application> horizontal tab > Manual Injection depends on > JavaScript Agent > Agent Location and with Agent Location "/" (localhost, absolute path) it is:
<script src='
/dtagent_bootstrap.js'></script>

Generic format:
<script src='[http://
<instrumentedJavaOrWebServer>][/path][/]dtagent_bootstrap.js'></script>

The bootstrapped manual injection frees you from changing every injected website every time the System Profile settings changed.

The tag could look like this:

<script src='http://static-easytravel.com:8080/ajax/dtagent_bootstrap.js?app=Staging'></script>

There are various ways this feature can be leveraged:

  • UEM Only: If you have no instrumented server, you can just point the script tag to the location of the dynaTraceMonitor, and the bootstrapper should load your configured JavaScript Agent correctly.
  • On Premise: If you have an instrumented server (application or web server) and you can't use automatic injection, you can just insert the script tag as you did before with the JS Agent script tag, but don't have to edit the tag on every site every time you change the configuration.

Statically Served Agent

If you want to have less traffic to the instrumented server, you can manually download dtagent_bootstrap.js and the corresponding JavaScript Agent file and co-locate them anywhere on your server.

As this is a corner-case, please mind that the <System Profile> > User Experience vertical tab > <application> horizontal tab > Manual Injection > download buttons are only visible in debug mode. Please ask if you don't know how to.

For statically served Agents you put the bootstrap script tag as above, which references the locally available bootstrap and consequentially the Agent file.
When configuration changes, just switch the two files.

How does it work?

After UEM setting changes new bootstrappers are created containing all necessary information about the current configuration for each application. They get sent to all relevant app / web server Agents which are then capable to deliver them to browsers.

If a page is injected with the bootstrap Agent, it checks if the browser already stored some application information and creates the JavaScript Agent script tag. It is then injected directly after the bootstrap agent and will start working immediately.

Performance Notes

  • Overhead: Due to the fact that the JavaScript Agent is still needed, the bootstrap agent causes a second request to the same server. (The connection has already been established, so it's just the non-cached file size.) This is only necessary once a week per visitor. The second request is made via injection of a script tag and will behave like any other script tag inside the head of a website.
  • Caching: Since the bootstrap Agent as well as the JavaScript Agent are cached for about a week, there is a chance that the former will load the latter with outdated settings. In this case the first page load will be tracked using the old settings. A beacon is sent and in response the app / web server Agent provides new configurations which are then stored in the browser's local storage. Upon the next page load these settings are loaded and the bootstrapper is capable of creating an updated JavaScript Agent tag.
  • Filesize: Depending on the application configuration the obfuscated bootstrap Agent's size is about 680b. (1.08kb if gzip is disabled)
  • Browser support: Internet Explorer 6 and 7 have no implementation of Local or Session Storage and will therefore not automatically update upon configuration changes. However, as soon as the cached files age, they will be replaced with newer files containing updated settings.

Scenarios

There are various ways the bootstrap Agent is executed, depending on the visitor.

  1. New visitor: First, the bootstrap Agent is loaded, which loads the JavaScript Agent depending on the current configuration.
  2. Recurring visitor: The bootstrap Agent is loaded from cache and checks the browser's local storage for configuration entries. If there are none, it takes the last known configuration and loads the JavaScript Agent from cache. In case new settings are sent with the beacon, those get stored in the local storage.
  3. Recurring visitor with changed settings: The bootstrap Agent is loaded from cache and checks the browser's local storage for configuration entries. If there are any, it checks if they are newer than the ones contained in the bootstrap file and takes the latest settings to create the JavaScript Agent tag. If feature hash and version are the same, the JavaScript Agent is loaded from cache.
  4. Recurring visitor which shouldn't be tracked: If a visit should not be tracked due to visit percentage settings, the JavaScript Agent will initially still be injected by the bootstrapper and will send a beacon containing a load action. The application / web server Agents receive this beacon and decide if the visit should be tracked or not. If not, the beacon is ignored and the response contains a flag. Should the JavaScript Agent receive such a flag, every communication will shut down and no more beacons will be sent until the browser session ends.

Monitor Signal Behavior

The JavaScript Agent sends the gathered information in the form of POST requests. This behavior is recommended for most servers and requires that POST requests be allowed on dynaTraceMonitor?*. For reliable page performance some specific actions are sent via GET, such as when actions have to be sent in Chrome or newer Opera versions (15+) in onbeforeunload.

In most cases signals are sent as soon as actions are finished. This action starts with a user input that triggers a request and ends as soon as all of the request's callbacks are finished. The load-action occurs on each iframe and full page load and is sent on every page, if user inputs exist or not.

These actions trigger signals to be sent immediately after the actions are finished, in contrast to medium priority signals. These are triggered by timeless and lesser important actions. These medium priority actions are bandwidth, streaming, and third-party information, as well as reported values like errors or custom strings. If a signal is queued, this information is appended and doesn't create a separate request.

If multiple actions happen in a small time frame, such as a user action during page load, all of those actions are sent in a single signal.

For longer actions, a preview signal is sent as medium priority signal. Actions are sent only if all of their children and siblings are finished. If, for example, an action is opened and a second one is opened (which automatically is a child of the first one), the second one won't be sent until the first one is finished.

Support for Cross-Origin Resource Sharing (CORS)

Reporting from a non-instrumented host

Dynatrace enables injection of the JavaScript Agent on web servers that are not instrumented. If a website is hosted on a web server where UEM is not active, the JavaScript Agent has to report to a different domain, which can cause cross domain problems. If you use a CDN and don't want to send the monitor signal back through the CDN, you can send the monitor signal via CORS (Cross Origin Resource Sharing).

To enable support for CORS, in the Client GUI check Send Dynatrace monitoring request to foreign domain in <System Profile> > User Experience vertical tab > <application> horizontal tab > JavaScript Agent link right top.
The JavaScript Agent script tag must look like:

<script type="text/javascript" src="dt/dtagent630_x_1305.js" data-dtconfig="ridPath=/index.jsp|reportUrl=http://some-other-domain.example.com/dynaTraceMonitor|domain=.example.com|cors=1"></script>

Set the reportUrl parameter to a location that is UEM-enabled (for example by a Java Agent) and the cors parameter to 1.

Monitoring of CORS requests

Web requests can only be linked to user actions if cookies are available. In the case of CORS requests, cookies aren't sent per default. Therefore correlation between user actions and CORS web requests can only be achieved by using the withCredentials property of the XMLHttpRequest object. This applies for an environment like this:

Restrictions

Due to access-control-restrictions it is not possible to capture OPTIONS requests like those sent as CORS preflight requests. Capturing those requests would require sending a Dynatrace cookie to the receiver of the request, which is not allowed. This could result in User Action PurePaths that have the correct timing values, but are missing the time the OPTIONS request took before the "real" CORS request is fired. See MDN for more information about CORS preflight requests.

Bandwidth Detection

To detect a client's bandwidth, the JavaScript Agent requests signals of different sizes from the server. These GET-requests force the Agent to generate images of a specific file size and send them back to the client. The bandwidth is calculated according to the loadtime of these images. To reduce failures and guarantee the validity of the results, we recommend that you allow GET-requests on dynaTraceMonitor?bwstate=*.
Do not gzip or compress the requests. This reduces the file size of the generated images and the time it takes the clients to download them and such biases bandwidth to be better than it actually is.

Which features is it needed for?

  • Bandwidth measure
  • Network contribution time measure, calculated based on bandwidth and on resource size which is measured on the server side
  • User experience index for page actions for bandwidths lower than broadband
    The threshold will be multiplied by a factor between 1 and 2. Max. factor is 2.

How is it implemented?

  • Bandwidth detection will trigger 2 seconds after the JS Agent was loaded
  • The JavaScript Agent will load a series of fixed size images (0k, 3k, 10k, 30k, 100k, 300k, 1000k) and measure the time
  • First (0k) image is used for latency calculation, which will be subtracted from all other measurements
  • All subsequent images will be loaded until the download time without latency exceeds 100ms

What can be configured?

  • Bandwidth detection can be enabled per application (default: off)
  • Can be enabled separately for mobile browsers (default: off)
  • Frequency of bandwidth checks can be configured (default: every 5min)

What is the impact?

The bandwidth detection can have an impact on the user experience, because it might be triggered while the page is still loading. Even if there is no impact on the response time, synthetic tools still might consider the timings of the bandwidth check images for their calculation of the response time.

  • Typical impact on the response time: 0 - 100ms (highly depending on the individual page performance)
  • Impact on the total resource size of a page: up to 1443k