diff --git a/.eslintrc.json b/.eslintrc.json index c04b1ce18d5..87f945e398f 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -578,7 +578,8 @@ "vscode-oniguruma", "iconv-lite-umd", "jschardet", - "@vscode/vscode-languagedetection" + "@vscode/vscode-languagedetection", + "@microsoft/applicationinsights-web" ] }, { diff --git a/package.json b/package.json index bb4785b5921..7914a379df1 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "extensions-ci": "node --max_old_space_size=4095 ./node_modules/gulp/bin/gulp.js extensions-ci" }, "dependencies": { + "@microsoft/applicationinsights-web": "^2.6.4", "@vscode/vscode-languagedetection": "1.0.12", "applicationinsights": "1.0.8", "chokidar": "3.5.1", diff --git a/remote/web/package.json b/remote/web/package.json index 28be4df40b6..058e61408f6 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -3,6 +3,7 @@ "version": "0.0.0", "private": true, "dependencies": { + "@microsoft/applicationinsights-web": "^2.6.4", "@vscode/vscode-languagedetection": "1.0.12", "iconv-lite-umd": "0.6.8", "jschardet": "3.0.0", diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index d3f17fccae4..ead4cbf5e04 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -2,6 +2,87 @@ # yarn lockfile v1 +"@microsoft/applicationinsights-analytics-js@2.6.4": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.6.4.tgz#22ad17276ed922f2f0e66b7efe304f31c50ede64" + integrity sha512-BHx3U6H4j3ddtl2wSJNt+kX2jG+qsvH4mNnimFJjZ4Mq9dheD3o6ghnBH8gQjIb5Up09JdyV5itsTZf1aC84Dg== + dependencies: + "@microsoft/applicationinsights-common" "2.6.4" + "@microsoft/applicationinsights-core-js" "2.6.4" + "@microsoft/applicationinsights-shims" "2.0.0" + "@microsoft/dynamicproto-js" "^1.1.4" + +"@microsoft/applicationinsights-channel-js@2.6.4": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.6.4.tgz#49c139e8d801835bfba25547cb57d030286dec8a" + integrity sha512-ps9ZglUw8nzou9/CxmfRgHO7aGjhopu9YqsadbQL6yz/q8LSj1w30+ADa3gSMYCEEy8FQrDo5e5UebDEnX/w+A== + dependencies: + "@microsoft/applicationinsights-common" "2.6.4" + "@microsoft/applicationinsights-core-js" "2.6.4" + "@microsoft/applicationinsights-shims" "2.0.0" + "@microsoft/dynamicproto-js" "^1.1.4" + +"@microsoft/applicationinsights-common@2.6.4": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.6.4.tgz#c3a4129c727127271c93c7e23b86cf18fcb9e3a0" + integrity sha512-/YLrKpxXL8zusjzu8GTYPuRrKw0OzUD4rLh8mxSlUZWK+SLOE/1loizJIesmd6OLgcgmOTrd1iZFVsuxn20b/g== + dependencies: + "@microsoft/applicationinsights-core-js" "2.6.4" + "@microsoft/applicationinsights-shims" "2.0.0" + "@microsoft/dynamicproto-js" "^1.1.4" + +"@microsoft/applicationinsights-core-js@2.6.4": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.6.4.tgz#163caa31c02e72cfe02fc4abebd6bffd6b587de3" + integrity sha512-rYxfJzl4aLXFGOLsRoJqyKj5qfhQTz1u/eXSo6N6gIIr/D+RCVNJZKVzeBh3xOOytm4UBGRshK0QFZJlIQL3Kw== + dependencies: + "@microsoft/applicationinsights-shims" "2.0.0" + "@microsoft/dynamicproto-js" "^1.1.4" + +"@microsoft/applicationinsights-dependencies-js@2.6.4": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.6.4.tgz#6d120965cdc3ef5798feac6bc729bc97d40a4bb5" + integrity sha512-mJ/yTe00HPlUpQCmQWGhY3ronlkhsPgIYBWjxstN4NHRO4Qt17/ITxFoRa+r50J8Sf4ouc4qBoEFSVc56x80bg== + dependencies: + "@microsoft/applicationinsights-common" "2.6.4" + "@microsoft/applicationinsights-core-js" "2.6.4" + "@microsoft/applicationinsights-shims" "2.0.0" + "@microsoft/dynamicproto-js" "^1.1.4" + +"@microsoft/applicationinsights-properties-js@2.6.4": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.6.4.tgz#d779cd552277e6049b30efe71024a39bad5264e7" + integrity sha512-SdIR3gVX46N0RdC0zV/pXKoCxwT+2+79ek6hVXvXa2o2I+JfgYEAxb1Q8flYNGEdlFd/Ge7BHcJLqFvjat1t4Q== + dependencies: + "@microsoft/applicationinsights-common" "2.6.4" + "@microsoft/applicationinsights-core-js" "2.6.4" + "@microsoft/applicationinsights-shims" "2.0.0" + "@microsoft/dynamicproto-js" "^1.1.4" + +"@microsoft/applicationinsights-shims@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.0.tgz#ee622588f14e58ae3c055b12431da8ed55d71991" + integrity sha512-OaKew7f7acuNFgKYjMSPrRTRQi93xUyONWeeCeBlJSx7oRNJaL0TqbTvW6j5GHnSr3mhinPtAQ+rCQWASBnOrg== + +"@microsoft/applicationinsights-web@^2.6.4": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web/-/applicationinsights-web-2.6.4.tgz#509069c798a4da2c2b2b494bb15eb328425d4e86" + integrity sha512-/lBngt78Q7YNs8Llu1xz22f9oT5Rr2lo1QmSSSSKal30HL6kkzkP14J2E6+0+O5dRmyTDgOSiEePt6AhF8NFzg== + dependencies: + "@microsoft/applicationinsights-analytics-js" "2.6.4" + "@microsoft/applicationinsights-channel-js" "2.6.4" + "@microsoft/applicationinsights-common" "2.6.4" + "@microsoft/applicationinsights-core-js" "2.6.4" + "@microsoft/applicationinsights-dependencies-js" "2.6.4" + "@microsoft/applicationinsights-properties-js" "2.6.4" + "@microsoft/applicationinsights-shims" "2.0.0" + "@microsoft/dynamicproto-js" "^1.1.4" + +"@microsoft/dynamicproto-js@^1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.4.tgz#40e1c0ad20743fcee1604a7df2c57faf0aa1af87" + integrity sha512-Ot53G927ykMF8cQ3/zq4foZtdk+Tt1YpX7aUTHxBU7UHNdkEiBvBfZSq+rnlUmKCJ19VatwPG4mNzvcGpBj4og== + "@vscode/vscode-languagedetection@1.0.12": version "1.0.12" resolved "https://registry.yarnpkg.com/@vscode/vscode-languagedetection/-/vscode-languagedetection-1.0.12.tgz#884c080257298b078fdd6dd75c35f8bd42ba83fa" diff --git a/src/vs/base/common/product.ts b/src/vs/base/common/product.ts index d47fc57bf84..78d60602133 100644 --- a/src/vs/base/common/product.ts +++ b/src/vs/base/common/product.ts @@ -42,6 +42,7 @@ export interface IProductConfiguration { readonly win32AppUserModelId?: string; readonly win32MutexName?: string; readonly applicationName: string; + readonly embedderIdentifier?: string; readonly urlProtocol: string; readonly dataFolderName: string; // location for extensions (e.g. ~/.vscode-insiders) diff --git a/src/vs/code/browser/workbench/workbench-dev.html b/src/vs/code/browser/workbench/workbench-dev.html index 01ddede28c5..39ccebd6fb7 100644 --- a/src/vs/code/browser/workbench/workbench-dev.html +++ b/src/vs/code/browser/workbench/workbench-dev.html @@ -41,6 +41,7 @@ } }), paths: { + '@microsoft/applicationinsights-web': `${window.location.origin}/static/remote/web/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js`, '@vscode/vscode-languagedetection': `${window.location.origin}/static/remote/web/node_modules/@vscode/vscode-languagedetection/dist/lib/index.js`, 'vscode-textmate': `${window.location.origin}/static/remote/web/node_modules/vscode-textmate/release/main`, 'vscode-oniguruma': `${window.location.origin}/static/remote/web/node_modules/vscode-oniguruma/release/main`, diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index b188561d008..db0077a905b 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -40,6 +40,7 @@ } }), paths: { + '@microsoft/applicationinsights-web': `${window.location.origin}/static/node_modules/@microsoft/applicationinsights-web/dist/applicationinsights-web.js`, '@vscode/vscode-languagedetection': `${window.location.origin}/static/node_modules/@vscode/vscode-languagedetection/dist/lib/index.js`, 'vscode-textmate': `${window.location.origin}/static/node_modules/vscode-textmate/release/main`, 'vscode-oniguruma': `${window.location.origin}/static/node_modules/vscode-oniguruma/release/main`, diff --git a/src/vs/platform/telemetry/common/telemetryUtils.ts b/src/vs/platform/telemetry/common/telemetryUtils.ts index 425b7ae7675..23db462500a 100644 --- a/src/vs/platform/telemetry/common/telemetryUtils.ts +++ b/src/vs/platform/telemetry/common/telemetryUtils.ts @@ -56,15 +56,12 @@ export class NullEndpointTelemetryService implements ICustomEndpointTelemetrySer export interface ITelemetryAppender { log(eventName: string, data: any): void; flush(): Promise; - // If specified replaces common.product in the telemetry data - productIdentifier?: string; } export function combinedAppender(...appenders: ITelemetryAppender[]): ITelemetryAppender { return { log: (e, d) => appenders.forEach(a => a.log(e, d)), flush: () => Promises.settled(appenders.map(a => a.flush())), - productIdentifier: appenders.find(a => a.productIdentifier !== undefined)?.productIdentifier }; } diff --git a/src/vs/workbench/services/telemetry/browser/telemetryService.ts b/src/vs/workbench/services/telemetry/browser/telemetryService.ts index 1584bf9386f..de6e2e98063 100644 --- a/src/vs/workbench/services/telemetry/browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/browser/telemetryService.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { ApplicationInsights } from '@microsoft/applicationinsights-web'; import { ITelemetryService, ITelemetryInfo, ITelemetryData } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService, combinedAppender, ITelemetryAppender } from 'vs/platform/telemetry/common/telemetryUtils'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -18,6 +19,56 @@ import { IProductService } from 'vs/platform/product/common/productService'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { TelemetryLogAppender } from 'vs/platform/telemetry/common/telemetryLogAppender'; +class WebAppInsightsAppender implements ITelemetryAppender { + private _aiClient: ApplicationInsights | undefined; + + constructor(private _eventPrefix: string, aiKey: string) { + const endpointUrl = 'https://vortex.data.microsoft.com/collect/v1'; + this._aiClient = new ApplicationInsights({ + config: { + instrumentationKey: aiKey, + endpointUrl, + disableAjaxTracking: true, + disableExceptionTracking: true, + disableFetchTracking: true, + disableCorrelationHeaders: true, + disableCookiesUsage: true, + autoTrackPageVisitTime: false, + emitLineDelimitedJson: true, + }, + }); + this._aiClient.loadAppInsights(); + + // If we cannot access the endpoint this most likely means it's being blocked + // and we should not attempt to send any telemetry. + fetch(endpointUrl).catch(() => (this._aiClient = undefined)); + } + + /** + * Logs a telemetry event with eventName and data + * @param eventName The event name + * @param data The data associated with the events + */ + public log(eventName: string, data: any): void { + if (!this._aiClient) { + return; + } + + this._aiClient.trackEvent({ name: this._eventPrefix + '/' + eventName }, data); + } + + /** + * Flushes all the telemetry data still in the buffer + */ + public flush(): Promise { + if (this._aiClient) { + this._aiClient.flush(); + this._aiClient = undefined; + } + return Promise.resolve(undefined); + } +} + class WebTelemetryAppender implements ITelemetryAppender { constructor(private _appender: ITelemetryAppender) { } @@ -48,11 +99,12 @@ export class TelemetryService extends Disposable implements ITelemetryService { ) { super(); - if (!!productService.enableTelemetry) { - const telemetryProvider: ITelemetryAppender = environmentService.options && environmentService.options.telemetryAppender || { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) }; + if (!!productService.enableTelemetry && productService.aiConfig?.asimovKey && environmentService.isBuilt) { + // If remote server is present send telemetry through that, else use the client side appender + const telemetryProvider: ITelemetryAppender = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : new WebAppInsightsAppender('monacoworkbench', productService.aiConfig?.asimovKey); const config: ITelemetryServiceConfig = { appender: combinedAppender(new WebTelemetryAppender(telemetryProvider), new TelemetryLogAppender(loggerService, environmentService)), - commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.remoteAuthority, telemetryProvider.productIdentifier, environmentService.options && environmentService.options.resolveCommonTelemetryProperties), + commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.remoteAuthority, productService.embedderIdentifier, environmentService.options && environmentService.options.resolveCommonTelemetryProperties), sendErrorTelemetry: false, }; diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts index b04c4d6d77d..cfef64888a3 100644 --- a/src/vs/workbench/workbench.web.api.ts +++ b/src/vs/workbench/workbench.web.api.ts @@ -19,7 +19,6 @@ import { IProductConfiguration } from 'vs/base/common/product'; import { mark } from 'vs/base/common/performance'; import { ICredentialsProvider } from 'vs/workbench/services/credentials/common/credentials'; import { TunnelProviderFeatures } from 'vs/platform/remote/common/tunnel'; -import { ITelemetryAppender } from 'vs/platform/telemetry/common/telemetryUtils'; interface IResourceUriProvider { (uri: URI): URI; @@ -365,12 +364,6 @@ interface IWorkbenchConstructionOptions { */ readonly resolveCommonTelemetryProperties?: ICommonTelemetryPropertiesResolver; - /** - * When provided used as the interface for sending telemetry events rather than the VS Code server. - * If no appender is provided and no server is present, no telemetry is sent. - */ - readonly telemetryAppender?: ITelemetryAppender; - /** * A set of optional commands that should be registered with the commands * registry. @@ -656,7 +649,6 @@ export { // Telemetry ICommonTelemetryPropertiesResolver, - ITelemetryAppender, // External Uris IExternalUriResolver, diff --git a/yarn.lock b/yarn.lock index 2835dc958e2..79e456386f3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -207,6 +207,87 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== +"@microsoft/applicationinsights-analytics-js@2.6.4": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.6.4.tgz#22ad17276ed922f2f0e66b7efe304f31c50ede64" + integrity sha512-BHx3U6H4j3ddtl2wSJNt+kX2jG+qsvH4mNnimFJjZ4Mq9dheD3o6ghnBH8gQjIb5Up09JdyV5itsTZf1aC84Dg== + dependencies: + "@microsoft/applicationinsights-common" "2.6.4" + "@microsoft/applicationinsights-core-js" "2.6.4" + "@microsoft/applicationinsights-shims" "2.0.0" + "@microsoft/dynamicproto-js" "^1.1.4" + +"@microsoft/applicationinsights-channel-js@2.6.4": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.6.4.tgz#49c139e8d801835bfba25547cb57d030286dec8a" + integrity sha512-ps9ZglUw8nzou9/CxmfRgHO7aGjhopu9YqsadbQL6yz/q8LSj1w30+ADa3gSMYCEEy8FQrDo5e5UebDEnX/w+A== + dependencies: + "@microsoft/applicationinsights-common" "2.6.4" + "@microsoft/applicationinsights-core-js" "2.6.4" + "@microsoft/applicationinsights-shims" "2.0.0" + "@microsoft/dynamicproto-js" "^1.1.4" + +"@microsoft/applicationinsights-common@2.6.4": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.6.4.tgz#c3a4129c727127271c93c7e23b86cf18fcb9e3a0" + integrity sha512-/YLrKpxXL8zusjzu8GTYPuRrKw0OzUD4rLh8mxSlUZWK+SLOE/1loizJIesmd6OLgcgmOTrd1iZFVsuxn20b/g== + dependencies: + "@microsoft/applicationinsights-core-js" "2.6.4" + "@microsoft/applicationinsights-shims" "2.0.0" + "@microsoft/dynamicproto-js" "^1.1.4" + +"@microsoft/applicationinsights-core-js@2.6.4": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.6.4.tgz#163caa31c02e72cfe02fc4abebd6bffd6b587de3" + integrity sha512-rYxfJzl4aLXFGOLsRoJqyKj5qfhQTz1u/eXSo6N6gIIr/D+RCVNJZKVzeBh3xOOytm4UBGRshK0QFZJlIQL3Kw== + dependencies: + "@microsoft/applicationinsights-shims" "2.0.0" + "@microsoft/dynamicproto-js" "^1.1.4" + +"@microsoft/applicationinsights-dependencies-js@2.6.4": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.6.4.tgz#6d120965cdc3ef5798feac6bc729bc97d40a4bb5" + integrity sha512-mJ/yTe00HPlUpQCmQWGhY3ronlkhsPgIYBWjxstN4NHRO4Qt17/ITxFoRa+r50J8Sf4ouc4qBoEFSVc56x80bg== + dependencies: + "@microsoft/applicationinsights-common" "2.6.4" + "@microsoft/applicationinsights-core-js" "2.6.4" + "@microsoft/applicationinsights-shims" "2.0.0" + "@microsoft/dynamicproto-js" "^1.1.4" + +"@microsoft/applicationinsights-properties-js@2.6.4": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.6.4.tgz#d779cd552277e6049b30efe71024a39bad5264e7" + integrity sha512-SdIR3gVX46N0RdC0zV/pXKoCxwT+2+79ek6hVXvXa2o2I+JfgYEAxb1Q8flYNGEdlFd/Ge7BHcJLqFvjat1t4Q== + dependencies: + "@microsoft/applicationinsights-common" "2.6.4" + "@microsoft/applicationinsights-core-js" "2.6.4" + "@microsoft/applicationinsights-shims" "2.0.0" + "@microsoft/dynamicproto-js" "^1.1.4" + +"@microsoft/applicationinsights-shims@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.0.tgz#ee622588f14e58ae3c055b12431da8ed55d71991" + integrity sha512-OaKew7f7acuNFgKYjMSPrRTRQi93xUyONWeeCeBlJSx7oRNJaL0TqbTvW6j5GHnSr3mhinPtAQ+rCQWASBnOrg== + +"@microsoft/applicationinsights-web@^2.6.4": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web/-/applicationinsights-web-2.6.4.tgz#509069c798a4da2c2b2b494bb15eb328425d4e86" + integrity sha512-/lBngt78Q7YNs8Llu1xz22f9oT5Rr2lo1QmSSSSKal30HL6kkzkP14J2E6+0+O5dRmyTDgOSiEePt6AhF8NFzg== + dependencies: + "@microsoft/applicationinsights-analytics-js" "2.6.4" + "@microsoft/applicationinsights-channel-js" "2.6.4" + "@microsoft/applicationinsights-common" "2.6.4" + "@microsoft/applicationinsights-core-js" "2.6.4" + "@microsoft/applicationinsights-dependencies-js" "2.6.4" + "@microsoft/applicationinsights-properties-js" "2.6.4" + "@microsoft/applicationinsights-shims" "2.0.0" + "@microsoft/dynamicproto-js" "^1.1.4" + +"@microsoft/dynamicproto-js@^1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.4.tgz#40e1c0ad20743fcee1604a7df2c57faf0aa1af87" + integrity sha512-Ot53G927ykMF8cQ3/zq4foZtdk+Tt1YpX7aUTHxBU7UHNdkEiBvBfZSq+rnlUmKCJ19VatwPG4mNzvcGpBj4og== + "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b"