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 Chrome Extension #2189

Open
jykwon91 opened this issue Oct 30, 2023 · 9 comments
Open

Support for Chrome Extension #2189

jykwon91 opened this issue Oct 30, 2023 · 9 comments
Assignees
Labels
investigation required Further investigation or discussions required question

Comments

@jykwon91
Copy link

Is your feature request related to a problem? Please describe.
I'm currently running into an issue where I have a react app with an app insights implementation running inside of a chrome extension sidepanel. The problem is it seems to be working on the first run but when I start opening and closing the extension and switching between different tabs, the app(extension) completely crashes. When I comment out "appinsights.loadappinsights()", the app doesn't crash anymore but obviously, I can't use app insights.

Describe the solution you'd like
I would like to be able to use app insights inside of a chrome extension environment or diagnose the current issue I'm having to get to the root cause.

Describe alternatives you've considered
I don't think there would be an alternative for this.

Additional context
N/A

@MSNev
Copy link
Collaborator

MSNev commented Oct 30, 2023

Hi,
There is not much to go on here, but it should be working a couple of questions which might help narrow down where the issue might be

  • What version of the SDK are you using
  • How are you consuming the SDK (embedded via an npm package or loaded via the CDN)
  • Where is the application insights instance being loaded / initialized
    • In your own popup (where it's then isolated to just you extension),
    • In a shared code that you are "injecting" onto the host page (this could have issues for other pages that are not your own, but you can get it to work when using npm package and not adding to globals
  • Can you elaborate in this a bit more opening and closing the extension and switching between different tabs, the app(extension) completely crashes, specifically, what is the error (exception) that you are getting that crashes your extension? Part of this would also depending on the above question about "where" the Application Insights SDK is getting loaded / initialized (host page (tab), your popup or both).

We do have or own debug Chrome extension that is used to intercept outbound request and display them events in a more friendly / searchable away, this also "communicates" with any running Application Insights SDK instance in the Host page back to our popup to display some of the internal debugging messages that are not always sent as events. This "may" be helpful to identify any issues where the SDK is not getting initialized (or is) and whether it has been initialized successfully.

@MSNev MSNev added question information requested Bug is waiting on additional information from the user labels Oct 30, 2023
@jykwon91
Copy link
Author

jykwon91 commented Oct 30, 2023

Appreciate the quick response!

What version of the SDK are you using?
"@microsoft/applicationinsights-clickanalytics-js": "^3.0.4",
"@microsoft/applicationinsights-react-js": "^17.0.2",
"@microsoft/applicationinsights-web": "^3.0.4",

"node_modules/@microsoft/applicationinsights-web": {
  "version": "3.0.4",
  "@microsoft/applicationinsights-react-js": {
  "version": "17.0.2",
   "node_modules/@microsoft/applicationinsights-clickanalytics-js": {
  "version": "3.0.4",

How are you consuming the SDK (embedded via an npm package or loaded via the CDN)?
NPM

Where is the application insights instance being loaded / initialized
It's being loaded within the react application which is loaded when the sidepanel(extension) is open:
image

what it looks like:
image

It's hard to elaborate because it seems like there's no exception being thrown. Service worker doesn't return any exception and I'm not able to open dev tools when the app crashes so it could be an implementation error.

Generally the reproduction steps are:

  1. open extension
    • Calls to app insights is working
  2. open a new tab and open extension
    • Call to app insights works
  3. switch back to 1st tab
    • both tabs are frozen
    • opening and closing extension results in a blank page

So I've recently found that removing all config properties except for the connection string resolved the issue.

Original config that causes crash:

const reactPlugin = new ReactPlugin();
const appInsights = new ApplicationInsights({
    config: {
      connectionString:
        "InstrumentationKey=9544c8ff-d282-4592-87b6-b217b45a6408;IngestionEndpoint=https://eastus2-3.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus2.livediagnostics.monitor.azure.com/",
      extensions: [reactPlugin, clickPluginInstance],
      extensionConfig: {
        [clickPluginInstance.identifier]: clickPluginConfig,
      },
      enableAutoRouteTracking: true,
      disableAjaxTracking: false,
      autoTrackPageVisitTime: true,
      enableCorsCorrelation: true,
      enableRequestHeaderTracking: true,
      enableResponseHeaderTracking: true,
    },
});
appInsights.loadAppInsights();

appInsights.addTelemetryInitializer((env: ITelemetryItem) => {
    env.tags = env.tags || [];
    env.tags["ai.cloud.role"] = "testTag";
});

New config that works:

const reactPlugin = new ReactPlugin();
const appInsights = new ApplicationInsights({
    config: {
      connectionString:
        "InstrumentationKey=9544c8ff-d282-4592-87b6-b217b45a6408;IngestionEndpoint=https://eastus2-3.in.applicationinsights.azure.com/;LiveEndpoint=https://eastus2.livediagnostics.monitor.azure.com/",
      extensions: [reactPlugin]
    },
});
appInsights.loadAppInsights();

I'll probably add the config back one by one to isolate which one is causing it to fail.

debug Chrome extension that is used to intercept outbound request and display them events

This would be so incredibly helpful. Is this an internal tool or something I can use?

@MSNev
Copy link
Collaborator

MSNev commented Oct 30, 2023

Try adding everything back except the click analytics plugin as that plugin was specifically designed for the main web page.
I (suspect) that there might be something in there that is causing the issue when running in the extension (exactly what is going to be difficult to track down), but from memory the "popup" (extension) has a slightly different runtime.

From your description, it sounds like what might be happening is a stack overflow, where something is recursively looping on itself until the entire thing crashes. The click analytics plugin will "walk" up the DOM tree looking for parent elements of the clicked component, it does this by attaching itself to the main document and it receives the event.target that it walks up from... I'm taking a wild stab in the dark that it (might) be something around this.

@jykwon91
Copy link
Author

sounds like what might be happening is a stack overflow, where something is recursively looping on itself until the entire thing crashes.

Yep this is exactly what I suspect is happening. I'm just unsure of what's going on under the hood.

Still crashed after removing only the Click Analytics plugin.
image

@MSNev
Copy link
Collaborator

MSNev commented Oct 30, 2023

Hmm, the only other recursive code is around the validation / serialization of the "event", which would mean that there is something assigned to the "event" that loops back on itself that is referenced... When you call trackXXX are you passing anything additional to the events?

Or something in the header values that are assigned for the Ajax requests, because you have the header tracking enabled it will collect the "value" (not the string, but it will grab any object), so if you have an object assigned as the value for one or more of the headers the XHR / fetch will stringy it, but will grab the object and this (may) cause some recursion (but I've not hear of this before).

Actually, because your using ^3.0.4 the config is now shared across all components (extensions), and the "passed" in configuration is used as a "template" and it will be recursively called to create a "working" copy of the configuration, so if somehow this ends up with a recursive reference this would also cause the issue. The extensions part of the config did cause us some grief during initial implementation but internally we mark this as a "special" "in-place" / referenced version to stop the recursion, but if your creating new instances every time before you call loadAppInsights this (should not) be causing an issue.

@jykwon91
Copy link
Author

Just to close the loop on this, I think my implementation was bad. I created a class where I was initializing app insights for every instance.
image

Didn't have a chance to add the other settings back but I i think multiple instances of app insights was the main culprit.

Would it still be possible to have the debugging tool you used for chrome extension?

Thanks for all the help!

@MSNev
Copy link
Collaborator

MSNev commented Oct 31, 2023

Would it still be possible to have the debugging tool you used for chrome extension?

Yes, the chrome extension listens to "allow" instances that are on the any and all open tabs / pages. And yes, we do support having multiple initialized SDK instances on a page.

We technically, also support having an extension "shared" (used by) between different instances, but this really depends quite a bit on the implementation of the extension and what / how it operates as it has to "ignore" (mostly) the core instance passed in and only "use" the passed in context for the processTelemetry call, which doesn't really work for the auto capture components as they are generating the "track" calls themselves. So things like the ClickAnalytics and the Dependencies (Ajax calls) can't really be shared in this manner.

@jykwon91
Copy link
Author

Alright actually closing the loop on this. We started diabling the config and enabling one by one, it seems like disableFlushOnBeforeUnload: true resolved the issue.

I'm unsure of what Flush does, but will this impact the performance of the chrome extension?

@MSNev
Copy link
Collaborator

MSNev commented Nov 2, 2023

I have no idea on why this would resolve the issue either...
Looking at the code this flag causes the page unload / hide events to be "attempted" to be hooked. It sounds like there is something in the runtime that rather than returning "false" (could not hook) it's throwing...

@siyuniu-ms when you get a chance can you attempt to repo, to see if there is anything we can do to catch / stop this from crashing.

@MSNev MSNev added investigation required Further investigation or discussions required and removed information requested Bug is waiting on additional information from the user labels Nov 2, 2023
@MSNev MSNev added this to the 3.0.x milestone Nov 2, 2023
@MSNev MSNev modified the milestones: 3.1.0, 3.x.x (Future Release) Feb 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
investigation required Further investigation or discussions required question
Projects
None yet
Development

No branches or pull requests

3 participants