Code Monkey home page Code Monkey logo

applicationinsights-js's Introduction

Application Insights JavaScript SDK

GitHub Workflow Status (main) Build Status npm version minified size size gzip size

Before Getting Started

This SDK is not for non-browser environments, for example, the Node.js applications.

For instrumenting a Node.js app, the recommended SDK is the ApplicationInsights-node.js repository.

ES3 support has been removed from the latest version (v3.x), if required see for ES3/IE8 Support

Release Versions

Version Details
3.x
(main)
Current supported release from April '2023.
Supports dynamic configuration changes/updates after initialization. Supports all features of v2 except with the known Breaking changes from previous versions and does NOT support the previous v1.x compatible API proxy layer, it also removes support for ES3 / IE8. Minimum supported Runtime is now ES5 (IE9+).
2.x
(master)
Feature freeze from March '2023, security fixes and critical bugs only.
Supports adding / removing extensions and full unloading/removal of the SDK after initialization. Last version to support ES3 (IE8+), also provides a v1.x compatible API proxy layer for upgrading from V1.x.
1.0.x
(legacy-v1)
No longer actively maintained -- please Upgrade. The documentation for [email protected] has moved here. If you are looking to upgrade to the new version of the SDK, please see the Upgrade Guide.

💡 Note When multiple instances of Application Insights with different major version are active within a single session, errors may arise. For further details, please refer to the version conflict doc.

Getting Started

  1. Create an Application Insights resource in Azure by following these instructions.
  2. Grab the Connection String from the resource you created in step 1. Later, you'll add it to the connectionString setting of the Application Insights JavaScript SDK.
  3. Add Application Insights to your app. There are 2 ways to do this.

Basic Usage

NPM Setup (ignore if using Snippet Setup)

import { ApplicationInsights } from '@microsoft/applicationinsights-web'

const appInsights = new ApplicationInsights({ config: {
  connectionString: 'YOUR_CONNECTION_STRING_GOES_HERE'
  /* ...Other Configuration Options... */
} });
appInsights.loadAppInsights();
appInsights.trackPageView(); // Manually call trackPageView to establish the current user/session/pageview

Snippet Setup (Ignore if using NPM Setup)

If your app does not use NPM, you can directly instrument your webpages with Application Insights by pasting this snippet at the top of each your pages. Preferably, it should be the first script in your <head> section so that it can monitor any potential issues with all of your dependencies.

The current version of the snippet is version 7, the version is identified by the "sv:" in the script.

<script type="text/javascript">
!(function (cfg){function e(){cfg.onInit&&cfg.onInit(i)}var S,u,D,t,n,i,C=window,x=document,w=C.location,I="script",b="ingestionendpoint",E="disableExceptionTracking",A="ai.device.";"instrumentationKey"[S="toLowerCase"](),u="crossOrigin",D="POST",t="appInsightsSDK",n=cfg.name||"appInsights",(cfg.name||C[t])&&(C[t]=n),i=C[n]||function(l){var d=!1,g=!1,f={initialize:!0,queue:[],sv:"7",version:2,config:l};function m(e,t){var n={},i="Browser";function a(e){e=""+e;return 1===e.length?"0"+e:e}return n[A+"id"]=i[S](),n[A+"type"]=i,n["ai.operation.name"]=w&&w.pathname||"_unknown_",n["ai.internal.sdkVersion"]="javascript:snippet_"+(f.sv||f.version),{time:(i=new Date).getUTCFullYear()+"-"+a(1+i.getUTCMonth())+"-"+a(i.getUTCDate())+"T"+a(i.getUTCHours())+":"+a(i.getUTCMinutes())+":"+a(i.getUTCSeconds())+"."+(i.getUTCMilliseconds()/1e3).toFixed(3).slice(2,5)+"Z",iKey:e,name:"Microsoft.ApplicationInsights."+e.replace(/-/g,"")+"."+t,sampleRate:100,tags:n,data:{baseData:{ver:2}},ver:4,seq:"1",aiDataContract:undefined}}var h=-1,v=0,y=["js.monitor.azure.com","js.cdn.applicationinsights.io","js.cdn.monitor.azure.com","js0.cdn.applicationinsights.io","js0.cdn.monitor.azure.com","js2.cdn.applicationinsights.io","js2.cdn.monitor.azure.com","az416426.vo.msecnd.net"],k=l.url||cfg.src;if(k){if((n=navigator)&&(~(n=(n.userAgent||"").toLowerCase()).indexOf("msie")||~n.indexOf("trident/"))&&~k.indexOf("ai.3")&&(k=k.replace(/(\/)(ai\.3\.)([^\d]*)$/,function(e,t,n){return t+"ai.2"+n})),!1!==cfg.cr)for(var e=0;e<y.length;e++)if(0<k.indexOf(y[e])){h=e;break}var i=function(e){var a,t,n,i,o,r,s,c,p,u;f.queue=[],g||(0<=h&&v+1<y.length?(a=(h+v+1)%y.length,T(k.replace(/^(.*\/\/)([\w\.]*)(\/.*)$/,function(e,t,n,i){return t+y[a]+i})),v+=1):(d=g=!0,o=k,c=(p=function(){var e,t={},n=l.connectionString;if(n)for(var i=n.split(";"),a=0;a<i.length;a++){var o=i[a].split("=");2===o.length&&(t[o[0][S]()]=o[1])}return t[b]||(e=(n=t.endpointsuffix)?t.location:null,t[b]="https://"+(e?e+".":"")+"dc."+(n||"services.visualstudio.com")),t}()).instrumentationkey||l.instrumentationKey||"",p=(p=p[b])?p+"/v2/track":l.endpointUrl,(u=[]).push((t="SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details)",n=o,r=p,(s=(i=m(c,"Exception")).data).baseType="ExceptionData",s.baseData.exceptions=[{typeName:"SDKLoadFailed",message:t.replace(/\./g,"-"),hasFullStack:!1,stack:t+"\nSnippet failed to load ["+n+"] -- Telemetry is disabled\nHelp Link: https://go.microsoft.com/fwlink/?linkid=2128109\nHost: "+(w&&w.pathname||"_unknown_")+"\nEndpoint: "+r,parsedStack:[]}],i)),u.push((s=o,t=p,(r=(n=m(c,"Message")).data).baseType="MessageData",(i=r.baseData).message='AI (Internal): 99 message:"'+("SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details) ("+s+")").replace(/\"/g,"")+'"',i.properties={endpoint:t},n)),o=u,c=p,JSON&&((r=C.fetch)&&!cfg.useXhr?r(c,{method:D,body:JSON.stringify(o),mode:"cors"}):XMLHttpRequest&&((s=new XMLHttpRequest).open(D,c),s.setRequestHeader("Content-type","application/json"),s.send(JSON.stringify(o))))))},a=function(e,t){g||setTimeout(function(){!t&&f.core||i()},500),d=!1},T=function(e){var n=x.createElement(I),e=(n.src=e,cfg[u]);return!e&&""!==e||"undefined"==n[u]||(n[u]=e),n.onload=a,n.onerror=i,n.onreadystatechange=function(e,t){"loaded"!==n.readyState&&"complete"!==n.readyState||a(0,t)},cfg.ld&&cfg.ld<0?x.getElementsByTagName("head")[0].appendChild(n):setTimeout(function(){x.getElementsByTagName(I)[0].parentNode.appendChild(n)},cfg.ld||0),n};T(k)}try{f.cookie=x.cookie}catch(p){}function t(e){for(;e.length;)!function(t){f[t]=function(){var e=arguments;d||f.queue.push(function(){f[t].apply(f,e)})}}(e.pop())}var r,s,n="track",o="TrackPage",c="TrackEvent",n=(t([n+"Event",n+"PageView",n+"Exception",n+"Trace",n+"DependencyData",n+"Metric",n+"PageViewPerformance","start"+o,"stop"+o,"start"+c,"stop"+c,"addTelemetryInitializer","setAuthenticatedUserContext","clearAuthenticatedUserContext","flush"]),f.SeverityLevel={Verbose:0,Information:1,Warning:2,Error:3,Critical:4},(l.extensionConfig||{}).ApplicationInsightsAnalytics||{});return!0!==l[E]&&!0!==n[E]&&(t(["_"+(r="onerror")]),s=C[r],C[r]=function(e,t,n,i,a){var o=s&&s(e,t,n,i,a);return!0!==o&&f["_"+r]({message:e,url:t,lineNumber:n,columnNumber:i,error:a,evt:C.event}),o},l.autoExceptionInstrumented=!0),f}(cfg.cfg),(C[n]=i).queue&&0===i.queue.length?(i.queue.push(e),i.trackPageView({})):e();})({
    src: "https://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js",
    // name: "appInsights", // Global SDK Instance name defaults to "appInsights" when not supplied
    // ld: 0, // Defines the load delay (in ms) before attempting to load the sdk. -1 = block page load and add to head. (default) = 0ms load after timeout,
    // useXhr: 1, // Use XHR instead of fetch to report failures (if available),
    // dle: true, // Prevent the SDK from reporting load failure log
    crossOrigin: "anonymous", // When supplied this will add the provided value as the cross origin attribute on the script tag
    // onInit: null, // Once the application insights instance has loaded and initialized this callback function will be called with 1 argument -- the sdk instance (DO NOT ADD anything to the sdk.queue -- As they won't get called)
    cfg: { // Application Insights Configuration
        connectionString: "YOUR_CONNECTION_STRING"
    }
});
</script>

💡 Note

  1. For readability and to reduce possible JavaScript errors, all of the possible configuration options are listed on a new line in snippet code above, if you don't want to change the value of a commented line it can be removed.

  2. ConnectionString format should follow "InstrumentationKey=xxxx;...." If the string provided does not meet this format, the sdk load process would fail

Reporting Script load exceptions

This version of the snippet detects and reports an exception when loading the SDK from the CDN fails, this exception is reported to the Azure Monitor portal (under the failures > exceptions > browser), and provides visibility into failures of this type so that you are aware your application is not reporting telemetry (or other exceptions) as expected. This signal is an important measurement in understanding that you have lost telemetry because the SDK did not load or initialize, this provides clarity that you are missing the following telemetry:

  • Under-reporting of how users are using (or trying to use) your site;
  • Missing telemetry on how your end users are using your site;
  • Missing JavaScript errors that could potentially be blocking your end users from successfully using your site.

For details on this exception see SDK Load Failure page.

Reporting of this failure as an exception to the portal does not use the configuration option disableExceptionTracking from the application insights configuration and therefore if this failure occurs it will always be reported by the snippet, even when the window.onerror support is disabled.

Reporting of SDK load exceptions is specifically NOT supported on IE 8 (or less). This assists with reducing the minified size of the snippet by assuming that most environments are not exclusively IE 8 or less. If you have this requirement and you wish to receive these exceptions, you will need to either include a fetch poly fill or create you own snippet version that uses XDomainRequest instead of XMLHttpRequest, it is recommended that you use the provided snippet source code as a starting point.

💡 Note

If you are using a previous version of the snippet, it is highly recommended that you update to the latest version so that you will receive these previously unreported issues.

Snippet configuration options

All configuration options have now been move towards the end of the script to help avoid accidentally introducing JavaScript errors that would not just cause the SDK to fail to load, but also it would disable the reporting of the failure.

Each configuration option is shown above on a new line, if you don't wish to override the default value of an item listed as [optional] you can remove that line to minimize the resulting size of your returned page.

The available configuration options are: -

Name Type Description
src string [required] The full URL for where to load the SDK from. This value is used for the "src" attribute of a dynamically added <script /> tag. You can use the public CDN location or your own privately hosted one.
name string [optional] The global name for the initialized SDK, defaults to appInsights. So window.appInsights will be a reference to the initialized instance. Note: if you provide a name value or a previous instance appears to be assigned (via the global name appInsightsSDK) then this name value will also be defined in the global namespace as window.appInsightsSDK=<name value>, this is required by the SDK initialization code to ensure it's initializing and updating the correct snippet skeleton and proxy methods.
ld number in ms [optional] Defines the load delay to wait before attempting to load the SDK. Default value is 0ms and any negative value will immediately add a script tag to the <head> region of the page, which will then block the page load event until to script is loaded (or fails).
useXhr boolean [optional] This setting is used only for reporting SDK load failures. Reporting will first attempt to use fetch() if available and then fallback to XHR, setting this value to true just bypasses the fetch check. Use of this value is only be required if your application is being used in an environment where fetch would fail to send the failure events.
crossOrigin string [optional] By including this setting, the script tag added to download the SDK will include the crossOrigin attribute with this string value. When not defined (the default) no crossOrigin attribute is added. Recommended values are not defined (the default); ""; or "anonymous" (For all valid values see HTML attribute: crossorigin documentation)
onInit function(aiSdk) { ... } [optional] This callback function which is called after the main SDK script has been successfully loaded and initialized from the CDN (based on the src value), it is passed a reference to the sdk instance that it is being called for and it is also called before the first initial page view. If the SDK has already been loaded and initialized this callback will still be called. NOTE: As this callback is called during the processing of the sdk.queue array you CANNOT add any additional items to the queue as they will be ignored and dropped. (Added as part of snippet version 5 -- the sv:"#" value within the snippet script, the current version is 7)
cfg object [required] The configuration passed to the Application Insights SDK during initialization.

Example using the snippet onInit callback

<script type="text/javascript">
!function(T,l,y){<!-- Removed the Snippet code for brevity -->}(window,document,{
src: "https://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js",
crossOrigin: "anonymous",
onInit: function (sdk) {
  sdk.addTelemetryInitializer(function (envelope) {
    envelope.data.someField = 'This item passed through my telemetry initializer';
  });
}, // Once the application insights instance has loaded and initialized this method will be called
cfg: { // Application Insights Configuration
    connectionString: "YOUR_CONNECTION_STRING"
}});
</script>

Active Public CDN endpoints

To help with global resiliency, we have added and updated our primary CDN endpoint (source URL) so that if required we can address any outages without the need for everyone to update the URL used by the Application Insights snippet within their application.

All active CDN endpoints contain all of the previous (and future) versions of the SDK and there is currently no plans to stop or block accessing the snippet from the previous (legacy/backup) URL.

State CDN Endpoint Description
Primary https://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js Provides additional resiliency, allowing us to redirect to a different CDN provider should there be an unexpected issue (if required).
Legacy/Backup
❗ Deprecated
https://az416426.vo.msecnd.net/scripts/b/ai.2.min.js Due to the legacy nature of this URL / Domain, if there is an unexpected issue (outage) with this domain, your application will need to be updated and deployed to use the new URL.
❗ Due to #1813 this URL is now being classified as Deprecated and we will be actively making changes to the SDK to warnings in your telemetry if we detect this domain being used.

Connection String Setup

For either the NPM or Snippet setup, you can also configure your instance of Application Insights using a Connection String. Simply replace the instrumentationKey field with the connectionString field.

import { ApplicationInsights } from '@microsoft/applicationinsights-web'

const appInsights = new ApplicationInsights({ config: {
  connectionString: 'YOUR_CONNECTION_STRING_GOES_HERE'
  /* ...Other Configuration Options... */
} });
appInsights.loadAppInsights();
appInsights.trackPageView();

(Alternative Setup Method) Include AI JS SDK script and initialize statically

Use this approach if you would like to host AI JS SDK script on your endpoint or bundle it with other scripts.

<!-- use your own path to JS SDK script -->
<script type="text/javascript" src="/pathToAIJSSDK.js"></script>

After JS script has loaded, include the following snippet to initialize Application Insights:

<!-- the snippet below assumes that JS SDK script has already loaded -->
<script type="text/javascript">
    var snippet = {
        config: {
            connectionString: "InstrumentationKey=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
        }
    };
    var init = new Microsoft.ApplicationInsights.ApplicationInsights(snippet);
    var appInsights = init.loadAppInsights();
    appInsights.trackPageView();
</script>

Sending Telemetry to the Azure Portal

If initialized using the snippet, your Application Insights instance is located by default at window.appInsights

appInsights.trackEvent({name: 'some event'});
appInsights.trackPageView({name: 'some page'});
appInsights.trackPageViewPerformance({name : 'some page', url: 'some url'});
appInsights.trackException({exception: new Error('some error')});
appInsights.trackTrace({message: 'some trace'});
appInsights.trackMetric({name: 'some metric', average: 42});
appInsights.trackDependencyData({absoluteUrl: 'some url', responseCode: 200, method: 'GET', id: 'some id'});
appInsights.startTrackPage("pageName");
appInsights.stopTrackPage("pageName", null, {customePropertiesName: "some value"}, {customerMeasurementsName: 144});
appInsights.startTrackEvent("event");
appInsights.stopTrackEvent("event", null, {customePropertiesName: "some value"}, {customerMeasurementsName: 150});
appInsights.flush();

Custom properties can be included in your telemetry through the properties named argument. This can be done with any of the Track APIs except stopTrackPage and stopTrackEvent.

appInsights.trackEvent({
  name: 'some event',
  properties: { // accepts any type
    prop1: 'string',
    prop2: 123.45,
    prop3: { nested: 'objects are okay too' }
  }
});

When using stopTrackPage and stopTrackEvent, you can pass in data categorized by types:

Strings: These should be included under the properties field. Numbers: Add these under the measurements field. Remember, the order of the properties and measurements should not be altered. You can achieve this using the following code structure:

appInsights.startTrackEvent("event name"); 
appInsights.stopTrackEvent("event name", {
  stringProp1: 'string',
  stringProp2: {nested:"objects are okay too"}
  },
  {numProp1: 3.15, numProp2: 90000}
)

Setting Up Autocollection

All autocollection is ON by default. The full version of the Application Insights Javascript SDK auto collects:

  • Uncaught exceptions in your app, including information on
    • Stack trace
    • Exception details and message accompanying the error
    • Line & column number of error
    • URL where error was raised
  • Network Dependency Requests made by your app XHR and Fetch (fetch collection is enabled by default) requests, include information on
    • Url of dependency source
    • Command & Method used to request the dependency
    • Duration of the request
    • Result code and success status of the request
    • ID (if any) of user making the request
    • Correlation context (if any) where request is made
  • User information (e.g. Location, network, IP)
  • Device information (e.g. Browser, OS, version, language, model)
  • Session information

Telemetry Initializers

Telemetry initializers are used to modify the contents of collected telemetry before being sent from the user's browser. They can also be used to prevent certain telemetry from being sent, by returning false. Multiple telemetry initializers can be added to your Application Insights instance, and they are executed in order of adding them.

The input argument to addTelemetryInitializer is a callback that takes a ITelemetryItem as an argument and returns a boolean or void. If returning false, the telemetry item is not sent, else it proceeds to the next telemetry initializer, if any, or is sent to the telemetry collection endpoint.

var telemetryInitializer = (envelope) => {
  envelope.tags["ai.cloud.role"] = "your role name";
  envelope.tags["ai.cloud.roleInstance"] = "your role instance";
}
appInsights.addTelemetryInitializer(telemetryInitializer);

Example: Filtering

var telemetryInitializer = (envelope) => {
  envelope.data.someField = 'This item passed through my telemetry initializer';
};
appInsights.addTelemetryInitializer(telemetryInitializer);
appInsights.trackTrace({message: 'This message will use a telemetry initializer'});

appInsights.addTelemetryInitializer(() => false); // Nothing is sent after this is executed
appInsights.trackTrace({message: 'this message will not be sent'}); // Not sent

Dependency Listeners

A dependency listener is a callback function that allows you to perform additional manipulation of the request details before the request is performed.

This includes :-

  • Complete access to either the XMLHttpRequest instance or the fetch API input and init arguments.
  • Ability to get/set the properties used to generate the W3C traceparent header (traceId, spanId, traceFlags)
  • Set values in the object context container for other listeners called after the current one, as well as this context object is also made available to all dependency initializers.

Dependency Initializers

A Dependency Initializer is very similar to a Telemetry Initializer in that it allows you modify the contents of collected telemetry before being sent from the user's browser. And you can also returning false to cause the event to not be emitted.

The differences between a telemetry initializer and a dependency initializer are :-

  • A Dependency Initializer is called "before" the event is processed by the pipeline, as such it will NOT (yet) contain the automatically populated properties that are applied later;
  • When a dependency initializer returns false to drop the event the event does NOT count against the maxAjaxCallsPerView as this blocks the event call from being tracked, and while returning false from a Telemetry Initializer will also stop the event from being reported because this is further down the processing pipeline the dependency event IS counted against the maxAjaxCallsPerView limit.
  • It has access to an optional "context" { [key: string]: any } object that is also available to the Dependency Listeners. This allows a listener to add additional details to the context (before the XHR/fetch request is sent), and the initializer will be called after the request has completed.

Configuration

Most configuration fields are named such that they can be defaulted to falsey. All fields are optional except for instrumentationKey or a connectionString containing the instrumentation key.

Name Type Default Description
instrumentationKey string
[Required if connectionString not supplied]
null Instrumentation key that you obtained from the Azure Portal.
connectionString string
[Require if instrumentationKey not supplied]
null The Connection string that you obtained from the Azure portal
accountId string null An optional account id, if your app groups users into accounts. No spaces, commas, semicolons, equals, or vertical bars
sessionRenewalMs numeric 1800000 A session is logged if the user is inactive for this amount of time in milliseconds. Default is 30 minutes
sessionExpirationMs numeric 86400000 A session is logged if it has continued for this amount of time in milliseconds. Default is 24 hours
maxBatchSizeInBytes numberic 10000 Max size of telemetry batch. If a batch exceeds this limit, it is immediately sent and a new batch is started
maxBatchInterval numeric 15000 How long to batch telemetry for before sending (milliseconds)
disableExceptionTracking boolean false
disableTelemetry boolean false If true, telemetry is not collected or sent. Default is false.
enableDebug boolean false If true, internal debugging data is thrown as an exception instead of being logged, regardless of SDK logging settings. Default is false.
Note: Enabling this setting will result in dropped telemetry whenever an internal error occurs. This can be useful for quickly identifying issues with your configuration or usage of the SDK. If you do not want to lose telemetry while debugging, consider using loggingLevelConsole or loggingLevelTelemetry instead of enableDebug.
enableDebugExceptions boolean false Removed from v3.x, Prior to v2.8.12 this was the only supported value and the documented enableDebug was incorrect, since v2.8.12 both enableDebug and enableDebugExceptions is supported.
loggingLevelConsole numeric 0 Logs internal Application Insights errors to console.
0: off,
1: Critical errors only,
2: Everything (errors & warnings)
loggingLevelTelemetry numeric 1 Sends internal Application Insights errors as telemetry.
0: off,
1: Critical errors only,
2: Everything (errors & warnings)
diagnosticLogInterval numeric 10000 (internal) Polling interval (in ms) for internal logging queue
samplingPercentage numeric 100 Percentage of events that will be sent. Default is 100, meaning all events are sent. Set this if you wish to preserve your datacap for large-scale applications.
autoTrackPageVisitTime boolean false If true, on a pageview, the previous instrumented page's view time is tracked and sent as telemetry and a new timer is started for the current pageview. It is sent as a custom metric named PageVisitTime in milliseconds and is calculated via the Date now() function (if available) and falls back to (new Date()).getTime() if now() is unavailable (IE8 or less). Default is false.
disableAjaxTracking boolean false If true, Ajax calls are not autocollected. Default is false.
disableFetchTracking boolean false If true, Fetch requests are not autocollected. Default is false (Since v2.8.0, previously true)
excludeRequestFromAutoTrackingPatterns string[] | RegExp[] undefined Provide a way to exclude specific route from automatic tracking for XMLHttpRequest or Fetch request. If defined, for an ajax / fetch request that the request url matches with the regex patterns, auto tracking is turned off. Default is undefined.
addRequestContext (requestContext: IRequestionContext) => {[key: string]: any} undefined Provide a way to enrich dependencies logs with context at the beginning of api call. Default is undefined. You will need to check if xhr exists if you configure xhr related conetext. You will need to check if fetch request and fetch response exist if you configure fetch related context. Otherwise you may not get the data you need.
overridePageViewDuration boolean false If true, default behavior of trackPageView is changed to record end of page view duration interval when trackPageView is called. If false and no custom duration is provided to trackPageView, the page view performance is calculated using the navigation timing API. Default is false.
maxAjaxCallsPerView numeric 500 Default 500 - controls how many ajax calls will be monitored per page view. Set to -1 to monitor all (unlimited) ajax calls on the page.
disableDataLossAnalysis boolean true If false, internal telemetry sender buffers will be checked at startup for items not yet sent.
disableCorrelationHeaders boolean false If false, the SDK will add two headers ('Request-Id' and 'Request-Context') to all dependency requests to correlate them with corresponding requests on the server side. Default is false.
correlationHeaderExcludedDomains string[] undefined Disable correlation headers for specific domains
correlationHeaderExcludePatterns regex[] undefined Disable correlation headers using regular expressions
correlationHeaderDomains string[] undefined Enable correlation headers for specific domains
disableFlushOnBeforeUnload boolean false Default false. If true, flush method will not be called when onBeforeUnload event triggers
enableSessionStorageBuffer boolean true Default true. If true, the buffer with all unsent telemetry is stored in session storage. The buffer is restored on page load
cookieCfg ICookieCfgConfig
[Optional]
(Since 2.6.0)
undefined Defaults to cookie usage enabled see ICookieCfgConfig settings for full defaults.
isCookieUseDisabled
disableCookiesUsage
alias for cookieCfg.enabled
[Optional]
false Default false. A boolean that indicates whether to disable the use of cookies by the SDK. If true, the SDK will not store or read any data from cookies. isCookieUseDisable is deprecated in favor of disableCookiesUsage, when both are provided disableCookiesUsage take precedence.
(Since v2.6.0) If cookieCfg.enabled is defined it will take precedence over these values, Cookie usage can be re-enabled after initialization via the core.getCookieMgr().setEnabled(true).
cookieDomain alias for cookieCfg.domain
[Optional]
null Custom cookie domain. This is helpful if you want to share Application Insights cookies across subdomains.
(Since v2.6.0) If cookieCfg.domain is defined it will take precedence over this value.
cookiePath alias for cookieCfg.path
[Optional]
(Since 2.6.0)
null Custom cookie path. This is helpful if you want to share Application Insights cookies behind an application gateway.
If cookieCfg.path is defined it will take precedence over this value.
isRetryDisabled boolean false Default false. If false, retry on 206 (partial success), 408 (timeout), 429 (too many requests), 500 (internal server error), 503 (service unavailable), and 0 (offline, only if detected)
isStorageUseDisabled boolean false If true, the SDK will not store or read any data from local and session storage. Default is false.
isBeaconApiDisabled boolean true If false, the SDK will send all telemetry using the Beacon API
disableXhr boolean false Don't use XMLHttpRequest or XDomainRequest (for IE < 9) by default instead attempt to use fetch() or sendBeacon. If no other transport is available it will still use XMLHttpRequest
onunloadDisableBeacon boolean false Default false. when tab is closed, the SDK will send all remaining telemetry using the Beacon API
onunloadDisableFetch boolean false If fetch keepalive is supported do not use it for sending events during unload, it may still fallback to fetch() without keepalive
sdkExtension string null Sets the sdk extension name. Only alphabetic characters are allowed. The extension name is added as a prefix to the 'ai.internal.sdkVersion' tag (e.g. 'ext_javascript:2.0.0'). Default is null.
isBrowserLinkTrackingEnabled boolean false Default is false. If true, the SDK will track all Browser Link requests.
appId string null AppId is used for the correlation between AJAX dependencies happening on the client-side with the server-side requests. When Beacon API is enabled, it cannot be used automatically, but can be set manually in the configuration. Default is null
enableCorsCorrelation boolean false If true, the SDK will add two headers ('Request-Id' and 'Request-Context') to all CORS requests to correlate outgoing AJAX dependencies with corresponding requests on the server side. Default is false
namePrefix string undefined An optional value that will be used as name postfix for localStorage and session cookie name.
sessionCookiePostfix string undefined An optional value that will be used as name postfix for session cookie name. If undefined, namePrefix is used as name postfix for session cookie name.
userCookiePostfix string undefined An optional value that will be used as name postfix for user cookie name. If undefined, no postfix is added on user cookie name.
enableAutoRouteTracking boolean false Automatically track route changes in Single Page Applications (SPA). If true, each route change will send a new Pageview to Application Insights. Hash route changes changes (example.com/foo#bar) are also recorded as new page views.
enableRequestHeaderTracking boolean false If true, AJAX & Fetch request headers is tracked, default is false. If ignoreHeaders is not configured, Authorization and X-API-Key headers are not logged.
enableResponseHeaderTracking boolean false If true, AJAX & Fetch request's response headers is tracked, default is false. If ignoreHeaders is not configured, WWW-Authenticate header is not logged.
ignoreHeaders string[] ["Authorization", "X-API-Key", "WWW-Authenticate"] AJAX & Fetch request and response headers to be ignored in log data. To override or discard the default, add an array with all headers to be excluded or an empty array to the configuration.
enableAjaxErrorStatusText boolean false Default false. If true, include response error data text
enableAjaxPerfTracking boolean false Default false. Flag to enable looking up and including additional browser window.performance timings in the reported ajax (XHR and fetch) reported metrics.
maxAjaxPerfLookupAttempts numeric 3 Defaults to 3. The maximum number of times to look for the window.performance timings (if available), this is required as not all browsers populate the window.performance before reporting the end of the XHR request and for fetch requests this is added after its complete.
ajaxPerfLookupDelay numeric 25 Defaults to 25ms. The amount of time to wait before re-attempting to find the windows.performance timings for an ajax request, time is in milliseconds and is passed directly to setTimeout().
distributedTracingMode numeric or DistributedTracingModes DistributedTracingModes.AI_AND_W3C Sets the distributed tracing mode. If AI_AND_W3C mode or W3C mode is set, W3C trace context headers (traceparent/tracestate) will be generated and included in all outgoing requests. AI_AND_W3C is provided for back-compatibility with any legacy Application Insights instrumented services.
enableUnhandledPromiseRejectionTracking boolean false If true, unhandled promise rejections will be autocollected and reported as a javascript error. When disableExceptionTracking is true (dont track exceptions) the config value will be ignored and unhandled promise rejections will not be reported.
disableInstrumentationKeyValidation boolean false If true, instrumentation key validation check is bypassed. Default value is false.
enablePerfMgr boolean false [Optional] When enabled (true) this will create local perfEvents for code that has been instrumented to emit perfEvents (via the doPerf() helper). This can be used to identify performance issues within the SDK based on your usage or optionally within your own instrumented code. More details are available by the basic documentation. Since v2.5.7
perfEvtsSendAll boolean false [Optional] When enablePerfMgr is enabled and the IPerfManager fires a INotificationManager.perfEvent() this flag determines whether an event is fired (and sent to all listeners) for all events (true) or only for 'parent' events (false <default>).
A parent IPerfEvent is an event where no other IPerfEvent is still running at the point of this event being created and it's parent property is not null or undefined. Since v2.5.7
createPerfMgr (core: IAppInsightsCore, notificationManager: INotificationManager) => IPerfManager undefined Callback function that will be called to create a the IPerfManager instance when required and enablePerfMgr is enabled, this enables you to override the default creation of a PerfManager() without needing to setPerfMgr() after initialization.
idLength numeric 22 [Optional] Identifies the default length used to generate new random session and user id's. Defaults to 22, previous default value was 5 (v2.5.8 or less), if you need to keep the previous maximum length you should set this value to 5.
customHeaders [{header: string, value: string}] undefined [Optional] The ability for the user to provide extra headers when using a custom endpoint. customHeaders will not be added on browser shutdown moment when beacon sender is used. And adding custom headers is not supported on IE9 or earlier.
convertUndefined any undefined [Optional] Provide user an option to convert undefined field to user defined value.
eventsLimitInMem number 10000 [Optional] The number of events that can be kept in memory before the SDK starts to drop events when not using Session Storage (the default).
disableIkeyDeprecationMessage boolean true [Optional] Disable instrumentation Key deprecation error message. If true, error message will NOT be sent. Note: instrumentation key support will end soon, see aka.ms/IkeyMigrate for more details.
bufferOverride
since 2.8.12
IStorageBuffer undefined [Optional] Identifies a simple interface to allow you to override the storage mechanism used for tracking unsent and unacknowledged events, when not provided defaults to using SessionStorage interface. You MUST supply both the getItem and setItem functions when defined.
storagePrefix string[] undefined [Optional] An optional value that will be added as name prefix for storage name.
featureOptIn
since 3.0.3
IFeatureOptIn undefined [Optional] Set Feature opt in details.
throttleMgrCfg
since 3.0.3
{[key: number]: IThrottleMgrConfig} undefined [Optional] Set throttle mgr configuration by key.
retryCodes number[] undefined Identifies the status codes that will cause event batches to be resent, when null or undefined the SDK will use it's defaults [401, 408, 429, 500, 502, 503, 504]. 403 was removed in version 3.1.1.

ICookieMgrConfig

Cookie Configuration for instance based cookie management added in version 2.6.0.

Name Type Default Description
enabled boolean true A boolean that indicates whether the use of cookies by the SDK is enabled by the current instance. If false, the instance of the SDK initialized by this configuration will not store or read any data from cookies
domain string null Custom cookie domain. This is helpful if you want to share Application Insights cookies across subdomains. If not provided uses the value from root cookieDomain value.
path string / Specifies the path to use for the cookie, if not provided it will use any value from the root cookiePath value.
ignoreCookies string[] undefined Specify the cookie name(s) to be ignored, this will cause any matching cookie name to never be read or written. They may still be explicitly purged or deleted. You do not need to repeat the name in the blockedCookies configuration.(Since v2.8.8)
blockedCookies string[] undefined Specify the cookie name(s) to never be written, this will cause any cookie name to never be created or updated, they will still be read unless also included in the ignoreCookies and may still be explicitly purged or deleted. If not provided defaults to the same list provided in ignoreCookies. (Since v2.8.8)
getCookie (name: string) => string null Function to fetch the named cookie value, if not provided it will use the internal cookie parsing / caching.
setCookie (name: string, value: string) => void null Function to set the named cookie with the specified value, only called when adding or updating a cookie.
delCookie (name: string, value: string) => void null Function to delete the named cookie with the specified value, separated from setCookie to avoid the need to parse the value to determine whether the cookie is being added or removed.if not provided it will use the internal cookie parsing / caching.

Cookie Handling

From version 2.6.0, cookie management is now available directly from the instance and can be disabled and re-enabled after initialization.

If disabled during initialization via the disableCookiesUsage or cookieCfg.enabled configurations, you can now re-enable via the ICookieMgr setEnabled function.

The instance based cookie management also replaces the previous CoreUtils global functions of disableCookies(), setCookie(...), getCookie(...) and deleteCookie(...). And to benefit from the tree-shaking enhancements also introduced as part of version 2.6.0 you should no longer uses the global functions.

Simplified Usage of new instance Cookie Manager

General Guidance

When calling getCookieMgr() before the SDK has successfully initialized will return a temporary ICookieMgr instance that will have cookie support fully enabled, thus allowing the getting, setting and deleting of cookies. So unless you know that your configuration WILL ALLOW cookie usage you should delay accessing or using the cookie manager until after initialization.

In v2.6.0 the getCookieMgr() is not directly available on the main entry points documented above for the snippet, NPM (ApplicationInsights) or React Plugin usages. As a workaround for this version you will need to access it via the core or appInsights properties as below (the getCookieMgr() will be available in later versions)

Snippet usage notes

The getCookieMgr() method, core and appInsights properties are only available AFTER the SDK has been successfully loaded and initialized.

So you will need to only call or access the manager from within the onInit() callback function (available in snippet (v5) or above) or after you know that the SDK has been loaded and initialized, otherwise you will cause an exception, unless you also perform an existence check of the property or function.

Additional Legacy snippet users for v2.6.0

If you are using a legacy snippet for your application (it is suggested that you upgrade), you will need to use the following options

Tree-Shaking Support and enhancements

As part of changes being introduced in version 2.6.0 we are deprecating and removing the internal usages of the static helper classes CoreUtils, EventHelper, Util, UrlHelper, DateTimeUtils and ConnectionStringParser to provide better support for tree-shaking algorithms so that unused code can be safely dropped when using NPM packages.

See Tree-Shaking Recommendations

Service Notification

As part of changes being introduced in version 3.0.3, we are intergrating cfgSync plugin and throttle manager to AISKU. For versions before 3.1.2, these components are disabled by default.

For versions after 3.1.2, these components are turned on by default. See feature opt-in status for more details.

For users behind a firewall, see how to disable fetching from default CfgSync CDN.

Single Page Applications

By default, this SDK will not handle state based route changing that occurs in single page applications. To enable automatic route change tracking for your single page application, you can add enableAutoRouteTracking: true to your setup configuration.

Currently, we support a separate React plugin which you can initialize with this SDK. It will also accomplish route change tracking for you, as well as collect other React specific telemetry.

Source Map Support

The minified callstack of your exception telemetry can be unminified in the Azure Portal. All existing integrations on the Exception Details panel will work with the newly unminified callstack. Drag and drop source map unminifying supports all existing and future JS SDKs (+Node.JS), so you do not need to upgrade your SDK version. To view your unminified callstack,

  1. Select an Exception Telemetry item in the Azure Portal to view its "End-to-end transaction details"
  2. Identify which source maps correspond to this call stack. The source map must match a stack frame's source file, but suffixed with .map
  3. Drag and drop the source maps onto the call stack in the Azure Portal

Examples

For runnable examples, see Application Insights Javascript SDK Samples

Application Insights Web Basic

For a lightweight experience, you can instead install the basic version of Application Insights

npm i --save @microsoft/applicationinsights-web-basic

This version comes with the bare minimum amount of features and functionalities and relies on you to build it up as you see fit. For example, it performs no auto-collection (uncaught exceptions, ajax, etc). The APIs to send certain telemetry types, like trackTrace, trackException, etc, are not included in this version, so you will need to provide your own wrapper. The only api that is available is track. A sample is located here.

Available extensions for the SDK

Extensions NPM Version
Angular npm version
React npm version
React Native npm version

Build a new extension for the SDK

The SDK supports the ability to include multiple extensions at runtime. In order to create a new extension, please implement the following interface:

ITelemetryPlugin

On initialization, config.extensions accepts an array of ITelemetryPlugin objects. These are hooked up and ITelemetryPlugin.processTelemetry() is chained based on priority of these plugins. Please note that higher the priority, the later your processing code will be invoked. The SDK supports a plugin model and channels can also be plugged in similarly (advanced scenario). Target scenarios for creating a brand new extension is to share a usage scenario that benefits multiple customers. Please follow guidelines

Here is the priority ranges available:

  • Regular extension priority can be between 201 to 499.
  • Priorty range < 201 is reserved.
  • Priority range > 1000 is for channels (advanced scenario)

BaseTelemetryPlugin

To help with the creation of new extensions there is now a supported base class which can be used, this not only provides the common (boilerplate) implementations of common functions it will enable future plugins to automatically receive functional updates with the need to recode the plugins. it provides implementations for :-

  • ITelemetryPlugin.setNextPlugin() implementation to continuing supporting existing (non-shared) execution of plugins, however, new plugins should use the new IProcessTelemetryContext.processNext() moving forward as this support the creation of shared (singleton) plugins;

  • New ITelemetryPlugin.isInitialized() implementation

  • And several helper methods.

    If you are creating new extensions it is recommended that you extend from this base class so that your extension will automatically inherit any future enhancements that are added to the ITelemetryPlugin interface without it requiring updates.

Usage:

const customPluginInstance = new YourCustomPlugin()
const appInsights = new ApplicationInsights({ config: {
    connectionString: 'YOUR_CONNECTION_STRING_GOES_HERE',
    extensions: [customPluginInstance]
    // Other Configuration Options...
}});
appInsights.loadAppInsights();

ITelemetryPlugin has a simpler base type IPlugin that you can instantiate for initialization purposes when SDK loads.

Build & Test this repo

  1. Install all dependencies

    npm install
    npm install -g @microsoft/rush
  2. Navigate to the root folder and update rush dependencies

    rush update
  3. Build and test

    rush build
    npm run test

Performance

Application Insights JS adds a negligible amount of load time to your website. By using the snippet, minimal components of the library are quickly loaded. In the meantime, the full script is downloaded in the background.

While the script downloads from the CDN, all tracking of your page is queued. Once the downloaded script finishes asynchronously initializing, all events that were queued are tracked. As a result, you will not lose any telemetry during the entire life cycle of your page. This setup process provides your page with a seamless analytics system, invisible to your users.

Summary:

  • current npm version
  • gzip compressed size
  • ~15 ms overall initialization time
  • Zero tracking missed during life cycle of page

Module Formats

As part of packaging we produce umd (Universal Module Definition) modules using rollupjs which creates a wrapper that works for most users as it supports module loading and initialization with or without RequireJS.

However, there are some cases where your code doesn't directly use RequireJS but it is loaded into the runtime environment before your code and the 1DS SDK, in these cases the rollupjs wrapper registers (defines) but does not initialize (execute) the SDK and instead waits for the first to call "require()" before the module is executed

eg. var aiSdk = require("@microsoft/applicationinsights-web");

This situation can also occur when the scripts are loaded lazily, late or dynamically (and RequireJs is present) as this can cause a race condition between the SDK and RequireJS, which will cause the same issue if RequireJS is loaded first.

If users load Application Insights from the CDN via a script tag with require js running by other scripts, errors may occur. A typical error could be "Error: Mismatched anonymous define() module". The root reason is explained here.

To support this usage pattern we also produce and publish to the CDN endpoints an iife (Immediately Invoked Function Expression) module so that the SDK is always executed and initialized.

To use these modules instead of using the default script name simply add .gbl before the .min.js eg. use .gbl.min.js instead of .min.js at the end of the script name. (Note: Since version 7, the gbl modules is set as default module to solve the potential problem caused by require.js)

These modules are also included in the NPM packages within the bundle folder.

Example (not complete) CDN paths for the current major version.

Module Default Module (Supports loading via requireJs) IIFE Module
AISku
(Main Sdk)
http://js.monitor.azure.com/scripts/b/ai.3.min.js
http://js.monitor.azure.com/scripts/b/ai.2.min.js
http://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js
http://js.monitor.azure.com/scripts/b/ai.2.gbl.min.js
Click Analytics Extension http://js.monitor.azure.com/scripts/b/ext/ai.clck.3.min.js
http://js.monitor.azure.com/scripts/b/ext/ai.clck.2.min.js
http://js.monitor.azure.com/scripts/b/ext/ai.clck.3.gbl.min.js
http://js.monitor.azure.com/scripts/b/ext/ai.clck.2.gbl.min.js
Debug Plugin Extension http://js.monitor.azure.com/scripts/b/ext/ai.dbg.3.min.js
http://js.monitor.azure.com/scripts/b/ext/ai.dbg.2.min.js
http://js.monitor.azure.com/scripts/b/ext/ai.dbg.3.gbl.min.js
http://js.monitor.azure.com/scripts/b/ext/ai.dbg.2.gbl.min.js
Perf Mark/Measure Manager Extension http://js.monitor.azure.com/scripts/b/ext/ai.prfmm-mgr.3.min.js
http://js.monitor.azure.com/scripts/b/ext/ai.prfmm-mgr.2.min.js
http://js.monitor.azure.com/scripts/b/ext/ai.prfmm-mgr.3.gbl.min.js
http://js.monitor.azure.com/scripts/b/ext/ai.prfmm-mgr.2.gbl.min.js

As part of the CDN deployment and promoting new versions as the default we also provide both minor and explicit versions of all modules, so each published module will also include the following versions and formats. The example names are assuming version 3 as the current major version and 3.1 and the current minor.

Major Minor Patch (Explicit) Description
ai.3.min.js
ai.2.min.js
ai.3.0.min.js
ai.2.8.min.js
ai.3.0.2.min.js
ai.2.8.16.min.js
Minified UMD version
ai.3.gbl.min.js
ai.2.gbl.min.js
ai.3.0.gbl.min.js
ai.2.8.gbl.min.js
ai.3.0.2.gbl.min.js
ai.2.8.16.gbl.min.js
Minified IIFE version
(Recommended for v3.x)

And the process of Promoting (or rolling back) a deployed version is simply a case of replacing the major and minor version of the script with the current explicit version

CDN Debugging support

We support 2 basic approaches for debugging the SDK via the CDN hosted scripts

  • Every Module includes a //# sourceMappingURL=xxxx at the end of the file and has the referenced map file uploaded to the CDN.
  • We also publish unminified versions of every module, just drop the .min from the script name (eg. https://js.monitor.azure.com/scripts/b/ai.3.gbl.js)
Major Minor Patch (Explicit) Description
ai.3.min.js.map
ai.2.min.js.map
ai.3.0.min.js.map
ai.2.8.min.js.map
ai.3.0.2.min.js.map
ai.2.8.16.min.js.map
Map file for the UMD versions
ai.3.gbl.min.js.map
ai.2.gbl.min.js.map
ai.3.0.gbl.min.js.map
ai.2.8.gbl.min.js.map
ai.3.0.2.gbl.min.js.map
ai.2.8.16.gbl.min.js.map
Map file for the IIFE versions
ai.3.js
ai.2.js
ai.3.0.js
ai.2.8.js
ai.3.0.2.js
ai.2.8.16.js
Unminified UMD versions
ai.3.gbl.js
ai.2.gbl.js
ai.3.0.gbl.js
ai.2.8.gbl.js
ai.3.0.2.gbl.js
ai.2.8.16.gbl.js
Unminified IIFE versions

Nightly Builds

To aid with testing and validation we also produce and publish nightly builds whenever there is a change from the previous build. These builds are published to the NpmJs registry and to the CDN automatically on a successful build / test pass.

This process also tags the source code so that we can track the specific changes included using a nightly build specific version number which is the format "nightly-yymm-##" eg. nightly-2112-08

These nightly builds will not be retained indefinitely and should only be used for pre-production testing and/or validation of any changes that have not yet been released.

NPM

The NPM builds are tagged as "nightly" and can by downloaded using this as the version number npm install @microsoft/applicationinsights-web@nightly or using the nightly specific version number which is "nightly.yyyymm-###" (npm install @microsoft/[email protected]) where ## is the specific build number for the month (Note, slightly different version from the source code tag due to compatibility issues between the different systems).

CDN

These nightly builds are also uploaded to a different path on the CDN and explicitly have the -nightly added to the module name eg. /nightly/ai.2-nightly.min.js, each nightly build is re-numbered assuming the next release will be a patch release. So if the last release was 2.7.2, then all nightly builds will be numbered 2.7.3-nightly.

So to access simply update the URL used when downloading the required module.

Module Nightly Build
AISku (Main Sdk) http://js.monitor.azure.com/nightly/ai.2-nightly.min.js
Click Analytics Extension http://js.monitor.azure.com/nightly/ext/ai.clck.2-nightly.min.js
Debug Plugin Extension http://js.monitor.azure.com/nightly/ext/ai.dbg.2-nightly.min.js
Perf Mark/Measure Manager Extension http://js.monitor.azure.com/nightly/ext/ai.prfmm-mgr.2-nightly.min.js

As with the normal release process the nightly builds also include major, minor, explicit, IIFE (.gbl), *.map and unminified versions, these are primarily available for validating changes between builds.

Module CDN Path
Major http://js.monitor.azure.com/nightly/ai.2-nightly.min.js
http://js.monitor.azure.com/nightly/ai.2-nightly.gbl.min.js
http://js.monitor.azure.com/nightly/ai.2-nightly.js
http://js.monitor.azure.com/nightly/ai.2-nightly.gbl.js
Minor http://js.monitor.azure.com/nightly/ai.2.7-nightly.min.js
http://js.monitor.azure.com/nightly/ai.2.7-nightly.gbl.min.js
http://js.monitor.azure.com/nightly/ai.2.7-nightly.js
http://js.monitor.azure.com/nightly/ai.2.7-nightly.gbl.js
Explicit http://js.monitor.azure.com/nightly/ai.2.7.3-nightly.2112-08.min.js
http://js.monitor.azure.com/nightly/ai.2.7.3-nightly.2112-08.gbl.min.js
http://js.monitor.azure.com/nightly/ai.2.7.3-nightly.2112-08.js
http://js.monitor.azure.com/nightly/ai.2.7.3-nightly.2112-08.gbl.js

Deployment process and alternate CDN endpoints

When a new release is deployed the following occurs as part of the release

  • NPM packages are created and published to NpmJs
  • The new explicit versioned files (eg. ai.2.7.2.js; ai.2.7.2.min.js; ai.2.7.2.gbl.min.js; ai.2.7.2.min.js.map; etc) are uploaded to all cdn endpoints URL's (public, next and beta - details below)
  • We then go through a deployment process of "promoting" the new version to the "Major" (ai.3.gbl.min.js) and "Minor" (ai.3.x.gbl.min.js) release URL's to upgrade everyone to the newly released version based on the schedule listed below
Endpoint Url Schedule
Beta https://js.monitor.azure.com/beta/ai.3.gbl.min.js Same day as the NPM release
Next https://js.monitor.azure.com/next/ai.3.gbl.min.js One additional work day after the beta URL promotion.
Public https://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js Another One additional work day after the next URL promotion, (so 2 work days after initial release) unless this falls on the last work day of the week (eg. Friday) in which case it will be delayed until the first work day of the next work week.

The milestones for each release should include both the deployment plan (as it's about to be released) or the final release times as with v2.7.2

It is expected that most users will be using the Public URL, however, it is also recommended that if you have a test or canary environment that you should use either the beta or next URL's so that you would be alerted first before any production users are impacted. If any issues are detected with the beta or next URL's as a new release is being deployed please raise a new Issue as soon as this is confirmed.

Release Notes

Browser Support

  • ES5 Compliant browsers
Chrome Firefox IE Opera Safari
Latest ✔ Latest ✔ 9+ Full ✔ Latest ✔ Latest ✔

v3.x removed ES3 / IE8, if you need to retain ES3 (IE8) compatibility you will need to remain on the v2.x versions of the SDK. Which is now maintained on the old master branch

Build and Test this Project

Note: With the recent update to the latest version of rush npm run build fails with exit code 1 on successful build, hence the addition of --silent to the npm run build command.

npm install -g @microsoft/rush
npm install
npm run build --silent

Submitting a Change to this Project

<...added some code...>
rush change
<...enter details>
git add <...your changes and rush change file...>
git commit -m "info about your change"
git push

Contributing

Read our contributing guide to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to Application Insights.

Data Collection

As this SDK is designed to enable applications to perform data collection which is sent to the Microsoft collection endpoints the following is required to identify our privacy statement.

The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.

Trademarks

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft’s Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party’s policies.

License

MIT

applicationinsights-js's People

Contributors

aaronpowell avatar abaranch avatar alexbulankou avatar ameyagholkar avatar assaf-neufeld avatar bl-slalom avatar dfederm avatar dnduffy avatar florianchevallier avatar fudgepop01 avatar giladsu avatar hectorhdzg avatar itherael avatar iusafaro avatar jorupp avatar jpiyali avatar kamilszostak avatar karlie-777 avatar kartang avatar kryalama avatar markwolff avatar maxshehovtsov avatar msnev avatar olegsych avatar osvaldorosado avatar ramthi avatar regexrowboat avatar siyuniu-ms avatar stewartadam avatar xiao-lix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

applicationinsights-js's Issues

enable GZIP

Mainly for following the best practices (as perf gain is minimal - 70ms or 40KB)

IE10 - Telemetry failing to send

No page view or event data is being returned by my site when viewed from IE10. Requests are still being reported.

I have noticed that when using IE10, telemetry is failing to send. You get similar issues to below reported. Tested in IE8, IE9,IE11, latest Chrome and firefox.

Custom lib location:

Telemetry transmission failed, some telemetry will be lost: [object Error]{ stack: 'Error: Access is denied.

at _xhrSender (https://[blah].azurewebsites.net/scripts/lib/ai.0.15.0-build58334.min.js:1:22545)
at triggerSend (https://[blah].azurewebsites.net/scripts/lib/ai.0.15.0-build58334.min.js:1:22215)
at Anonymous function (https://[blah].azurewebsites.net/scripts/lib/ai.0.15.0-build58334.min.js:1:21643)', message: 'Access is denied.
', name: 'Error'

No lib specified:

AI (Internal): Telemetry transmission failed, some telemetry will be lost: Error properties: {"exception":"[object Error]{ stack: 'Error: Access is denied.\r\n\n at open (https://az416426.vo.msecnd.net/scripts/a/ai.0.js:1:11217)\n at _xhrSender (https://az416426.vo.msecnd.net/scripts/a/ai.0.js:1:34476)\n at triggerSend (https://az416426.vo.msecnd.net/scripts/a/ai.0.js:1:33992)\n at flush (https://az416426.vo.msecnd.net/scripts/a/ai.0.js:1:69470)\n at Anonymous function (https://az416426.vo.msecnd.net/scripts/a/ai.0.js:1:58106)', message: 'Access is denied.\r\n', name: 'Error'"}

I'm using a plain VS 2015 - ASP.NET MVC template site and hosting in Azure.

sanitizeString: Object doesn't support property or method 'substring'

Maximum ajax per page view limit reached message is sent on every page view

We are currently sending this trace message once per view

else if (this._trackAjaxAttempts === this.config.maxAjaxCallsPerView) {                
 -                _InternalLogging.throwInternalUserActionable(LoggingSeverity.CRITICAL,         +                _InternalLogging.throwInternalUserActionable(LoggingSeverity.CRITICAL, new _InternalLogMessage(
 -                    "Maximum ajax per page view limit reached, ajax monitoring is paused until the next trackPageView(). In order to increase the limit set the maxAjaxCallsPerView configuration parameter.");        +                    "Maximum ajax per page view limit reached, ajax monitoring is paused until the next trackPageView(). In order to increase the limit set the maxAjaxCallsPerView configuration parameter."));

I think we should send it once per session. @MaxShehovtsov's notes that this will make it harder to diagnose, however since the message is intended for application author (the one who is looking at telemetry in the portal) and not for end-user, once per session will be enough for application author to diagnose the issue.
So I would like to add a flag to sessionStorage once we send this trace message.

Provide an out of the box solution to enable cookie tracking only after user accepted cookie policy

This will be useful in European countries wher websites need to obey the "cookie law" (more: https://www.cookielaw.org/the-cookie-law/).

Sample scenario:

  1. User navigates to a website
  2. User accepts cookie policy
  3. User navigates to a subpage

In such case we should track 1) and 3) as separate sessions. I'm also not sure if we can set a cookie during the 1) request when user has not accepted the policy yet.

Huge page load time

Some customers see page views with huge durations. It's around 0.02% of all page views.

Trace Message: AI (Internal): Telemetry transmission failed, some telemetry will be lost

I've stumbled upon some strange traces logged by AI js SDK. And it all happens on IE 11 browser

AI (Internal): Telemetry transmission failed, some telemetry will be lost: [object Error]{ stack: 'Error: Not enough storage is available to complete this operation.

at t.prototype._xhrSender (https://az416426.vo.msecnd.net/scripts/a/ai.0.js:1:30534)
at t.prototype.triggerSend (https://az416426.vo.msecnd.net/scripts/a/ai.0.js:1:29875)
at Anonymous function (https://az416426.vo.msecnd.net/scripts/a/ai.0.js:1:29278)', message: 'Not enough storage is available to complete this operation.
', name: 'Error'

ai internal-telemetry transmission failed

Root operation life cycle across client-server boundary

I wanted to follow up from our discussion yesterday and propose a default lifetime model for root operations when crossing server-client boundary.

These are the basic rules:
1. Every client to server request starts new root operation
2. Server to server request does not start a new operation
3. When new physical page is initialized by the client, all telemetry logged by this page has root operation of the server request that served the page.
4. New virtual pages (user calling trackPageView() ) does not change root operation

During the discussion yesterday we considered an idea of every call to trackPageView() initializing new root operation and having subsequent operations be rooted to it. However at a given point of time client does not have a single active page, instead there could be multiple panels (consider OWA with task list, email list, new email panel opened) and opening of each new panel is likely recorded by a call to trackPageView().

Here's a diagram showing client->server->RDD interaction with distinct root operations color-coded:

image

What it means that by default if we take all telemetry for a root operation ID, we should be able to produce a topology diagram that includes page request, RDD requests needed to render the page and client-side telemetry logged by the page after it was served to the client. However it will not include AJAX requests initiated by this page.

We should consider allowing user to override this default behavior and pass root operation ID with AJAX requests, which will result in the following model:
image

Note that with this model, for a long-running single page app root operation ID becomes equivalent to session ID. I believe this should not be the default model, but there should be a way to implement it if needed.

Log verb (GET/POST) as part of AJAX name

The new ajax dependency tracking is awesome, but the dependency naming convention could be improved. Right now it looks like it is always the hostname of the AJAX request.

image

I feel like SQL dependencies, for example, have a much better naming convention, which is:
SQL: ServerName | DatabaseName | StoredProcedureName

The reporting on things like dependencies with performance problems is much more useful when the name has more context. It also helps a lot when browsing search results. Perhaps you could add the HTTP method and the relative URL to the dependency name?

Device Info not getting captured in UWP App

In our UWP App, AppInsight does not auto captures "Device Information". Below are parameters that should get auto populated:

  1. ContextDeviceOemName (e.g Hewlett-Packard, Dell Inc.)
  2. ContextDeviceDeviceModel (e.g HP Z230 SFF Workstation, XPS 12 9Q23)
  3. ContextDeviceScreenResolutionValue
  4. ContextDeviceType

I know, we will be able to set this manually using below code, but getting these values in UWP seems challenging.

        appInsights.context.device.oemName = "YOUR OEM NAME";
        appInsights.context.device.model = "YOUR MODEL";
        appInsights.context.device.resolution= "YOUR MODEL";
        appInsights.context.device.type = "YOUR TYPE";

track request takes too much time

Sometimes the track operation takes relatively very long time to complete and other requests are blocked till track completes.
long track
Testing on Windows 10, IE version 11.162.10586.

Is there any way to take this request from critical path?

trackMetric does not support setting custom properties

Unlike the .NET library, this library does not allow you to pass in additional properties to the .trackMetric function.

You can do it for the other types of telemetry like events and dependencies, but not metrics.

ContractsModule.Contracts.MetricData object has a spot for properties, so doesn't seem like it would break the model.

Telemetry data is lost when telemetry API calls fail

It appears that when sending telemetry to the app insights API fails, the telemetry is completely lost. I think there would be a lot of benefit in a store and forward model (write telemetry out to local storage first, attempt to send it after).

TrackEvent on onClick does not send the telemetry

Hello,

I have a tracking event on click of a simple link () that is added by JQuery on onClick event.
$('#xyz').click(function () {
appInsights.trackEvent("NameHere",
{ LinkDestination: "Go/Here", TypeButton: "GreenButton" }
);
});

This does not write the event in AppInsight. However, if I copy-paste it in Chrome's console. I can see the event in Azure portal. I suspect that the click of the link is so fast to go to the target page that the trackEvent does not have the time to send the event to AppInsight server. Is that a bug or a misuse of trackEvent and link?

Allow the tracking cookies to operate across subdomains

It would be useful to have the tracking cookies ai and ai_user visible on all subdomains for a given application.

This would allow support for apps where the js based front end is served from one domain - say www.example.com and the back-end also collects telemetry and is served from, for example api.example.com.

Having browsed through the code, it looks like this isn't currently a supported scenario. Perhaps having this domain configurable would be a win.

When I "enableDebug" for ASP.Net MVC5 app, I get a javascript assert - client performance math error: 831

I followed the steps here:
http://azure.microsoft.com/en-us/documentation/articles/app-insights-api-custom-events-metrics/#track-event to enable app insights for my ASP.Net MVC5 app. Everything works except when I try to enable developer mode with this code:
// Insert this in the initialization script, just before trackPageView:
appInsights.config.enableDebug = true;

When I add that line of code and hit F5 (start debugging) in Visual studio, I hit the attached exception.
javascript

Add ability to set the session cookie's domain

We have a site that spans two sub-domains. We can't join user session specific telemetry from the two domains unless the ai_session cookie can be set for the root domain.

It would be great if we could set something like config.sessionCookieDomain to solve the problem.

Support ajax monitoring

Ajax calls are instrumented by overriding prototype.open and prototype.send functions, and onreadystatechange event handler of XMLHttpRequest.

This is an entrypoint for ajax auto collection: https://github.com/Microsoft/ApplicationInsights-JS/blob/master/JavaScript/JavaScriptSDK/ajax/ajax.ts

Below is the ajax monitoring sequence chart:

  • XHR – an instance of XMLHttpRequest
  • User-defined callbacks – while appInsights subscribes (‘attaches’) to XMLHttpRequest.onreadystatechange event there might be other event handlers before or after (if user subscribed before or after initialization of appInsights object).
  • AjaxMonitor and AjaxRecord are the new appInsights entities added for supporting ajax monitoring.
  • AppInsights is the object exposing our public API (trackXXX methods) and initializing javascript monitoring.

Page crash iOS Safari in Private mode: infinite loop SessionStorage read warning

As of a few weeks ago, user reported issue with iOS Safari in Private mode. Normal mode works fine.

When loading the page with the AI script, the browser reports eventually in a message bar:
A problem occured with this webpage so it was reloaded.
and the page content has only the message:
A problem repeatedly occurred on "<URL>"..

Reproduced with Browserstack real browser on various devices and on my own iPhone.

The console log has repeatedly this message (up to 6400 times):

ai.0.js:1 AI (Internal): NONUSRACT_BrowserCannotWriteSessionStorage message:"Browser failed write to session storage. " props:"{exception:[object DOMException]{\code\:22,\name\:\QuotaExceededError\,\message\:\QuotaExceededError: DOM Exception 22\,\line\:1,\column\:16686,\sourceURL\:\https://az416426.vo.msecnd.net/scripts/a/ai.0.js\}}"

When Safari is in Private mode it doesn't allow to read session storage.

The AI code has a try/catch around that, but somehow the attempt is repeated.

ai safari private infinite loop

how to import ai.0.21.5-build00175.js file

I have download the package from nuget. It creates a file called ai.0.21.5-build00175.js. I couldnt find any sample html code about how to include this on my html code. All of them show examples for using the cdn. How do I use my local version?

Extract unit tests for TelemetryContext from AppInsightsTests to a new test class

TelemetryContext.track method contains a lot of complex logic, however, we don't have unit tests for it. It appears we are testing it through the AppInsights.track methods in the AppInsightsTests class. Here is an example of such tests:

this.testCase({
    name: "AppInsightsTests: application context is applied",
    test: () => {
        // setup
        var appInsights = new Microsoft.ApplicationInsights.AppInsights(this.getAppInsightsSnippet());
        appInsights.context._sessionManager._sessionHandler = null;
        appInsights.context.application.ver = "101";
        appInsights.context.application.build = "101";
        var trackStub = sinon.stub(appInsights.context._sender, "send");

        // verify
        var test = (action) => {
            action();
            this.clock.tick(1);
            var envelope = this.getFirstResult(action, trackStub);
            var contextKeys = new AI.ContextTagKeys();
            Assert.equal("101", envelope.tags[contextKeys.applicationVersion], "application.ver");
            Assert.equal("101", envelope.tags[contextKeys.applicationBuild], "application.build");
            trackStub.reset();
        };

        // act
        test(() => appInsights.trackEvent("testEvent"));
        test(() => appInsights.trackPageView());
        test(() => appInsights.trackMetric("testMetric", 0));
        test(() => appInsights.trackException(new Error()));
        test(() => appInsights.trackTrace("testTrace"));

        // teardown
        trackStub.restore();
    }
});

Notice how complex a test for TelemetryContext has to be here - it needs to use a sinon.stub to intercept send calls in order to inspect envelope.tags. It also has to call multiple track methods to ensure all paths to send are covered. When we add new methods, such as trackDependency, all of tests like this will have to be updated to call the new method ass well.

We can significantly simplify AppInsightsTests by introducing TelemetryContextTests to verify the TelemetryContext.track method separately. With that done, we only need to check that AppInsights.track methods call TelemetryContext.track, so a lot of these tests could be deleted.

Can't send exceptions with empty method

Currently we may end up with an empty method for a stack frame in exception telemetry item. This may happen if error is thrown inside a global scope.
The suggestion is to report "Global scope" or "Unknown" or something like that as a method name in this case

Always send 1 client perf per page load

Per this comment - e0ea11d

We want to make an internal flag that allows us:

  1. to make sure at least 1 client perf is sent
  2. to make sure no more than 1 client perf is sent even if there are multiple calls of trackPageView

Single Page Apps

trackPageView correctly uses performance.timing, however for SPA using xhr this is always first page load time. Use of Resource Timing can get round this.

PerformanceTiming

{connectEnd: 1429922346337
connectStart: 1429922346216
domComplete: 1429922378350
domContentLoadedEventEnd: 1429922378038
domContentLoadedEventStart: 1429922378028
domInteractive: 1429922378028
domLoading: 1429922377408
domainLookupEnd: 1429922346216
domainLookupStart: 1429922346216
fetchStart: 1429922346215
loadEventEnd: 1429922378361
loadEventStart: 1429922378350
navigationStart: 1429922345941
redirectEnd: 0
redirectStart: 0
requestStart: 1429922346337
responseEnd: 1429922377776
responseStart: 1429922377406
secureConnectionStart: 0
unloadEventEnd: 0
unloadEventStart: 0}

PerformanceResourceTiming

{connectEnd: 0
connectStart: 0
domainLookupEnd: 0
domainLookupStart: 0
duration: 13486.342999996617
entryType: "resource"
fetchStart: 10071187.829000002
initiatorType: "xmlhttprequest"
name: "http://..../"
redirectEnd: 0
redirectStart: 0
requestStart: 0
responseEnd: 10084674.171999998
responseStart: 0
secureConnectionStart: 0
startTime: 10071187.829000002}

However that's also a little messy in that you need to search though it to find your xhr page load and it has everything in it, images, xhr (including dc.services.visualstudio.com/v2/track) etc so you need to pick out the correct one. Also you need to periodically clear the buffer when it gets full to add more recent stuff (e.g. 150 items in chrome):

if (window.performance) {
    if (performance.clearResourceTimings) {
        performance.clearResourceTimings();
    } else if (performance.webkitClearResourceTimings) {
        performance.webkitClearResourceTimings()
    }
}

Equally, the user will need to manually calculate the domProcessing, perhaps using setImmedate or polyfill for it. So there isn't an immediate "this is the right way solution" that I can think of that can be automated, without bundling it into the xhr loader + page updater.

However... all the the properties of Telemetry.PageViewPerformance can be calculated so it would be useful to be able to pass in a PageViewPerformance either to trackPageView or a new function trackDataLoad e.g.

public trackPageView(name?: string, url?: string, 
    properties?: Object, measurements?: Object, 
    timings?: PageViewPerformance) {

That it would use instead of new Telemetry.PageViewPerformance when provided?

should prefix.js fall back to https if loaded from file:// uri?

from this stack overflow: http://stackoverflow.com/questions/33952511/microsoft-application-insights-on-cordova-requests-goes-to-file/34230709#34230709

the default prefix/snippet doesn't specify a protocol, falling back to whatever the page got loaded from (presumably so http gets the ai script also via http, and https sites get the script via https so there's no "unsecure content" errors or warnings.

however, if you use the example from a file:// based source, like a cordova app in the stack overflow question above, it also tries to load / submit data to:

file:// dc.services.visualstudio.com/v2/track

instead of using https. should there be code in the snippet to fall back to https when sending data to DC even if the source was loaded from a file:// uri?

Support telemetry filtering

I think it would be useful to have filtering/masking capability (like the .NET TelemetryProcessor). I would use this to filter out specific AJAX dependency calls (by hostname) with the built-in AJAX dependency tracking.

Api Reference: remove autoCollectErrors, add disableExceptionTracking

autoCollectErrors seems to not exist in the SDK, however the docs say that it controlls automatic exception tracking (which actually does not).
On other hand the disableExceptionTracking setting is the one that controls automatic exception collection, and it's not mentioned in the api reference.

support for vs2015?

I realize the instructions say use vs2013, but is there support for vs2015? Or plans to support it?

WireDep Issues

I'm using WireDep to automatically grab all of my bower packages and inject them into my application. https://github.com/taptapship/wiredep

It is not finding this library. They require that an application define its dependencies and have a main property in it's bower.json file. I tried hardcoding these, but have been unsuccessfuly in getting it to recognize.

Has anyone else came across this issue before?

IConfig.appUserId appears to be unused?

Not sure if I'm missing something subtle here, but while looking at some of the API docs and the code itself, IConfig.appUserId appears to be set in a few places, but never actually read. I had assumed, due to its proximity to IConfig.accountId, that it was related to AppInsights.setAuthenticatedUserContext, but it appears to not be the case.

If this is indeed dead code, I'd be happy to submit a PR to clean it up. If it's not dead code, I'm prepared to be enlightened. Thanks either way! :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.