diff --git a/README.md b/README.md index 7a3401204..574fa16a0 100644 --- a/README.md +++ b/README.md @@ -71,15 +71,43 @@ cfg: { // Application Insights Configuration ``` -The snippet supports reporting sdk script load failures as exceptions to the portal, this type of error would cause your application/website to either not report any telemetry or in some extreme cases become unstable due to excessive queuing of events which are never sent. +> :bulb: **Note** +> +> 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. + +#### 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](docs/SdkLoadFailure.md) 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](https://github.com/microsoft/ApplicationInsights-JS/blob/master/AISKU/snippet/snippet.js) as a starting point. + +> :bulb: **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 -It also supports some additional snippet specific configuration. - - src (string) [required] - The URL of the SDK version to load - - name (string) [optional] - The global SDK instance name to use, defaults to appInsights - - 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 just add a script tag to the page head and will block the page load event. - - useXhr (boolean) [optional] - This setting is specifically for the reporting of SDK load failures. Reporting will first use fetch() if available and then fallback to XHR, setting this value to true just bypasses the fetch check. Use of this value would only be required if you know your app/site 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 used 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 https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) - - cfg (object) - This is the Application Insights configuration that is used to initialize your sdk. +| 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=```, 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](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) documentation) +| cfg | object **[required]** | THe configuration passed to the Application Insights SDK during initialization. ### Connection String Setup @@ -126,9 +154,9 @@ 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", {customProp1: "some value"}); +appInsights.stopTrackPage("pageName", null, {customProp1: "some value"}); appInsights.startTrackEvent("event"); -appInsights.stopTrackEvent("event", {customProp1: "some value"}); +appInsights.stopTrackEvent("event", null, {customProp1: "some value"}); appInsights.flush(); ``` @@ -379,7 +407,8 @@ While the script downloads from the CDN, all tracking of your page is queued. On > Summary: > -> - **~28 KB** gzipped +> - ![current npm version](https://badge.fury.io/js/%40microsoft%2Fapplicationinsights-web.svg) +> - ![gzip compressed size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.min.js.svg?compression=gzip) > - **15 ms** overall initialization time > - **Zero** tracking missed during life cycle of page diff --git a/docs/SdkLoadFailure.md b/docs/SdkLoadFailure.md new file mode 100644 index 000000000..1f02b3eb8 --- /dev/null +++ b/docs/SdkLoadFailure.md @@ -0,0 +1,131 @@ +# SDK Load Failure: Failed to load Application Insights SDK script (see stack for details) + +This exception is created and reported by the snippet (v3 or later) when it detects that the SDK script failed to download or initialize. Simplistically, your end users client (browser) was unable to download the Application Insights SDK, or initialize from the identified hosting page and therefore no telemetry or events will be reported. + +

Azure portal browser failure overview

+ +> :bulb: **Note** +> +> This exception is supported on all major browsers that support the fetch() API or XMLHttpRequest, this therefore explicitly excludes IE 8 and below, so you will not get this type of exception reported from those browsers (unless your environment includes a fetch polyfill). + +## What does this exception mean? + +There are many possible reasons for this exception to be reported, we will cover some of the known issues as well the details to diagnose the root cause of the problem. + +

browser exception detail

+ +The stack details include the basic information with the URLs being used by the end user and is formatted as below + +> SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details)
+> Snippet failed to load [__<CDN Endpoint>__] -- Telemetry is disabled
+> Help Link: __<Help Link>__
+> Host: __<Host URL>__
+> Endpoint: __<Endpoint URL>__
+ +| Name | Description +|----------------------|------------ +| <CDN Endpoint> | The URL that was used (and failed) to download the SDK +| <Help Link> | A help link URL that links to this page +| <Host URL> | The complete URL of the page that the end user was using +| <Endpoint URL> | The URL that was used to report the exception, this value may be helpful in identifying whether the hosting page was accessed from the public internet or a private cloud. + +## Why did this exception occur? + +There are many possible reasons for this exception to be reported, and the most common ones are described below with links to corresponding troubleshooting steps. + +> :bulb: **Note** +> +> Several of the Troubleshooting steps assume that your application has direct control of the Snippet <script /> tag and it's configuration that are returned as part of the hosting HTML page. If you don't then those identified steps will not apply for your scenario. + +## The Application Insights JS CDN has been blocked + +While typically NOT the cause for this exception, we recommend you rule it out first since there are limited options for you or your end users and may require immediate external assistance. + +### Troubleshooting + +- [Check if the CDN has been blocked](SdkLoadFailureSteps.md#cdn-blocked) +- [Change the URL used to download the SDK](SdkLoadFailureSteps.md#change-the-cdn-endpoint) +- [Host the SDK on you own CDN](SdkLoadFailureSteps.md#host-sdk) +- [Use NPM packages to embed the Application Insights SDK](SdkLoadFailureSteps.md#use-npm). + +## Intermittent network connectivity failure + +This is the most common reason for seeing this exception, though it may seem largely out of the developer's control. It's especially common in a mobile roaming scenario where the user looses network connectivity intermittently. + +To minimize this issue, we have implemented Cache-Control headers on all of the CDN files so that once the end users browser has downloaded the current version of the SDK it will not need to downloaded again and the browser will reuse the previously obtained copy (see [How caching works](https://docs.microsoft.com/azure/cdn/cdn-how-caching-works)). If the caching check fails or there has been a new release, then your end users browser will need and download the updated version, so you may see a background level of _"noise"_ in the check failure scenario or a temporary spike when a new release occurs and is made generally available (deployed to the CDN). + +If this exception is persistent and is occurring across many of your users (diagnosed by a rapid and sustained level of this exception being reported) along with a reduction in normal client telemetry, then intermittent network connectivity issues is _not-likely_ to be the true cause of the problem and you should continue diagnosing with the other known possible issues below. + +### Troubleshooting + +- [Intermittent Network failure](SdkLoadFailureSteps.md#intermittent-network-failure) +- [Use NPM packages to embed the Application Insights SDK](SdkLoadFailureSteps.md#use-npm). + +> :bulb: **Note** +> +> Due to the caching headers on the CDN files and depending on how often and when your users access your site, not all of them will attempt to download the newer version at the same point in time, so reports may be staggered. + +## Application Insights JS CDN is blocked (by End User - blocked by browser; installed blocker; Personal firewall) + +Check if your end users have installed: - +- a browser plug-in (typically some form of Ad/Malware/Popup blocker); +- blocked (or not allowed) the Application Insights CDN endpoints in their browser or proxy; +- or configured a firewall rule that is causing the CDN domain for the SDK to be blocked (or the DNS entry to not be resolved). + +If they have configured any of these options, you will need to work with them (or provide documentation) to allow the CDN endpoints. + +It is also possible that the plug-in they have installed is using the [public blocklisting](SdkLoadFailureSteps.md#cdn-blocked), which is why that option is listed first, if you get here then it's most likely some other manually configured solution or it's using a private domain blocklisting. + +### Troubleshooting + +- [Check if CDN has been blocked](SdkLoadFailureSteps.md#cdn-blocked) +- [Change the URL used to download the SDK](SdkLoadFailureSteps.md#change-the-cdn-endpoint) +- [Add exceptions for CDN endpoints](SdkLoadFailureSteps.md#add-exceptions-for-cdn-endpoints) +- [Host the SDK on you own CDN](SdkLoadFailureSteps.md#host-sdk) +- [Use NPM packages to embed the Application Insights SDK](SdkLoadFailureSteps.md#use-npm). + +> :bulb: **Note** +> +> For this exception to be reported, they would not be blocking the reporting endpoint (otherwise you would not see the exception). + +## Application Insights CDN is blocked (by Corporate firewall) + +If your end users are on a corporate network, then they are most likely behind some form of firewall solution and it's likely that their IT department has implemented some form of internet filtering system. In this case, you will need to work with them to allow the necessary rules for your end users. + +### Troubleshooting + +- [Check if CDN has been blocked](SdkLoadFailureSteps.md#cdn-blocked) +- [Change the URL used to download the SDK](SdkLoadFailureSteps.md#change-the-cdn-endpoint) +- [Add exceptions for CDN endpoints for corporations](SdkLoadFailureSteps.md#corporate-exceptions-for-cdn-endpoints) +- [Host the SDK on you own CDN](SdkLoadFailureSteps.md#host-sdk) +- [Use NPM packages to embed the Application Insights SDK](SdkLoadFailureSteps.md#use-npm). + +> :bulb: **Note** +> +> For this exception to be reported, they would not be blocking the reporting endpoint (otherwise you would not see the exception). + +## Application Insights CDN outage + +You can confirm this scenario by attempting to access the CDN endpoint directly from the browser (for example, https://az416426.vo.msecnd.net/scripts/b/ai.2.min.js) from a different location to that of your end users (probably from your own development machine - assuming that your organization has not blocked this domain). + +### Troubleshooting + +- [Create a support ticket](https://azure.microsoft.com/support/create-ticket/) with details of the outage and the CDN endpoint that is experiencing the issue. +- [Change the URL used to download the SDK](SdkLoadFailureSteps.md#change-the-cdn-endpoint) + +### SDK failed to initialize after loading the script + +There are several possible reasons that may cause the script to fail during initialization, when this occurs the SDK <script /> was successfully downloaded from the cdn but it fails during initialization. This issue can be because of one or more missing dependencies; invalid or some form of JavaScript exception. + +The first thing to check is whether the SDK was successfully downloaded, if the script was NOT downloaded then this scenario is __not__ the failing scenario. + +Quick check: Using a browser that supports Developer tools (F12), validate on the network tab that the script defined in the ```src``` snippet configuration was downloaded with a response code of 200 (success) or a 304 (not changed). You could also use a tool like fiddler to review the network traffic. + +### Troubleshooting + +- [SDK Failed to initialize](SdkLoadFailureSteps.md#sdk-failed-to-initialize) + +## Next steps +* [Get additional help by filing an issue on GitHub](https://github.com/Microsoft/ApplicationInsights-JS/issues) +* [Back to Snippet setup](../README.md#reporting-script-load-failures) + diff --git a/docs/SdkLoadFailureSteps.md b/docs/SdkLoadFailureSteps.md new file mode 100644 index 000000000..aff0be862 --- /dev/null +++ b/docs/SdkLoadFailureSteps.md @@ -0,0 +1,137 @@ +# SDK Load Failure: Troubleshooting steps + +## CDN Blocked + +This situation is possible when an Application Insights JS SDK CDN endpoint has been reported and/or identified as being unsafe for some reason. When this occurs, it will cause the endpoint to be publicly block-listed and consumers of these lists will begin to block all access. +Resolving this requires the owner of the CDN endpoint to work with the block-listing entity that has marked the endpoint as unsafe so that it can be removed from the relevant list. + +Check if the CDN endpoint has been identified as unsafe. +- [Google Transparency Report](https://transparencyreport.google.com/safe-browsing/search) +- [VirusTotal](https://www.virustotal.com/gui/home/url) +- [Sucuri SiteCheck](https://sitecheck.sucuri.net/) + +Depending on the frequency that the application, firewall or environment update their local copies of these lists, it may take a considerable amount of time and/or require manual intervention by end users or corporate IT departments to force an update or explicitly allow the CDN endpoints to resolve the issue. + +If the CDN endpoint is identified as unsafe, please [create a support ticket](#create-a-support-ticket) with the required details to ensure that the issue is resolved as soon as possible. + +You may also want to consider [changing the SDK CDN endpoint](#change-the-cdn-endpoint) to _potentially_ bypass this issue more rapidly. + +## Intermittent Network Failure + +If the user is experiencing intermittent network connectivity failures, then there are fewer possible solutions and they will generally resolve themselves over a short period of time. For example, if the user reloads your site the files will (eventually) get downloaded and cached locally until an updated version is released. + +With this situation [Hosting the SDK on you own CDN](#host-sdk) is unlikely to provide or reduce the occurrences of this exception, as your own CDN will be affected by the same issue. + +The same is also true when [using the SDK via NPM packages](#use-npm) solution, however, from the end users perspective when this occurs your entire application fails to load / initialize (rather than _just_ the telemetry SDK - which they don't see visually), so they will most likely refresh your site until is loads completely. + +## Add Exceptions for CDN endpoints + +Work with your end users or provide documentation informing them that they should allow scripts from the Application Insights CDN endpoints to be downloaded by including them in their browsers plug-in or firewall rule exception list, this will vary based on the end users environment. + +Here is an example of how to configure within [Chrome to allow or block access to websites](https://support.google.com/chrome/a/answer/7532419?hl=en) + +## Corporate Exceptions for CDN endpoints + +This is similar to [adding exceptions for end users](#add-exceptions-for-cdn-endpoints), but you will need to work with your end users IT department to have them configure the Application Insights CDN endpoints to be downloaded by including (or removing) them in any domain block-listing or allow-listing services. + +> :warning: **Important** +> +> If the your corporate user is using a [private cloud](https://azure.microsoft.com/overview/what-is-a-private-cloud/) and they cannot enable any form of exception to provide their internal users with public access for the CDN endpoints then you will need to [use the NPM packages](#use-npm) or [host the Application Insights SDK on your own CDN](#host-sdk). + +## Change the CDN endpoint + +As the snippet and its configuration are returned by your application as part of each generated page, you can change the snippet `src` configuration to use a different URL for the SDK. By using this approach, you could bypass the [CDN Blocked](#cdn-blocked) issue as the new URL should not be blocked. + +Current Application Insights JavaScript SDK CDN endpoints +- https://az416426.vo.msecnd.net/scripts/b/ai.2.min.js +- https://js.monitor.azure.com/scripts/b/ai.2.min.js + +> :bulb: **Note** +> +> The https://js.monitor.azure.com/ endpoint is an alias that allows us to switch between CDN providers within approximately 5 minutes, without the need for you to change any config. This is to enable us to fix detected CDN related issues more rapidly if a CDN provider is having regional or global issues without requiring everyone to adjust their settings. + +## Use NPM + +Rather than using the snippet and public CDN endpoints you could use the NPM packages to include the SDK as part of your own JavaScript files. With this approach, the SDK will become just another package within your own scripts. Note: It is recommended that when using this approach, you should also use some form of [JavaScript bundler](https://www.bing.com/search?q=javascript+bundler) to assist with code splitting and minification. + +As with the snippet, it is also possible that your own scripts (with or without using the SDK NPM packages) could be affected by the same blocking issues listed here, so depending on your application, your users, and your framework you may want to consider implementing something similar to logic in the snippet to detect and report these issues. + +> :bulb: **Note** +> +> You will need to use this approach (or [Host the SDK on you own CDN](#host-sdk)) if your users are using a [private cloud](https://azure.microsoft.com/overview/what-is-a-private-cloud/) as they most likely will not have access to the public internet. + +## Host SDK + +Rather than your end users downloading the Application Insights SDK from the public CDN you could host the Application Insights SDK from your own CDN endpoint. If using this approach, it is recommended that you use a specific version (ai.2.#.#.min.js) so that it's easier to identify which version you are using, it is also recommended that update it on a regular basis to the current version (ai.2.min.js) so you can leverage any bug fixes and new features that become available. + +
+ +:bulb: __Note:__ You will need to use this approach (or [Use NPM packages](#use-npm)) if your users are using a [private cloud](https://azure.microsoft.com/overview/what-is-a-private-cloud/) as they most likely will not have access to the public internet. +
+ +## Create a support ticket + +Use the Azure Support portal to [create a new support ticket](https://azure.microsoft.com/support/create-ticket/) with details of the outage. + +> __Please include__ :- +> 1. If the detected failure is caused by block-listing from a public Anti-virus or block-listing provider, please include details of the provider. This will help in reducing the time required to get the issue resolved; +> 2. Checks / Validations that you have already performed; +> 3. The timeframe(s) of the reported issues; +> 4. The Expected SDK version # to be downloaded; +> 5. Stack details from the reported exception (as it includes the CDN endpoint, the hosting page URL and the endpoint used to report the exception); +> 6. The reported browser and if know the version of the browser/environment. +> --- + + +## SDK Failed to initialize + +We will assume that you have already validated that the SDK script was successfully downloaded. + +> Basic reporting rules: This section includes different reporting options, it will recommend either creating a support ticket or raising an issue on GitHub. +> - If the issue is only affecting a small number of users and more specifically a specific or subset of browser version(s) (check the details on the reported exception) then it's likely an end user or environment only issue which will probably require you application to provide additional polyfill implementations. For these please raise a GitHub issue. +> - If this issue is affecting your entire application and all of your users are affected then it's probably a release related issue and therefore you should create a support ticket. + +First lets check for JavaScript exceptions, using a browser that supports developer tools (F12) load the page and review if any exceptions occurred. + +If there are exceptions being reported in the SDK script (for example ai.2.min.js), then this may indicate that the configuration passed into the SDK contains unexpected or missing required configuration or a faulty release has been deployed to the CDN. + +To check for faulty configuration, change the configuration passed into the snippet (if not already) so that it only includes your instrumentation key as a string value + +> src: "https://az416426.vo.msecnd.net/scripts/b/ai.2.min.js",
+> cfg:{
+> instrumentationKey: "INSTRUMENTATION_KEY"
+> }});
+ +If when using this minimal configuration you are still seeing a JavaScript exception in the SDK script, please [create a support ticket](#create-a-support-ticket) with the details as this will require the faulty build to be rolled back as it's most likely an issue with a newly deployed version. + +If the exception disappears, then the issue is likely caused by a type mismatch or unexpected value, proceed to re-add your configuration options until the exception occurs again and then check the documentation for the item causing the issue. If the documentation is unclear or you need assistance, please [file an issue on GitHub](https://github.com/Microsoft/ApplicationInsights-JS/issues). + +If your configuration was previously deployed and working but just started reporting this exception, then it may be an issue with a newly deployed version, please check whether is affecting only a small set of your users / browser and either [file an issue on GitHub](https://github.com/Microsoft/ApplicationInsights-JS/issues) or [create a support ticket](#create-a-support-ticket). + +Assuming there are no exceptions being thrown the next step is to enabling console debugging by adding ```loggingLevelConsole``` setting to the configuration, this will send all initialization errors and warnings to the browsers console (normally available via the developer tools (F12)). Any reported errors should be self-explanatory and if you need further assistance [file an issue on GitHub](https://github.com/Microsoft/ApplicationInsights-JS/issues). +> cfg:{
+> instrumentationKey: "INSTRUMENTATION_KEY",
+> loggingLevelConsole: 2
+> }});
+ +> :bulb: **Note** +> +> During initialization the SDK performs some basic checks for known major dependencies, if these are not provided by the current runtime it will report the failures out as warning messages to the console, but only if the loggingLevelConsole is greater than zero. + +If it still fails to initialize, try enabling the ```enableDebug``` configuration setting, which will cause all internal errors to be thrown as an exception (which will cause telemetry to be lost), as this is a developer only setting it will probably get very noisy with exceptions getting thrown as part of some internal checks, so you will need to review each exception to determine which issue is causing the SDK to fail. Use the non-minified version of the script (note the extension below it's ".js" and not ".min.js") otherwise the exceptions will be unreadable. + +> :rotating_light: **WARNING:** +> +> This is a developer only setting and should NEVER be enabled in a full production environment as you will loose telemetry. + +> src: "https://az416426.vo.msecnd.net/scripts/b/ai.2.js",
+> cfg:{
+> instrumentationKey: "INSTRUMENTATION_KEY",
+> enableDebug: true
+> }});
+ +If this still does not provide any insights, you should [file an issue on GitHub](https://github.com/Microsoft/ApplicationInsights-JS/issues) with the details and if you have an example site that would be extremely useful. Please ensure to include the browser version, operating system, and JS framework details to help identify the issue. + +## Next steps +* [Get additional help by filing an issue on GitHub](https://github.com/Microsoft/ApplicationInsights-JS/issues) +* [SDK Load Failure details](SdkLoadFailure.md) diff --git a/docs/media/sdk-load-failure-exception.png b/docs/media/sdk-load-failure-exception.png new file mode 100644 index 000000000..7b24792e0 Binary files /dev/null and b/docs/media/sdk-load-failure-exception.png differ diff --git a/docs/media/sdk-load-failure-overview.png b/docs/media/sdk-load-failure-overview.png new file mode 100644 index 000000000..4ad736ee8 Binary files /dev/null and b/docs/media/sdk-load-failure-overview.png differ