Skip to content

Commit 690c5c8

Browse files
authored
Merge pull request #188 from microsoft/lramos15/old-parrotfish
Use web basic SDK for both node + web to reduce bundle size
2 parents d02e6c5 + 894a9af commit 690c5c8

8 files changed

+309
-2995
lines changed

package-lock.json

Lines changed: 215 additions & 2824 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@vscode/extension-telemetry",
33
"description": "A module for Visual Studio Code extensions to report consistent telemetry.",
4-
"version": "0.8.5",
4+
"version": "0.9.0",
55
"author": {
66
"name": "Microsoft Corporation"
77
},
@@ -20,23 +20,22 @@
2020
"compile": "tsc -p 'src/browser/tsconfig.json' && tsc -p 'src/node/tsconfig.json'"
2121
},
2222
"dependencies": {
23-
"@microsoft/1ds-core-js": "^3.2.13",
24-
"@microsoft/1ds-post-js": "^3.2.13",
25-
"@microsoft/applicationinsights-web-basic": "^3.0.2",
26-
"applicationinsights": "^2.7.1"
23+
"@microsoft/1ds-core-js": "^4.0.3",
24+
"@microsoft/1ds-post-js": "^4.0.3",
25+
"@microsoft/applicationinsights-web-basic": "^3.0.4"
2726
},
2827
"devDependencies": {
29-
"@types/mocha": "^10.0.1",
30-
"@types/node": "^20.4.9",
31-
"@types/sinon": "^10.0.16",
28+
"@types/mocha": "^10.0.3",
29+
"@types/node": "^20.8.9",
30+
"@types/sinon": "^10.0.20",
3231
"@types/vscode": "^1.75.0",
33-
"@typescript-eslint/eslint-plugin": "^6.3.0",
34-
"@typescript-eslint/parser": "^6.3.0",
35-
"eslint": "^8.46.0",
32+
"@typescript-eslint/eslint-plugin": "^6.9.1",
33+
"@typescript-eslint/parser": "^6.9.1",
34+
"eslint": "^8.52.0",
3635
"mocha": "^10.2.0",
37-
"sinon": "^15.2.0",
38-
"typescript": "^5.1.6",
39-
"user-agent-data-types": "^0.3.1"
36+
"sinon": "^17.0.0",
37+
"typescript": "^5.2.2",
38+
"user-agent-data-types": "^0.4.2"
4039
},
4140
"repository": {
4241
"type": "git",

src/browser/telemetryReporter.ts

Lines changed: 4 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,59 +2,12 @@
22
* Copyright (C) Microsoft Corporation. All rights reserved.
33
*--------------------------------------------------------*/
44

5-
import type { ApplicationInsights } from "@microsoft/applicationinsights-web-basic";
65
import * as vscode from "vscode";
76
import { oneDataSystemClientFactory } from "../common/1dsClientFactory";
8-
import { BaseTelemetrySender, BaseTelemetryClient } from "../common/baseTelemetrySender";
9-
import { SenderData, BaseTelemetryReporter, ReplacementOption } from "../common/baseTelemetryReporter";
7+
import { BaseTelemetrySender } from "../common/baseTelemetrySender";
8+
import { BaseTelemetryReporter, ReplacementOption } from "../common/baseTelemetryReporter";
109
import { TelemetryUtil } from "../common/util";
11-
12-
const webAppInsightsClientFactory = async (key: string, replacementOptions?: ReplacementOption[]): Promise<BaseTelemetryClient> => {
13-
let appInsightsClient: ApplicationInsights | undefined;
14-
try {
15-
const web = await import/* webpackMode: "eager" */ ("@microsoft/applicationinsights-web-basic");
16-
appInsightsClient = new web.ApplicationInsights({
17-
instrumentationKey: key,
18-
disableAjaxTracking: true,
19-
disableExceptionTracking: true,
20-
disableFetchTracking: true,
21-
disableCorrelationHeaders: true,
22-
disableCookiesUsage: true,
23-
autoTrackPageVisitTime: false,
24-
emitLineDelimitedJson: false,
25-
disableInstrumentationKeyValidation: true
26-
},
27-
);
28-
} catch (e) {
29-
return Promise.reject(e);
30-
}
31-
// Sets the appinsights client into a standardized form
32-
const telemetryClient: BaseTelemetryClient = {
33-
logEvent: (eventName: string, data?: SenderData) => {
34-
const properties = { ...data?.properties, ...data?.measurements };
35-
if (replacementOptions?.length) {
36-
TelemetryUtil.applyReplacements(properties, replacementOptions);
37-
}
38-
appInsightsClient?.track(
39-
{ name: eventName, data: properties },
40-
);
41-
},
42-
flush: async () => {
43-
appInsightsClient?.flush(false);
44-
},
45-
dispose: async () => {
46-
const unloadPromise = new Promise<void>((resolve) => {
47-
appInsightsClient?.unload(true, () => {
48-
resolve();
49-
appInsightsClient = undefined;
50-
}, 1000);
51-
}
52-
);
53-
return unloadPromise;
54-
}
55-
};
56-
return telemetryClient;
57-
};
10+
import { appInsightsClientFactory } from "../common/appInsightsClientFactory";
5811

5912
function getBrowserRelease(navigator: Navigator): string {
6013
if (navigator.userAgentData) {
@@ -67,7 +20,7 @@ function getBrowserRelease(navigator: Navigator): string {
6720

6821
export default class TelemetryReporter extends BaseTelemetryReporter {
6922
constructor(key: string, replacementOptions?: ReplacementOption[]) {
70-
let clientFactory = (key: string) => webAppInsightsClientFactory(key, replacementOptions);
23+
let clientFactory = (key: string) => appInsightsClientFactory(key, undefined, replacementOptions);
7124
// If key is usable by 1DS use the 1DS SDk
7225
if (TelemetryUtil.shouldUseOneDataSystemSDK(key)) {
7326
clientFactory = (key: string) => oneDataSystemClientFactory(key, vscode);

src/browser/tsconfig.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"module": "ES2020",
66
"moduleResolution": "node",
77
"outDir": "../../dist/browser",
8-
"typeRoots": []
98
},
109
"include": [".", "../common", "../../node_modules/user-agent-data-types"]
1110
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import type { ApplicationInsights } from "@microsoft/applicationinsights-web-basic";
7+
import type { IXHROverride } from "@microsoft/applicationinsights-core-js";
8+
import { BreezeChannelIdentifier } from "@microsoft/applicationinsights-common";
9+
import { ReplacementOption, SenderData } from "./baseTelemetryReporter";
10+
import { BaseTelemetryClient } from "./baseTelemetrySender";
11+
import { TelemetryUtil } from "./util";
12+
import type { IChannelConfiguration } from "@microsoft/1ds-post-js";
13+
14+
export const appInsightsClientFactory = async (key: string, xhrOverride?: IXHROverride, replacementOptions?: ReplacementOption[]): Promise<BaseTelemetryClient> => {
15+
let appInsightsClient: ApplicationInsights | undefined;
16+
try {
17+
const basicAISDK = await import/* webpackMode: "eager" */("@microsoft/applicationinsights-web-basic");
18+
appInsightsClient = new basicAISDK.ApplicationInsights({
19+
instrumentationKey: key,
20+
disableAjaxTracking: true,
21+
disableExceptionTracking: true,
22+
disableFetchTracking: true,
23+
disableCorrelationHeaders: true,
24+
disableCookiesUsage: true,
25+
autoTrackPageVisitTime: false,
26+
emitLineDelimitedJson: false,
27+
disableInstrumentationKeyValidation: true
28+
},
29+
);
30+
31+
if (xhrOverride) {
32+
appInsightsClient.config.extensionConfig = {};
33+
// Configure the channel to use a XHR Request override since it's not available in node
34+
const channelConfig: IChannelConfiguration = {
35+
alwaysUseXhrOverride: true,
36+
httpXHROverride: xhrOverride
37+
};
38+
appInsightsClient.config.extensionConfig[BreezeChannelIdentifier] = channelConfig;
39+
}
40+
} catch (e) {
41+
return Promise.reject(e);
42+
}
43+
// Sets the appinsights client into a standardized form
44+
const telemetryClient: BaseTelemetryClient = {
45+
logEvent: (eventName: string, data?: SenderData) => {
46+
const properties = { ...data?.properties, ...data?.measurements };
47+
if (replacementOptions?.length) {
48+
TelemetryUtil.applyReplacements(properties, replacementOptions);
49+
}
50+
appInsightsClient?.track({
51+
name: eventName,
52+
data: properties,
53+
baseType: "EventData",
54+
baseData: { name: eventName, properties: data?.properties, measurements: data?.measurements }
55+
});
56+
},
57+
flush: async () => {
58+
appInsightsClient?.flush(false);
59+
},
60+
dispose: async () => {
61+
const unloadPromise = new Promise<void>((resolve) => {
62+
appInsightsClient?.unload(true, () => {
63+
resolve();
64+
appInsightsClient = undefined;
65+
}, 1000);
66+
}
67+
);
68+
return unloadPromise;
69+
}
70+
};
71+
return telemetryClient;
72+
};

src/common/baseTelemetryReporter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export class BaseTelemetryReporter {
119119
const propertyValue = modifiedProperties[propertyKey];
120120
if (typeof propertyKey === "string" && propertyValue !== undefined) {
121121
// Trusted values are not sanitized, which is what we want for raw telemetry
122-
modifiedProperties[propertyKey] = new this.vscodeAPI.TelemetryTrustedValue<string>(typeof propertyValue === 'string' ? propertyValue : propertyValue.value);
122+
modifiedProperties[propertyKey] = new this.vscodeAPI.TelemetryTrustedValue<string>(typeof propertyValue === "string" ? propertyValue : propertyValue.value);
123123
}
124124
}
125125

src/node/telemetryReporter.ts

Lines changed: 4 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -5,111 +5,12 @@
55
import * as os from "os";
66
import * as vscode from "vscode";
77
import * as https from "https";
8-
import { type TelemetryClient } from "applicationinsights";
9-
import { SenderData, BaseTelemetryReporter, ReplacementOption } from "../common/baseTelemetryReporter";
10-
import { BaseTelemetrySender, BaseTelemetryClient } from "../common/baseTelemetrySender";
8+
import { BaseTelemetryReporter, ReplacementOption } from "../common/baseTelemetryReporter";
9+
import { BaseTelemetrySender } from "../common/baseTelemetrySender";
1110
import { TelemetryUtil } from "../common/util";
1211
import type { IXHROverride, IPayloadData } from "@microsoft/1ds-post-js";
1312
import { oneDataSystemClientFactory } from "../common/1dsClientFactory";
14-
/**
15-
* A factory function which creates a telemetry client to be used by an sender to send telemetry in a node application.
16-
*
17-
* @param key The app insights key
18-
* @param replacementOptions Optional list of {@link ReplacementOption replacements} to apply to the telemetry client. This allows
19-
* the sender to filter out any sensitive or unnecessary information from the telemetry server.
20-
*
21-
* @returns A promise which resolves to the telemetry client or rejects upon error
22-
*/
23-
const appInsightsClientFactory = async (key: string, replacementOptions?: ReplacementOption[]): Promise<BaseTelemetryClient> => {
24-
let appInsightsClient: TelemetryClient | undefined;
25-
try {
26-
process.env["APPLICATION_INSIGHTS_NO_DIAGNOSTIC_CHANNEL"] = "1";
27-
const appInsights = await import(/* webpackMode: "eager" */ "applicationinsights");
28-
//check if another instance is already initialized
29-
if (appInsights.defaultClient) {
30-
appInsightsClient = new appInsights.TelemetryClient(key);
31-
// no other way to enable offline mode
32-
appInsightsClient.channel.setUseDiskRetryCaching(true);
33-
} else {
34-
appInsights.setup(key)
35-
.setAutoCollectRequests(false)
36-
.setAutoCollectPerformance(false)
37-
.setAutoCollectExceptions(false)
38-
.setAutoCollectDependencies(false)
39-
.setAutoDependencyCorrelation(false)
40-
.setAutoCollectConsole(false)
41-
.setAutoCollectHeartbeat(false)
42-
.setAutoCollectIncomingRequestAzureFunctions(false)
43-
.setUseDiskRetryCaching(true)
44-
.start();
45-
appInsightsClient = appInsights.defaultClient;
46-
}
47-
if (vscode && vscode.env) {
48-
appInsightsClient.context.tags[appInsightsClient.context.keys.userId] = vscode.env.machineId;
49-
appInsightsClient.context.tags[appInsightsClient.context.keys.sessionId] = vscode.env.sessionId;
50-
appInsightsClient.context.tags[appInsightsClient.context.keys.cloudRole] = vscode.env.appName;
51-
appInsightsClient.context.tags[appInsightsClient.context.keys.cloudRoleInstance] = vscode.env.appName;
52-
}
53-
} catch (e: any) {
54-
return Promise.reject("Failed to initialize app insights!\n" + e.message);
55-
}
56-
57-
if (replacementOptions?.length) {
58-
addReplacementOptions(appInsightsClient, replacementOptions);
59-
}
60-
61-
// Sets the appinsights client into a standardized form
62-
const telemetryClient: BaseTelemetryClient = {
63-
logEvent: (eventName: string, data?: SenderData) => {
64-
try {
65-
appInsightsClient?.trackEvent({
66-
name: eventName,
67-
properties: data?.properties,
68-
measurements: data?.measurements
69-
});
70-
} catch (e: any) {
71-
throw new Error("Failed to log event to app insights!\n" + e.message);
72-
}
73-
},
74-
flush: async () => {
75-
try {
76-
appInsightsClient?.flush();
77-
} catch (e: any) {
78-
throw new Error("Failed to flush app insights!\n" + e.message);
79-
}
80-
},
81-
dispose: async () => {
82-
appInsightsClient?.flush({ isAppCrashing: true });
83-
appInsightsClient = undefined;
84-
}
85-
};
86-
return telemetryClient;
87-
};
88-
89-
/**
90-
* Adds replacement options to this {@link TelemetryClient}.
91-
*
92-
* If any replacement options are specified, this function will search through any event about to be
93-
* sent to the telemetry server and replace any matches with the specified replacement string. Both
94-
* the envelope and the base data will be searched.
95-
*
96-
* @param appInsightsClient The {@link TelemetryClient} to add the filters to.
97-
* @param replacementOptions The replacement options to add.
98-
*/
99-
function addReplacementOptions(appInsightsClient: TelemetryClient, replacementOptions: ReplacementOption[]) {
100-
appInsightsClient.addTelemetryProcessor((event) => {
101-
if (Array.isArray(event.tags)) {
102-
event.tags.forEach(tag => TelemetryUtil.applyReplacements(tag, replacementOptions));
103-
} else if (event.tags) {
104-
TelemetryUtil.applyReplacements(event.tags, replacementOptions);
105-
}
106-
107-
if (event.data.baseData) {
108-
TelemetryUtil.applyReplacements(event.data.baseData, replacementOptions);
109-
}
110-
return true;
111-
});
112-
}
13+
import { appInsightsClientFactory } from "../common/appInsightsClientFactory";
11314

11415
/**
11516
* Create a replacement for the XHTMLRequest object utilizing nodes HTTP module.
@@ -154,7 +55,7 @@ function getXHROverride() {
15455

15556
export default class TelemetryReporter extends BaseTelemetryReporter {
15657
constructor(key: string, replacementOptions?: ReplacementOption[]) {
157-
let clientFactory = (key: string) => appInsightsClientFactory(key, replacementOptions);
58+
let clientFactory = (key: string) => appInsightsClientFactory(key, getXHROverride(), replacementOptions);
15859
// If key is usable by 1DS use the 1DS SDk
15960
if (TelemetryUtil.shouldUseOneDataSystemSDK(key)) {
16061
clientFactory = (key: string) => oneDataSystemClientFactory(key, vscode, getXHROverride());

src/node/tsconfig.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
"module": "CommonJS",
77
"moduleResolution": "node",
88
"outDir": "../../dist/node",
9-
"typeRoots": []
109
},
1110
"include": [".", "../common", "../../vscode.proposed.telemetryLogger.d.ts"]
1211
}

0 commit comments

Comments
 (0)