mirror of
https://github.com/Microsoft/vscode
synced 2024-10-02 09:18:59 +00:00
1DS appender for the web (#152489)
* 1ds web appender * Start testing web
This commit is contained in:
parent
dea813ff7c
commit
0edb88f3b5
|
@ -227,8 +227,6 @@
|
|||
"@vscode/ripgrep",
|
||||
"@vscode/iconv-lite-umd",
|
||||
"applicationinsights",
|
||||
"@microsoft/1ds-core-js",
|
||||
"@microsoft/1ds-post-js",
|
||||
"assert",
|
||||
"child_process",
|
||||
"console",
|
||||
|
@ -332,7 +330,9 @@
|
|||
"vs/base/~",
|
||||
"vs/base/parts/*/~",
|
||||
"vs/platform/*/~",
|
||||
"tas-client-umd" // node module allowed even in /common/
|
||||
"tas-client-umd", // node module allowed even in /common/
|
||||
"@microsoft/1ds-core-js",// node module allowed even in /common/
|
||||
"@microsoft/1ds-post-js" // node module allowed even in /common/
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
128
src/vs/platform/telemetry/browser/1dsAppender.ts
Normal file
128
src/vs/platform/telemetry/browser/1dsAppender.ts
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import type { AppInsightsCore, IExtendedConfiguration } from '@microsoft/1ds-core-js';
|
||||
import type { PostChannel } from '@microsoft/1ds-post-js';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import { ITelemetryAppender, validateTelemetryData } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
|
||||
const endpointUrl = 'https://mobile.events.data.microsoft.com/OneCollector/1.0';
|
||||
|
||||
async function getClient(instrumentationKey: string): Promise<AppInsightsCore> {
|
||||
const oneDs = await import('@microsoft/1ds-core-js');
|
||||
const postPlugin = await import('@microsoft/1ds-post-js');
|
||||
const appInsightsCore = new oneDs.AppInsightsCore();
|
||||
const collectorChannelPlugin: PostChannel = new postPlugin.PostChannel();
|
||||
// Configure the app insights core to send to collector++ and disable logging of debug info
|
||||
const coreConfig: IExtendedConfiguration = {
|
||||
instrumentationKey,
|
||||
endpointUrl,
|
||||
loggingLevelTelemetry: 0,
|
||||
loggingLevelConsole: 0,
|
||||
disableCookiesUsage: true,
|
||||
disableDbgExt: true,
|
||||
disableInstrumentationKeyValidation: true,
|
||||
channels: [[
|
||||
collectorChannelPlugin
|
||||
]]
|
||||
};
|
||||
|
||||
appInsightsCore.initialize(coreConfig, []);
|
||||
|
||||
appInsightsCore.addTelemetryInitializer((envelope) => {
|
||||
if (envelope.tags) {
|
||||
// Sets it to be internal only based on Windows UTC flagging
|
||||
envelope.tags['utc.flags'] = 0x0000811ECD;
|
||||
}
|
||||
});
|
||||
|
||||
return appInsightsCore;
|
||||
}
|
||||
|
||||
// TODO @lramos15 maybe make more in line with src/vs/platform/telemetry/browser/appInsightsAppender.ts with caching support
|
||||
export class OneDataSystemWebAppender implements ITelemetryAppender {
|
||||
|
||||
private _aiCoreOrKey: AppInsightsCore | string | undefined;
|
||||
private _asyncAiCore: Promise<AppInsightsCore> | null;
|
||||
|
||||
constructor(
|
||||
private _eventPrefix: string,
|
||||
private _defaultData: { [key: string]: any } | null,
|
||||
iKeyOrClientFactory: string | (() => AppInsightsCore), // allow factory function for testing
|
||||
) {
|
||||
if (!this._defaultData) {
|
||||
this._defaultData = Object.create(null);
|
||||
}
|
||||
|
||||
if (typeof iKeyOrClientFactory === 'function') {
|
||||
this._aiCoreOrKey = iKeyOrClientFactory();
|
||||
} else {
|
||||
this._aiCoreOrKey = iKeyOrClientFactory;
|
||||
}
|
||||
this._asyncAiCore = null;
|
||||
|
||||
// If we cannot fetch the endpoint it means it is down and we should not send any telemetry.
|
||||
// This is most likely due to ad blockers
|
||||
fetch(endpointUrl, { method: 'POST' }).catch(err => {
|
||||
this._aiCoreOrKey = undefined;
|
||||
});
|
||||
}
|
||||
|
||||
private _withAIClient(callback: (aiCore: AppInsightsCore) => void): void {
|
||||
if (!this._aiCoreOrKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof this._aiCoreOrKey !== 'string') {
|
||||
callback(this._aiCoreOrKey);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._asyncAiCore) {
|
||||
this._asyncAiCore = getClient(this._aiCoreOrKey);
|
||||
}
|
||||
|
||||
this._asyncAiCore.then(
|
||||
(aiClient) => {
|
||||
callback(aiClient);
|
||||
},
|
||||
(err) => {
|
||||
onUnexpectedError(err);
|
||||
console.error(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
log(eventName: string, data?: any): void {
|
||||
if (!this._aiCoreOrKey) {
|
||||
return;
|
||||
}
|
||||
data = mixin(data, this._defaultData);
|
||||
data = validateTelemetryData(data);
|
||||
|
||||
try {
|
||||
this._withAIClient((aiClient) => aiClient.track({
|
||||
name: this._eventPrefix + '/' + eventName,
|
||||
data: { ...data.properties, ...data.measurements },
|
||||
|
||||
}));
|
||||
} catch { }
|
||||
}
|
||||
|
||||
flush(): Promise<any> {
|
||||
if (this._aiCoreOrKey) {
|
||||
return new Promise(resolve => {
|
||||
this._withAIClient((aiClient) => {
|
||||
aiClient.unload(true, () => {
|
||||
this._aiCoreOrKey = undefined;
|
||||
resolve(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
|||
import { ILoggerService } from 'vs/platform/log/common/log';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { OneDataSystemWebAppender } from 'vs/platform/telemetry/browser/1dsAppender';
|
||||
import { WebAppInsightsAppender } from 'vs/platform/telemetry/browser/appInsightsAppender';
|
||||
import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings';
|
||||
import { ITelemetryData, ITelemetryInfo, ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
@ -37,11 +38,20 @@ export class TelemetryService extends Disposable implements ITelemetryService {
|
|||
) {
|
||||
super();
|
||||
|
||||
if (supportsTelemetry(productService, environmentService) && productService.aiConfig?.asimovKey) {
|
||||
if (supportsTelemetry(productService, environmentService) && productService.aiConfig?.asimovKey && productService.aiConfig?.ariaKey) {
|
||||
// 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 internalTesting = configurationService.getValue<boolean>('telemetry.internalTesting');
|
||||
const appenders = [];
|
||||
if (internalTesting) {
|
||||
const telemetryProvider: ITelemetryAppender = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : new OneDataSystemWebAppender('monacoworkbench', null, productService.aiConfig?.ariaKey);
|
||||
appenders.push(telemetryProvider);
|
||||
} else {
|
||||
const telemetryProvider: ITelemetryAppender = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : new WebAppInsightsAppender('monacoworkbench', productService.aiConfig?.asimovKey);
|
||||
appenders.push(telemetryProvider);
|
||||
}
|
||||
appenders.push(new TelemetryLogAppender(loggerService, environmentService));
|
||||
const config: ITelemetryServiceConfig = {
|
||||
appenders: [telemetryProvider, new TelemetryLogAppender(loggerService, environmentService)],
|
||||
appenders,
|
||||
commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.remoteAuthority, productService.embedderIdentifier, productService.removeTelemetryMachineId, environmentService.options && environmentService.options.resolveCommonTelemetryProperties),
|
||||
sendErrorTelemetry: this.sendErrorTelemetry,
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue