From 61a322c55ba99f416669dad7ed6fa0d9d3b90662 Mon Sep 17 00:00:00 2001 From: siyuniu-ms Date: Tue, 30 Jul 2024 22:54:38 -0700 Subject: [PATCH 01/13] Update W3cTraceParent.ts --- .../src/JavaScriptSDK/W3cTraceParent.ts | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts b/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts index e1264da83..e09b3808c 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts @@ -202,3 +202,46 @@ export function findW3cTraceParent(selectIdx?: number): ITraceParent { return traceParent; } + +export interface scriptsInfo { + url: string; + crossOrigin?: string; + async?: boolean; + defer?: boolean; + referrePolicy?: string; +} + +/** + * Find all script tags in the provided document and return the information about them. + * @param doc + * @returns + */ +export function findAllScripts(doc: any) { + let scripts = doc.getElementsByTagName("script"); + let result: scriptsInfo[] = []; + for (let i = 0; i < scripts.length; i++) { + let script = scripts[i]; + let src = script.getAttribute("src"); + if (src) { + let crossOrigin = script.getAttribute("crossorigin"); + let async = script.getAttribute("async") === "true"; + let defer = script.getAttribute("defer") === "true"; + let referrePolicy = script.getAttribute("referrerpolicy"); + let info: scriptsInfo = { url: src }; + if (crossOrigin) { + info.crossOrigin = crossOrigin; + } + if (async) { + info.async = async; + } + if (defer) { + info.defer = defer; + } + if (referrePolicy) { + info.referrePolicy = referrePolicy; + } + result.push(info); + } + } + return result; +} From ca9f2157f0fc29c6208124b7e7140ea40c54ba8a Mon Sep 17 00:00:00 2001 From: siyuniu-ms Date: Wed, 31 Jul 2024 15:26:34 -0700 Subject: [PATCH 02/13] local test work --- .../src/JavaScriptSDK/AnalyticsPlugin.ts | 11 +++++++++-- .../src/applicationinsights-common.ts | 2 +- .../src/JavaScriptSDK/W3cTraceParent.ts | 4 ++-- .../src/applicationinsights-core-js.ts | 2 +- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts b/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts index 6edfb95ed..6904daf27 100644 --- a/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts +++ b/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts @@ -17,8 +17,9 @@ import { IInstrumentCallDetails, IPlugin, IProcessTelemetryContext, IProcessTelemetryUnloadContext, ITelemetryInitializerHandler, ITelemetryItem, ITelemetryPluginChain, ITelemetryUnloadState, InstrumentEvent, TelemetryInitializerFunction, _eInternalMessageId, arrForEach, cfgDfBoolean, cfgDfSet, cfgDfString, cfgDfValidate, createProcessTelemetryContext, createUniqueNamespace, dumpObj, eLoggingSeverity, - eventOff, eventOn, generateW3CId, getDocument, getExceptionName, getHistory, getLocation, getWindow, hasHistory, hasWindow, isFunction, - isNullOrUndefined, isString, isUndefined, mergeEvtNamespace, onConfigChange, safeGetCookieMgr, strUndefined, throwError + eventOff, eventOn, findAllScripts, generateW3CId, getDocument, getExceptionName, getHistory, getLocation, getWindow, hasHistory, + hasWindow, isFunction, isNullOrUndefined, isString, isUndefined, mergeEvtNamespace, onConfigChange, safeGetCookieMgr, strUndefined, + throwError } from "@microsoft/applicationinsights-core-js"; import { PropertiesPlugin } from "@microsoft/applicationinsights-properties-js"; import { isError, objDeepFreeze, objDefine, scheduleTimeout, strIndexOf } from "@nevware21/ts-utils"; @@ -431,6 +432,12 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights customProperties, systemProperties ); + let doc = getDocument(); + if (doc){ + let scriptsInfo = findAllScripts(doc); + console.log("get scripts info"); + telemetryItem.tags["exceptionScripts"] = JSON.stringify(scriptsInfo); + } _self.core.track(telemetryItem); }; diff --git a/shared/AppInsightsCommon/src/applicationinsights-common.ts b/shared/AppInsightsCommon/src/applicationinsights-common.ts index 32af7d137..958c027c3 100644 --- a/shared/AppInsightsCommon/src/applicationinsights-common.ts +++ b/shared/AppInsightsCommon/src/applicationinsights-common.ts @@ -64,7 +64,7 @@ export { eDistributedTracingModes, DistributedTracingModes, EventPersistence } f export { stringToBoolOrDefault, msToTimeSpan, getExtensionByName, isCrossOriginError } from "./HelperFuncs"; export { isBeaconsSupported as isBeaconApiSupported, - ITraceParent, createTraceParent, parseTraceParent, isValidTraceId, isValidSpanId, isValidTraceParent, isSampledFlag, formatTraceParent, findW3cTraceParent + ITraceParent, createTraceParent, parseTraceParent, isValidTraceId, isValidSpanId, isValidTraceParent, isSampledFlag, formatTraceParent, findW3cTraceParent, findAllScripts } from "@microsoft/applicationinsights-core-js"; export { createDomEvent } from "./DomHelperFuncs"; export { diff --git a/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts b/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts index e09b3808c..eac990312 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts @@ -213,8 +213,8 @@ export interface scriptsInfo { /** * Find all script tags in the provided document and return the information about them. - * @param doc - * @returns + * @param doc + * @returns */ export function findAllScripts(doc: any) { let scripts = doc.getElementsByTagName("script"); diff --git a/shared/AppInsightsCore/src/applicationinsights-core-js.ts b/shared/AppInsightsCore/src/applicationinsights-core-js.ts index 9eaf98bde..3a8551abc 100644 --- a/shared/AppInsightsCore/src/applicationinsights-core-js.ts +++ b/shared/AppInsightsCore/src/applicationinsights-core-js.ts @@ -93,7 +93,7 @@ export { ITelemetryUnloadState } from "./JavaScriptSDK.Interfaces/ITelemetryUnlo export { IDistributedTraceContext } from "./JavaScriptSDK.Interfaces/IDistributedTraceContext"; export { ITraceParent } from "./JavaScriptSDK.Interfaces/ITraceParent"; export { - createTraceParent, parseTraceParent, isValidTraceId, isValidSpanId, isValidTraceParent, isSampledFlag, formatTraceParent, findW3cTraceParent + createTraceParent, parseTraceParent, isValidTraceId, isValidSpanId, isValidTraceParent, isSampledFlag, formatTraceParent, findW3cTraceParent, findAllScripts } from "./JavaScriptSDK/W3cTraceParent"; // Dynamic Config definitions From 0b0339c4936af45526d72d84ba0f8d597cf2fb21 Mon Sep 17 00:00:00 2001 From: siyuniu-ms Date: Wed, 31 Jul 2024 16:47:36 -0700 Subject: [PATCH 03/13] add config --- .../src/JavaScriptSDK/AnalyticsPlugin.ts | 3 +-- shared/AppInsightsCommon/src/Interfaces/IConfig.ts | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts b/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts index 6904daf27..671a495b9 100644 --- a/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts +++ b/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts @@ -96,7 +96,6 @@ function _updateStorageUsage(extConfig: IConfig) { } export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights, IAppInsightsInternal { - public static Version = "#version#"; // Not currently used anywhere public identifier: string = AnalyticsPluginIdentifier; // do not change name or priority public priority: number = 180; // take from reserved priority range 100- 200 @@ -433,7 +432,7 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights systemProperties ); let doc = getDocument(); - if (doc){ + if (doc && _self.config.getExceptionScriptsInfo){ let scriptsInfo = findAllScripts(doc); console.log("get scripts info"); telemetryItem.tags["exceptionScripts"] = JSON.stringify(scriptsInfo); diff --git a/shared/AppInsightsCommon/src/Interfaces/IConfig.ts b/shared/AppInsightsCommon/src/Interfaces/IConfig.ts index 878911921..a71ba6b4d 100644 --- a/shared/AppInsightsCommon/src/Interfaces/IConfig.ts +++ b/shared/AppInsightsCommon/src/Interfaces/IConfig.ts @@ -389,6 +389,12 @@ export interface IConfig { * This URL takes precedence over the 'config.endpointUrl' and any endpoint in the connection string. */ userOverrideEndpointUrl?: string; + + /** + * [Optional] If set to true, when exception is sent out, the SDK will also send out all scripts basic info that are loaded on the page. + * Notice: This would increase the size of the exception telemetry. + */ + getExceptionScriptsInfo?: boolean; } export class ConfigurationManager { From 49c3918adcebb692f3aeb2e5f307f1a1089cad52 Mon Sep 17 00:00:00 2001 From: siyuniu-ms Date: Thu, 1 Aug 2024 14:04:37 -0700 Subject: [PATCH 04/13] put in properties --- .../src/JavaScriptSDK/AnalyticsPlugin.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts b/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts index 671a495b9..6df32b4d5 100644 --- a/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts +++ b/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts @@ -96,6 +96,7 @@ function _updateStorageUsage(extConfig: IConfig) { } export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights, IAppInsightsInternal { + public static Version = '3.3.0'; // Not currently used anywhere public identifier: string = AnalyticsPluginIdentifier; // do not change name or priority public priority: number = 180; // take from reserved priority range 100- 200 @@ -422,7 +423,12 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights exception.severityLevel, exception.id ).toInterface(); - + var doc = getDocument(); + if (doc && _self.config.getExceptionScriptsInfo){ + var scriptsInfo = findAllScripts(doc); + console.log("get scripts info", JSON.stringify(scriptsInfo)); + exceptionPartB.properties["exceptionScripts"] = JSON.stringify(scriptsInfo); + } let telemetryItem: ITelemetryItem = createTelemetryItem( exceptionPartB, Exception.dataType, @@ -431,12 +437,6 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights customProperties, systemProperties ); - let doc = getDocument(); - if (doc && _self.config.getExceptionScriptsInfo){ - let scriptsInfo = findAllScripts(doc); - console.log("get scripts info"); - telemetryItem.tags["exceptionScripts"] = JSON.stringify(scriptsInfo); - } _self.core.track(telemetryItem); }; From b1b25d381b3d1b4648ca9de9ab9ed4379fd8626e Mon Sep 17 00:00:00 2001 From: siyuniu-ms Date: Thu, 1 Aug 2024 18:55:37 -0700 Subject: [PATCH 05/13] add test --- .../Tests/Unit/src/AnalyticsPlugin.tests.ts | 66 ++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts b/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts index 4528bf636..9d3511db7 100644 --- a/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts +++ b/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts @@ -7,7 +7,7 @@ import { Exception, SeverityLevel, Event, Trace, PageViewPerformance, IConfig, IExceptionInternal, AnalyticsPluginIdentifier, IAppInsights, Metric, PageView, RemoteDependencyData, utlCanUseLocalStorage, createDomEvent } from "@microsoft/applicationinsights-common"; -import { ITelemetryItem, AppInsightsCore, IPlugin, IConfiguration, IAppInsightsCore, setEnableEnvMocks, getLocation, dumpObj, __getRegisteredEvents, createCookieMgr } from "@microsoft/applicationinsights-core-js"; +import { ITelemetryItem, AppInsightsCore, IPlugin, IConfiguration, IAppInsightsCore, setEnableEnvMocks, getLocation, dumpObj, __getRegisteredEvents, createCookieMgr, findAllScripts } from "@microsoft/applicationinsights-core-js"; import { Sender } from "@microsoft/applicationinsights-channel-js" import { PropertiesPlugin } from "@microsoft/applicationinsights-properties-js"; import { AnalyticsPlugin } from "../../../src/JavaScriptSDK/AnalyticsPlugin"; @@ -406,6 +406,70 @@ export class AnalyticsPluginTests extends AITestClass { this.addOnErrorTests(); this.addTrackMetricTests(); this.addTelemetryInitializerTests(); + this.addScriptInfoTests(); + } + + private addScriptInfoTests(): void { + this.testCase({ + name: "AppInsightsTests: findAllScripts function returns correct information", + useFakeTimers: true, + test: () => { + // Initialize Application Insights core with plugins + let script = window.document.createElement("script"); + script.src = "https://www.example.com/test.js"; + script.innerHTML = 'test script'; + window.document.body.appendChild(script); + + let doc = window.document; + let scriptsInfo = findAllScripts(doc); + Assert.deepEqual(true, JSON.stringify(scriptsInfo).indexOf("https://www.example.com/test.js") !== -1, "script info contains the correct url"); + } + }); + this.testCase({ + name: "AppInsightsTests: trackException would contain scrips info when config turns on", + useFakeTimers: true, + test: () => { + const appInsights = new AnalyticsPlugin(); + const core = new AppInsightsCore(); + const channel = new ChannelPlugin(); + const properties = new PropertiesPlugin(); + // Configuration + const config = { + instrumentationKey: 'ikey', + }; + this.onDone(() => { + core.unload(false); + }); + // Initialize Application Insights core with plugins + core.initialize(config, [appInsights, channel, properties]); + + + // add test script + let script = window.document.createElement("script"); + script.src = "https://www.example.com/test.js"; + script.innerHTML = 'test script'; + window.document.body.appendChild(script); + + + const trackStub = this.sandbox.stub(appInsights.core, "track"); + appInsights.trackException({error: new Error(), severityLevel: SeverityLevel.Critical}); + Assert.ok(trackStub.calledOnce, "single exception is tracked"); + const baseData = (trackStub.args[0][0] as ITelemetryItem).baseData as IExceptionInternal; + const prop = baseData.properties; + Assert.equal(-1, JSON.stringify(prop).indexOf("https://www.example.com/test.js"), "script info is not included"); + + + appInsights.config.getExceptionScriptsInfo = true; + this.clock.tick(1); + appInsights.trackException({error: new Error(), severityLevel: SeverityLevel.Critical}); + Assert.ok(trackStub.calledTwice, "single exception is tracked"); + const baseData2 = (trackStub.args[1][0] as ITelemetryItem).baseData as IExceptionInternal; + const prop2 = baseData2.properties; + Assert.ok(JSON.stringify(prop2).indexOf("https://www.example.com/test.js") !== -1, "script info is included"); + } + }); + + } private addGenericTests(): void { From 08988d664f9c6b8f84290a118d25d99810422f53 Mon Sep 17 00:00:00 2001 From: siyuniu-ms Date: Thu, 1 Aug 2024 18:59:04 -0700 Subject: [PATCH 06/13] Update AnalyticsPlugin.ts --- .../src/JavaScriptSDK/AnalyticsPlugin.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts b/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts index 6df32b4d5..940218880 100644 --- a/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts +++ b/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts @@ -96,7 +96,7 @@ function _updateStorageUsage(extConfig: IConfig) { } export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights, IAppInsightsInternal { - public static Version = '3.3.0'; // Not currently used anywhere + public static Version = "#version#"; // Not currently used anywhere public identifier: string = AnalyticsPluginIdentifier; // do not change name or priority public priority: number = 180; // take from reserved priority range 100- 200 @@ -426,7 +426,6 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights var doc = getDocument(); if (doc && _self.config.getExceptionScriptsInfo){ var scriptsInfo = findAllScripts(doc); - console.log("get scripts info", JSON.stringify(scriptsInfo)); exceptionPartB.properties["exceptionScripts"] = JSON.stringify(scriptsInfo); } let telemetryItem: ITelemetryItem = createTelemetryItem( From 479a979c7b900c4384c038ecaed00f1d48f53c13 Mon Sep 17 00:00:00 2001 From: siyuniu-ms Date: Fri, 2 Aug 2024 14:46:15 -0700 Subject: [PATCH 07/13] restructure config --- .../Tests/Unit/src/AnalyticsPlugin.tests.ts | 2 +- .../src/JavaScriptSDK/AnalyticsPlugin.ts | 15 ++++++++------- .../AppInsightsCommon/src/Interfaces/IConfig.ts | 6 +++--- .../src/Interfaces/IExceptionTelemetry.ts | 8 ++++++++ .../src/applicationinsights-common.ts | 2 +- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts b/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts index 9d3511db7..12901123b 100644 --- a/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts +++ b/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts @@ -459,7 +459,7 @@ export class AnalyticsPluginTests extends AITestClass { Assert.equal(-1, JSON.stringify(prop).indexOf("https://www.example.com/test.js"), "script info is not included"); - appInsights.config.getExceptionScriptsInfo = true; + appInsights.config.exceptionConfig.includeScripts = true; this.clock.tick(1); appInsights.trackException({error: new Error(), severityLevel: SeverityLevel.Critical}); Assert.ok(trackStub.calledTwice, "single exception is tracked"); diff --git a/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts b/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts index 940218880..a3b455651 100644 --- a/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts +++ b/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts @@ -6,7 +6,7 @@ import dynamicProto from "@microsoft/dynamicproto-js"; import { AnalyticsPluginIdentifier, Event as EventTelemetry, Exception, IAppInsights, IAutoExceptionTelemetry, IConfig, IDependencyTelemetry, - IEventTelemetry, IExceptionInternal, IExceptionTelemetry, IMetricTelemetry, IPageViewPerformanceTelemetry, + IEventTelemetry, IExceptionConfig, IExceptionInternal, IExceptionTelemetry, IMetricTelemetry, IPageViewPerformanceTelemetry, IPageViewPerformanceTelemetryInternal, IPageViewTelemetry, IPageViewTelemetryInternal, ITraceTelemetry, Metric, PageView, PageViewPerformance, PropertiesPluginIdentifier, RemoteDependencyData, Trace, createDistributedTraceContextFromTrace, createDomEvent, createTelemetryItem, dataSanitizeString, eSeverityLevel, isCrossOriginError, strNotSpecified, utlDisableStorage, utlEnableStorage, @@ -16,10 +16,10 @@ import { BaseTelemetryPlugin, IAppInsightsCore, IConfigDefaults, IConfiguration, ICookieMgr, ICustomProperties, IDistributedTraceContext, IInstrumentCallDetails, IPlugin, IProcessTelemetryContext, IProcessTelemetryUnloadContext, ITelemetryInitializerHandler, ITelemetryItem, ITelemetryPluginChain, ITelemetryUnloadState, InstrumentEvent, TelemetryInitializerFunction, _eInternalMessageId, arrForEach, - cfgDfBoolean, cfgDfSet, cfgDfString, cfgDfValidate, createProcessTelemetryContext, createUniqueNamespace, dumpObj, eLoggingSeverity, - eventOff, eventOn, findAllScripts, generateW3CId, getDocument, getExceptionName, getHistory, getLocation, getWindow, hasHistory, - hasWindow, isFunction, isNullOrUndefined, isString, isUndefined, mergeEvtNamespace, onConfigChange, safeGetCookieMgr, strUndefined, - throwError + cfgDfBoolean, cfgDfMerge, cfgDfSet, cfgDfString, cfgDfValidate, createProcessTelemetryContext, createUniqueNamespace, dumpObj, + eLoggingSeverity, eventOff, eventOn, findAllScripts, generateW3CId, getDocument, getExceptionName, getHistory, getLocation, getWindow, + hasHistory, hasWindow, isFunction, isNullOrUndefined, isString, isUndefined, mergeEvtNamespace, onConfigChange, safeGetCookieMgr, + strUndefined, throwError } from "@microsoft/applicationinsights-core-js"; import { PropertiesPlugin } from "@microsoft/applicationinsights-properties-js"; import { isError, objDeepFreeze, objDefine, scheduleTimeout, strIndexOf } from "@nevware21/ts-utils"; @@ -67,7 +67,8 @@ const defaultValues: IConfigDefaults = objDeepFreeze({ namePrefix: cfgDfString(), enableDebug: cfgDfBoolean(), disableFlushOnBeforeUnload: cfgDfBoolean(), - disableFlushOnUnload: cfgDfBoolean(false, "disableFlushOnBeforeUnload") + disableFlushOnUnload: cfgDfBoolean(false, "disableFlushOnBeforeUnload"), + exceptionConfig: cfgDfMerge({includeScripts: false}) }); function _chkConfigMilliseconds(value: number, defValue: number): number { @@ -424,7 +425,7 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights exception.id ).toInterface(); var doc = getDocument(); - if (doc && _self.config.getExceptionScriptsInfo){ + if (doc && _self.config.exceptionConfig && _self.config.exceptionConfig.includeScripts) { var scriptsInfo = findAllScripts(doc); exceptionPartB.properties["exceptionScripts"] = JSON.stringify(scriptsInfo); } diff --git a/shared/AppInsightsCommon/src/Interfaces/IConfig.ts b/shared/AppInsightsCommon/src/Interfaces/IConfig.ts index a71ba6b4d..13c8a2650 100644 --- a/shared/AppInsightsCommon/src/Interfaces/IConfig.ts +++ b/shared/AppInsightsCommon/src/Interfaces/IConfig.ts @@ -2,6 +2,7 @@ // Licensed under the MIT License. import { IConfiguration, ICustomProperties, isNullOrUndefined } from "@microsoft/applicationinsights-core-js"; import { DistributedTracingModes } from "../Enums"; +import { IExceptionConfig } from "./IExceptionTelemetry"; import { IRequestContext } from "./IRequestContext"; import { IStorageBuffer } from "./IStorageBuffer"; import { IThrottleMgrConfig } from "./IThrottleMgr"; @@ -391,10 +392,9 @@ export interface IConfig { userOverrideEndpointUrl?: string; /** - * [Optional] If set to true, when exception is sent out, the SDK will also send out all scripts basic info that are loaded on the page. - * Notice: This would increase the size of the exception telemetry. + * [Optional] Set additional configuration for exceptions, such as more scripts to include in the exception telemetry. */ - getExceptionScriptsInfo?: boolean; + exceptionConfig?: IExceptionConfig; } export class ConfigurationManager { diff --git a/shared/AppInsightsCommon/src/Interfaces/IExceptionTelemetry.ts b/shared/AppInsightsCommon/src/Interfaces/IExceptionTelemetry.ts index 6f0be410f..bc910aa8a 100644 --- a/shared/AppInsightsCommon/src/Interfaces/IExceptionTelemetry.ts +++ b/shared/AppInsightsCommon/src/Interfaces/IExceptionTelemetry.ts @@ -4,6 +4,14 @@ import { SeverityLevel } from "./Contracts/SeverityLevel"; import { IPartC } from "./IPartC"; +export interface IExceptionConfig{ + /** + * If set to true, when exception is sent out, the SDK will also send out all scripts basic info that are loaded on the page. + * Notice: This would increase the size of the exception telemetry. + */ + includeScripts?: boolean; +} + /** * @export * @interface IExceptionTelemetry diff --git a/shared/AppInsightsCommon/src/applicationinsights-common.ts b/shared/AppInsightsCommon/src/applicationinsights-common.ts index 958c027c3..dcc988c06 100644 --- a/shared/AppInsightsCommon/src/applicationinsights-common.ts +++ b/shared/AppInsightsCommon/src/applicationinsights-common.ts @@ -26,7 +26,7 @@ export { IEventTelemetry } from "./Interfaces/IEventTelemetry"; export { ITraceTelemetry } from "./Interfaces/ITraceTelemetry"; export { IMetricTelemetry } from "./Interfaces/IMetricTelemetry"; export { IDependencyTelemetry } from "./Interfaces/IDependencyTelemetry"; -export { IExceptionTelemetry, IAutoExceptionTelemetry, IExceptionInternal } from "./Interfaces/IExceptionTelemetry"; +export { IExceptionTelemetry, IAutoExceptionTelemetry, IExceptionInternal, IExceptionConfig } from "./Interfaces/IExceptionTelemetry"; export { IPageViewTelemetry, IPageViewTelemetryInternal } from "./Interfaces/IPageViewTelemetry"; export { IPageViewPerformanceTelemetry, IPageViewPerformanceTelemetryInternal } from "./Interfaces/IPageViewPerformanceTelemetry"; export { Trace } from "./Telemetry/Trace"; From 86e1482b400777b16b986856e38f52f5048c9434 Mon Sep 17 00:00:00 2001 From: siyuniu-ms Date: Fri, 2 Aug 2024 14:59:49 -0700 Subject: [PATCH 08/13] rename --- channels/1ds-post-js/src/DataModels.ts | 2 +- .../Tests/Unit/src/AnalyticsPlugin.tests.ts | 2 +- .../src/JavaScriptSDK/AnalyticsPlugin.ts | 4 ++-- shared/AppInsightsCommon/src/Interfaces/IConfig.ts | 2 +- .../AppInsightsCommon/src/Interfaces/IExceptionTelemetry.ts | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/channels/1ds-post-js/src/DataModels.ts b/channels/1ds-post-js/src/DataModels.ts index 6ec624dfe..59483949c 100644 --- a/channels/1ds-post-js/src/DataModels.ts +++ b/channels/1ds-post-js/src/DataModels.ts @@ -256,7 +256,7 @@ export interface IChannelConfiguration { * - "same-origin": only send and include credentials for same-origin requests. * * If not set, the default value will be "include". - * + * * For more information, refer to: * - [Fetch API - Using Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#including_credentials) * @since 3.3.1 diff --git a/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts b/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts index 12901123b..ca7900c87 100644 --- a/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts +++ b/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts @@ -459,7 +459,7 @@ export class AnalyticsPluginTests extends AITestClass { Assert.equal(-1, JSON.stringify(prop).indexOf("https://www.example.com/test.js"), "script info is not included"); - appInsights.config.exceptionConfig.includeScripts = true; + appInsights.config.expCfg.inclScripts = true; this.clock.tick(1); appInsights.trackException({error: new Error(), severityLevel: SeverityLevel.Critical}); Assert.ok(trackStub.calledTwice, "single exception is tracked"); diff --git a/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts b/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts index a3b455651..2530e01b5 100644 --- a/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts +++ b/extensions/applicationinsights-analytics-js/src/JavaScriptSDK/AnalyticsPlugin.ts @@ -68,7 +68,7 @@ const defaultValues: IConfigDefaults = objDeepFreeze({ enableDebug: cfgDfBoolean(), disableFlushOnBeforeUnload: cfgDfBoolean(), disableFlushOnUnload: cfgDfBoolean(false, "disableFlushOnBeforeUnload"), - exceptionConfig: cfgDfMerge({includeScripts: false}) + expCfg: cfgDfMerge({inclScripts: false}) }); function _chkConfigMilliseconds(value: number, defValue: number): number { @@ -425,7 +425,7 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights exception.id ).toInterface(); var doc = getDocument(); - if (doc && _self.config.exceptionConfig && _self.config.exceptionConfig.includeScripts) { + if (doc && _self.config.expCfg?.inclScripts) { var scriptsInfo = findAllScripts(doc); exceptionPartB.properties["exceptionScripts"] = JSON.stringify(scriptsInfo); } diff --git a/shared/AppInsightsCommon/src/Interfaces/IConfig.ts b/shared/AppInsightsCommon/src/Interfaces/IConfig.ts index 13c8a2650..7c63fe954 100644 --- a/shared/AppInsightsCommon/src/Interfaces/IConfig.ts +++ b/shared/AppInsightsCommon/src/Interfaces/IConfig.ts @@ -394,7 +394,7 @@ export interface IConfig { /** * [Optional] Set additional configuration for exceptions, such as more scripts to include in the exception telemetry. */ - exceptionConfig?: IExceptionConfig; + expCfg?: IExceptionConfig; } export class ConfigurationManager { diff --git a/shared/AppInsightsCommon/src/Interfaces/IExceptionTelemetry.ts b/shared/AppInsightsCommon/src/Interfaces/IExceptionTelemetry.ts index bc910aa8a..5207e515d 100644 --- a/shared/AppInsightsCommon/src/Interfaces/IExceptionTelemetry.ts +++ b/shared/AppInsightsCommon/src/Interfaces/IExceptionTelemetry.ts @@ -9,7 +9,7 @@ export interface IExceptionConfig{ * If set to true, when exception is sent out, the SDK will also send out all scripts basic info that are loaded on the page. * Notice: This would increase the size of the exception telemetry. */ - includeScripts?: boolean; + inclScripts?: boolean; } /** From 30441dde9ea45de4c8fc70fd0be2b6982ca963ad Mon Sep 17 00:00:00 2001 From: siyuniu-ms Date: Fri, 2 Aug 2024 15:12:03 -0700 Subject: [PATCH 09/13] sizecheck --- .../Tests/Unit/src/AppInsightsCoreSize.Tests.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/AppInsightsCore/Tests/Unit/src/AppInsightsCoreSize.Tests.ts b/shared/AppInsightsCore/Tests/Unit/src/AppInsightsCoreSize.Tests.ts index 1cdcf9337..8a22e9ae6 100644 --- a/shared/AppInsightsCore/Tests/Unit/src/AppInsightsCoreSize.Tests.ts +++ b/shared/AppInsightsCore/Tests/Unit/src/AppInsightsCoreSize.Tests.ts @@ -4,8 +4,8 @@ import * as pako from "pako"; export class AppInsightsCoreSizeCheck extends AITestClass { private readonly MAX_RAW_SIZE = 65; private readonly MAX_BUNDLE_SIZE = 65; - private readonly MAX_RAW_DEFLATE_SIZE = 27; - private readonly MAX_BUNDLE_DEFLATE_SIZE = 27; + private readonly MAX_RAW_DEFLATE_SIZE = 28; + private readonly MAX_BUNDLE_DEFLATE_SIZE = 28; private readonly rawFilePath = "../dist/es5/applicationinsights-core-js.min.js"; private readonly prodFilePath = "../browser/es5/applicationinsights-core-js.min.js"; From bafc0a51f2b6ccf6e7da78ca939d132e8844c0ee Mon Sep 17 00:00:00 2001 From: siyuniu-ms Date: Mon, 5 Aug 2024 11:19:23 -0700 Subject: [PATCH 10/13] check hasattribute --- .../Tests/Unit/src/AnalyticsPlugin.tests.ts | 14 ++++++++++---- .../src/JavaScriptSDK/W3cTraceParent.ts | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts b/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts index ca7900c87..77707db9b 100644 --- a/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts +++ b/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts @@ -443,12 +443,17 @@ export class AnalyticsPluginTests extends AITestClass { // Initialize Application Insights core with plugins core.initialize(config, [appInsights, channel, properties]); - // add test script let script = window.document.createElement("script"); - script.src = "https://www.example.com/test.js"; + script.src = "https://www.example1.com/test.js"; + script.setAttribute("referrerpolicy", "no-referrer"); script.innerHTML = 'test script'; + let script2 = window.document.createElement("script"); + script2.src = "https://www.test.com/test.js"; + script2.innerHTML = "test tests"; + script2.setAttribute("async", ""); window.document.body.appendChild(script); + window.document.body.appendChild(script2); const trackStub = this.sandbox.stub(appInsights.core, "track"); @@ -458,14 +463,15 @@ export class AnalyticsPluginTests extends AITestClass { const prop = baseData.properties; Assert.equal(-1, JSON.stringify(prop).indexOf("https://www.example.com/test.js"), "script info is not included"); - appInsights.config.expCfg.inclScripts = true; this.clock.tick(1); appInsights.trackException({error: new Error(), severityLevel: SeverityLevel.Critical}); Assert.ok(trackStub.calledTwice, "single exception is tracked"); const baseData2 = (trackStub.args[1][0] as ITelemetryItem).baseData as IExceptionInternal; const prop2 = baseData2.properties; - Assert.ok(JSON.stringify(prop2).indexOf("https://www.example.com/test.js") !== -1, "script info is included"); + Assert.deepEqual(true, prop2["exceptionScripts"].includes('"url":"https://www.test.com/test.js","async":true}')) + Assert.deepEqual(true, prop2["exceptionScripts"].includes('"url":"https://www.example1.com/test.js","referrePolicy":"no-referrer"')) + } }); diff --git a/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts b/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts index eac990312..43c5ce2b5 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts @@ -224,8 +224,8 @@ export function findAllScripts(doc: any) { let src = script.getAttribute("src"); if (src) { let crossOrigin = script.getAttribute("crossorigin"); - let async = script.getAttribute("async") === "true"; - let defer = script.getAttribute("defer") === "true"; + let async = script.hasAttribute("async") === true; + let defer = script.hasAttribute("defer") === true; let referrePolicy = script.getAttribute("referrerpolicy"); let info: scriptsInfo = { url: src }; if (crossOrigin) { From 3199e7d4b50930cb423f72ff67ac286a579b2c8b Mon Sep 17 00:00:00 2001 From: siyuniu-ms Date: Mon, 5 Aug 2024 12:56:17 -0700 Subject: [PATCH 11/13] Update W3cTraceParent.ts --- shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts b/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts index 43c5ce2b5..7d7f09f1e 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts @@ -1,4 +1,4 @@ -import { isArray, isString, strLeft, strTrim } from "@nevware21/ts-utils"; +import { arrForEach, isArray, isString, strLeft, strTrim } from "@nevware21/ts-utils"; import { ITraceParent } from "../JavaScriptSDK.Interfaces/ITraceParent"; import { generateW3CId } from "./CoreUtils"; import { findMetaTag, findNamedServerTiming } from "./EnvUtils"; @@ -219,8 +219,7 @@ export interface scriptsInfo { export function findAllScripts(doc: any) { let scripts = doc.getElementsByTagName("script"); let result: scriptsInfo[] = []; - for (let i = 0; i < scripts.length; i++) { - let script = scripts[i]; + arrForEach(scripts, (script: any) => { let src = script.getAttribute("src"); if (src) { let crossOrigin = script.getAttribute("crossorigin"); @@ -242,6 +241,6 @@ export function findAllScripts(doc: any) { } result.push(info); } - } + }); return result; } From aa2b650c642da06524b74e8fc061f22d182928de Mon Sep 17 00:00:00 2001 From: siyuniu-ms Date: Mon, 5 Aug 2024 12:57:50 -0700 Subject: [PATCH 12/13] referrerPolicy --- .../Tests/Unit/src/AnalyticsPlugin.tests.ts | 2 +- .../AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts b/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts index 77707db9b..7c457d856 100644 --- a/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts +++ b/extensions/applicationinsights-analytics-js/Tests/Unit/src/AnalyticsPlugin.tests.ts @@ -470,7 +470,7 @@ export class AnalyticsPluginTests extends AITestClass { const baseData2 = (trackStub.args[1][0] as ITelemetryItem).baseData as IExceptionInternal; const prop2 = baseData2.properties; Assert.deepEqual(true, prop2["exceptionScripts"].includes('"url":"https://www.test.com/test.js","async":true}')) - Assert.deepEqual(true, prop2["exceptionScripts"].includes('"url":"https://www.example1.com/test.js","referrePolicy":"no-referrer"')) + Assert.deepEqual(true, prop2["exceptionScripts"].includes('"url":"https://www.example1.com/test.js","referrerPolicy":"no-referrer"')) } }); diff --git a/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts b/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts index 7d7f09f1e..ca62f1723 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK/W3cTraceParent.ts @@ -208,7 +208,7 @@ export interface scriptsInfo { crossOrigin?: string; async?: boolean; defer?: boolean; - referrePolicy?: string; + referrerPolicy?: string; } /** @@ -225,7 +225,7 @@ export function findAllScripts(doc: any) { let crossOrigin = script.getAttribute("crossorigin"); let async = script.hasAttribute("async") === true; let defer = script.hasAttribute("defer") === true; - let referrePolicy = script.getAttribute("referrerpolicy"); + let referrerPolicy = script.getAttribute("referrerpolicy"); let info: scriptsInfo = { url: src }; if (crossOrigin) { info.crossOrigin = crossOrigin; @@ -236,8 +236,8 @@ export function findAllScripts(doc: any) { if (defer) { info.defer = defer; } - if (referrePolicy) { - info.referrePolicy = referrePolicy; + if (referrerPolicy) { + info.referrerPolicy = referrerPolicy; } result.push(info); } From d10bc33cc6bd62854120ec4fbb88a5c669857629 Mon Sep 17 00:00:00 2001 From: siyuniu-ms Date: Mon, 5 Aug 2024 15:19:55 -0700 Subject: [PATCH 13/13] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 42a27f182..8d1fa5329 100644 --- a/README.md +++ b/README.md @@ -396,6 +396,8 @@ Most configuration fields are named such that they can be defaulted to falsey. A | 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. | +| expCfg | [`IExceptionConfig`](https://github.com/microsoft/ApplicationInsights-JS/blob/main/shared/AppInsightsCommon/src/Interfaces/IExceptionTelemetry.ts) | undefined | Set additional configuration for exceptions, such as more scripts to include in the exception telemetry. | + ### ExtensionConfig