From 617e20104011ea60136bb0bbd047a1055ac2e301 Mon Sep 17 00:00:00 2001 From: Nev Wylie <54870357+MSNev@users.noreply.github.com> Date: Fri, 24 Feb 2023 15:13:29 -0800 Subject: [PATCH] [BUG] App Insights not auto-capturing from a Web Worker #1995 --- common/config/rush/npm-shrinkwrap.json | 12 +++--- examples/shared-worker/src/worker-npm-init.ts | 8 +++- examples/shared-worker/src/worker.ts | 41 +++++++++++++++++-- .../Telemetry/PageViewManager.ts | 13 +++--- 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/common/config/rush/npm-shrinkwrap.json b/common/config/rush/npm-shrinkwrap.json index a0a92cb2..7746f8ac 100644 --- a/common/config/rush/npm-shrinkwrap.json +++ b/common/config/rush/npm-shrinkwrap.json @@ -2183,9 +2183,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.314", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.314.tgz", - "integrity": "sha512-+3RmNVx9hZLlc0gW//4yep0K5SYKmIvB5DXg1Yg6varsuAHlHwTeqeygfS8DWwLCsNOWrgj+p9qgM5WYjw1lXQ==" + "version": "1.4.315", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.315.tgz", + "integrity": "sha512-ndBQYz3Eyy3rASjjQ9poMJGoAlsZ/aZnq6GBsGL4w/4sWIAwiUHVSsMuADbxa8WJw7pZ0oxLpGbtoDt4vRTdCg==" }, "node_modules/encodeurl": { "version": "1.0.2", @@ -7205,9 +7205,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { - "version": "1.4.314", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.314.tgz", - "integrity": "sha512-+3RmNVx9hZLlc0gW//4yep0K5SYKmIvB5DXg1Yg6varsuAHlHwTeqeygfS8DWwLCsNOWrgj+p9qgM5WYjw1lXQ==" + "version": "1.4.315", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.315.tgz", + "integrity": "sha512-ndBQYz3Eyy3rASjjQ9poMJGoAlsZ/aZnq6GBsGL4w/4sWIAwiUHVSsMuADbxa8WJw7pZ0oxLpGbtoDt4vRTdCg==" }, "encodeurl": { "version": "1.0.2", diff --git a/examples/shared-worker/src/worker-npm-init.ts b/examples/shared-worker/src/worker-npm-init.ts index 79a95640..3c3ac2e2 100644 --- a/examples/shared-worker/src/worker-npm-init.ts +++ b/examples/shared-worker/src/worker-npm-init.ts @@ -11,7 +11,7 @@ let _appInsights: ApplicationInsights; * @param config * @returns */ -export function initApplicationInsights(config: IConfiguration) { +export function initApplicationInsights(config: IConfiguration, onInitCallback: (appInsights: ApplicationInsights, port: MessagePort) => void, port: MessagePort) { if (!_appInsights) { // Make sure we have a configuration object @@ -25,7 +25,11 @@ export function initApplicationInsights(config: IConfiguration) { }); _appInsights.loadAppInsights(); - _appInsights.trackPageView(); // Manually call trackPageView to establish the current user/session/pageview + if (_appInsights.core.isInitialized()) { + // Call the callback before the trackPageView + onInitCallback(_appInsights, port); + _appInsights.trackPageView(); // Manually call trackPageView to establish the current user/session/pageview + } return _appInsights; } diff --git a/examples/shared-worker/src/worker.ts b/examples/shared-worker/src/worker.ts index a601fb70..6dfd13ee 100644 --- a/examples/shared-worker/src/worker.ts +++ b/examples/shared-worker/src/worker.ts @@ -3,7 +3,7 @@ import { initApplicationInsights, trackPageView, unloadApplicationInsights } from "./worker-npm-init"; import { ExampleMessageType, IExampleRequest, IExampleResponse } from "./interfaces/IExampleMessage"; -import { IConfiguration, INotificationListener } from "@microsoft/applicationinsights-web"; +import { ApplicationInsights, IConfiguration, INotificationListener } from "@microsoft/applicationinsights-web"; import { dumpObj, objAssign } from "@nevware21/ts-utils"; /** @@ -12,7 +12,16 @@ import { dumpObj, objAssign } from "@nevware21/ts-utils"; * the connection string. */ const defaultApplicationInsightsConfig: IConfiguration = { - + /** + * Telemtry logging level to instrumentation key. All logs with a severity + * level higher than the configured level will sent as telemetry data to + * the configured instrumentation key. + * + * 0: ALL iKey logging off + * 1: logs to iKey: severity >= CRITICAL + * 2: logs to iKey: severity >= WARNING + */ + loggingLevelTelemetry: 2 }; /** @@ -91,6 +100,31 @@ function notificationListener(port: MessagePort): INotificationListener { }; } +/** + * We only want to add any notification listener or telemetry initializer once + * otherwise they WILL get called multiple times during processing. + * @param appInsights + * @param port + */ +function onInitAddInitializers(appInsights: ApplicationInsights, port: MessagePort) { + // This callback is only called once, otherwise we would keep adding listeners and initializers + appInsights.core.getNotifyMgr().addNotificationListener(notificationListener(port)); + + // This is not normally needed, but this provides a view from the worker to the + // main page about errors that the worker is having / seeing + appInsights.addTelemetryInitializer((theEvent) => { + if (theEvent && theEvent.name && theEvent.name["startsWith"]("InternalMessageId") && theEvent.baseData) { + port.postMessage({ + success: true, + message: "Internal Message: " + (theEvent.baseData?.message || "--") + }); + + // Drop ALL internal message from being sent to Azure Monitor portal + return false; + } + }); +} + /** * Initialize the SDK using the passed connection string from the request (if supplied) * @param request @@ -100,9 +134,8 @@ function notificationListener(port: MessagePort): INotificationListener { function workerLoadSdk(request: IExampleRequest, port: MessagePort) { let theConfig = objAssign({}, defaultApplicationInsightsConfig); theConfig.connectionString = request.connectionString; - let appInsights = initApplicationInsights(theConfig); + let appInsights = initApplicationInsights(theConfig, onInitAddInitializers, port); if (appInsights && appInsights.core.isInitialized()) { - appInsights.core.getNotifyMgr().addNotificationListener(notificationListener(port)); return { success: true, message: `SDK Loaded and Initialized with - ${appInsights.config.connectionString}` diff --git a/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/Telemetry/PageViewManager.ts b/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/Telemetry/PageViewManager.ts index 2aa5f532..f2253a21 100644 --- a/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/Telemetry/PageViewManager.ts +++ b/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/Telemetry/PageViewManager.ts @@ -9,6 +9,7 @@ import { IAppInsightsCore, IDiagnosticLogger, IProcessTelemetryUnloadContext, ITelemetryUnloadState, _eInternalMessageId, _throwInternal, arrForEach, dumpObj, eLoggingSeverity, getDocument, getExceptionName, getLocation, isNullOrUndefined } from "@microsoft/applicationinsights-core-js"; +import { isWebWorker } from "@nevware21/ts-utils"; import { PageViewPerformanceManager } from "./PageViewPerformanceManager"; /** @@ -99,11 +100,13 @@ export class PageViewManager { ); _flushChannels(true); - // no navigation timing (IE 8, iOS Safari 8.4, Opera Mini 8 - see http://caniuse.com/#feat=nav-timing) - _throwInternal(_logger, - eLoggingSeverity.WARNING, - _eInternalMessageId.NavigationTimingNotSupported, - "trackPageView: navigation timing API used for calculation of page duration is not supported in this browser. This page view will be collected without duration and timing info."); + if (!isWebWorker()) { + // no navigation timing (IE 8, iOS Safari 8.4, Opera Mini 8 - see http://caniuse.com/#feat=nav-timing) + _throwInternal(_logger, + eLoggingSeverity.WARNING, + _eInternalMessageId.NavigationTimingNotSupported, + "trackPageView: navigation timing API used for calculation of page duration is not supported in this browser. This page view will be collected without duration and timing info."); + } return; }