Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for service workers? #1436

Closed
SwintDC opened this issue Nov 25, 2020 · 6 comments
Closed

Support for service workers? #1436

SwintDC opened this issue Nov 25, 2020 · 6 comments
Labels
service-worker Required to properly support service workers

Comments

@SwintDC
Copy link

SwintDC commented Nov 25, 2020

After searching the net for several hours, and trying different javascript libraries, I am still unable to get a working sample of the SDK working in a service worker. I am testing in Chrome v87 and the Chromium based Edge v86, no logging appears in Application Insights and both have the same browser console output:

Warning: Failed to initialize AppInsights JS SDK for instance <unknown> - Missing window
Error: test
    at service-worker.js:34
Warning: AI (Internal): 28 message:"Sender was not initialized"
Warning: AI (Internal): 28 message:"Sender was not initialized"

My code in the service worker that produces this output:

importScripts("https://az416426.vo.msecnd.net/next/ai.2.js"); // Application Insights JavaScript SDK - Web, 2.5.9

const instrumentationKey = "<instrumentation key>";
const loggingLevelConsole = 2;

const appInsightsInit = new Microsoft.ApplicationInsights.ApplicationInsights({ config: { instrumentationKey, loggingLevelConsole } });
const appInsights = appInsightsInit.loadAppInsights();

function logError(error) {
    console.error(error);
    const telemetryItem = { exception: error, properties: {} };
    if (typeof error === "string") {
        telemetryItem.exception = new Error(error);
    }
    appInsights.trackException(telemetryItem);
    appInsights.flush();
}
self.setTimeout(() => {
    logError(new Error("test"));
}, 5000);

Am i doing something wrong?
Some documentation on how to use the SDK in a service worker would be handy. I noticed other people are also struggling with this issue. (for example: https://stackoverflow.com/questions/55955760/how-can-i-utilise-applicationinsights-js-in-a-service-worker)

PS: I know about the workaround using the fetch API to simply call the Microsoft Azure API directly on the https://dc.services.visualstudio.com/v2/track endpoint myself. I prefer the more clean solution using the SDK.

@MSNev
Copy link
Collaborator

MSNev commented Dec 3, 2020

Hi @SwintDC, I agree with your reluctance to call the track endpoint directly and this is not a supported scenario (i.e. if the backend or Azure Monitor mapping changes in a way that broke this approach we would be unable to support your application -- breakages could occur by either the format of the request or required additional fields).

Now onto getting it working in a Service Worker, first off the main AISKU is designed to run in the main browser (with a window), so either importing or loading the SKU from the CDN wont work for a Service Worker. However, the main components should (we introduced the getGlobal() and getGlobalInst() helper functions to support not only service workers but also to abstract most of the code to work in a non-browser (think nodejs, react, etc) environments.

The exact approach will very a little depending on what you are trying to track (note that not all of the extensions will work in a Service Worker), but a high level overview on how to create and get in going will be (internally at MS we do have teams that are using the Core Application Insights (with extensions built on top of it) in Service Workers.

Basic Approach

  • DON'T use the AISKU (the init.ts will always throw the "missing window" error) either via NPM or the CDN
  • Create an instance of ApplicationInsights yourself eg. import { AppInsightsCore } from "@microsoft/applicationinsights-core-js"; (This only gives you the base "track" method)
  • Include the main analytics extension via import { ApplicationInsights } from "@microsoft/applicationinsights-analytics-js"; (This gives you the "extra" methods like start/stop track event, trackPageView, implementations etc
  • You will need to "initialize" your chosen instance WITH all of the extensions that you require along the same lines as the code in the AISKU loadAppInsights() function (https://github.com/microsoft/ApplicationInsights-JS/blob/master/AISKU/src/Initialization.ts#L311), key required components
    • Sender (this is the "channel" that actually sends the request to ApplicationInsights backend)
    • The instance of "@microsoft/applicationinsights-analytics-js".

If your using the analytics instance that (currently) you should consider that the analytics instance is the "AppInsights" instance for your calls, otherwise use the AppInsightsCore object.

Note: It is extremely unlikely that we will provide any default implementation (SKU) which does this as part of any version 2.x. As part of a later version (v3 or v4) Server Workers will become a more standard approach etc. And as part of the code size issues that we working on it is extremely likely that the above approach will need to change because of the current complex class inheritance and the current mixed responsibilities (i.e. things like treating the analytics extension as the AppInsights instance). The main goal of future versions will be to not break / minimize breaks for the main AISKU flow for initializing and loading from the CDN (which are the current bulk of users).

@MSNev
Copy link
Collaborator

MSNev commented Jan 5, 2021

@SwintDC was the above helpful? I'm looking the close this issue.

@Pkiri
Copy link

Pkiri commented Jan 29, 2021

@MSNev Do we need to create our own implementation of Sender to get this to work? The current sender implementation uses Beacon or XmlHttpRequest. Both are not supported in Service Workers:

if (!_self._senderConfig.isBeaconApiDisabled() && Util.IsBeaconApiSupported()) {

@MSNev
Copy link
Collaborator

MSNev commented Jan 29, 2021

Hi @Pkiri, not really... A lot simplier approach would be to just include an XMLHttpRequest polyfill (before you initialize Application Insights).

If this doesn't work for you there are some additional (not nice) ways to set the "_sender" function property on the contained Sender instance via the ApplicationInsights Core getTransmissionControls() -- but this is not really a recommended approach and is very likely to get broken at some point in the future (because it's not supported).

A better approach would be to add a fetch() implementation within Sender as defined in #1268 which so far has not made the list of features, due to other higher level work. I've just tagged this as a p2 and I'll go and create a new service worker label to start tagging features that are required for service worker support.

@MSNev MSNev added the service-worker Required to properly support service workers label Jan 29, 2021
@Pkiri
Copy link

Pkiri commented Jan 30, 2021

Hey @MSNev, The polyfill for XMLHttpRequest works. When I added the polyfill, I could use the Web-Basic SDK: https://az416426.vo.msecnd.net/next/aib.2.min.js

But I agree that adding a fetch implementation in de _sender function is a much better solution.

@MSNev MSNev closed this as completed Apr 23, 2021
@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 24, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
service-worker Required to properly support service workers
Projects
None yet
Development

No branches or pull requests

3 participants