未验证 提交 12ae3310 编写于 作者: L Logan Ramos 提交者: GitHub

Move appenders to be better controlled by services (#133465)

* Cleanup telemetry appenders to be owned by service

* Add telemetry level to services

* simplify

* Fix compile

* Rename supportsTelemetryLogging -> supportsTelemetry
Co-authored-by: NSteVen Batten <sbatten@microsoft.com>
上级 758daa73
...@@ -61,11 +61,11 @@ import { ISharedProcessConfiguration } from 'vs/platform/sharedProcess/node/shar ...@@ -61,11 +61,11 @@ import { ISharedProcessConfiguration } from 'vs/platform/sharedProcess/node/shar
import { IStorageService } from 'vs/platform/storage/common/storage'; import { IStorageService } from 'vs/platform/storage/common/storage';
import { NativeStorageService } from 'vs/platform/storage/electron-sandbox/storageService'; import { NativeStorageService } from 'vs/platform/storage/electron-sandbox/storageService';
import { resolveCommonProperties } from 'vs/platform/telemetry/common/commonProperties'; import { resolveCommonProperties } from 'vs/platform/telemetry/common/commonProperties';
import { ICustomEndpointTelemetryService, ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { ICustomEndpointTelemetryService, ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { TelemetryAppenderChannel } from 'vs/platform/telemetry/common/telemetryIpc'; import { TelemetryAppenderChannel } from 'vs/platform/telemetry/common/telemetryIpc';
import { TelemetryLogAppender } from 'vs/platform/telemetry/common/telemetryLogAppender'; import { TelemetryLogAppender } from 'vs/platform/telemetry/common/telemetryLogAppender';
import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService';
import { combinedAppender, getTelemetryLevel, ITelemetryAppender, NullAppender, NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { supportsTelemetry, ITelemetryAppender, NullAppender, NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender'; import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender';
import { CustomEndpointTelemetryService } from 'vs/platform/telemetry/node/customEndpointTelemetryService'; import { CustomEndpointTelemetryService } from 'vs/platform/telemetry/node/customEndpointTelemetryService';
import { LocalReconnectConstants, TerminalIpcChannels, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; import { LocalReconnectConstants, TerminalIpcChannels, TerminalSettingId } from 'vs/platform/terminal/common/terminal';
...@@ -213,21 +213,21 @@ class SharedProcessMain extends Disposable { ...@@ -213,21 +213,21 @@ class SharedProcessMain extends Disposable {
// Telemetry // Telemetry
let telemetryService: ITelemetryService; let telemetryService: ITelemetryService;
let telemetryAppender: ITelemetryAppender; let telemetryAppender: ITelemetryAppender;
let telemetryLevel = getTelemetryLevel(productService, environmentService); const appenders: ITelemetryAppender[] = [];
if (telemetryLevel >= TelemetryLevel.LOG) { if (supportsTelemetry(productService, environmentService)) {
telemetryAppender = new TelemetryLogAppender(loggerService, environmentService); telemetryAppender = new TelemetryLogAppender(loggerService, environmentService);
appenders.push(telemetryAppender);
const { appRoot, extensionsPath, installSourcePath } = environmentService; const { appRoot, extensionsPath, installSourcePath } = environmentService;
// Application Insights // Application Insights
if (productService.aiConfig && productService.aiConfig.asimovKey && telemetryLevel >= TelemetryLevel.USER) { if (productService.aiConfig && productService.aiConfig.asimovKey) {
const appInsightsAppender = new AppInsightsAppender('monacoworkbench', null, productService.aiConfig.asimovKey); const appInsightsAppender = new AppInsightsAppender('monacoworkbench', null, productService.aiConfig.asimovKey);
this._register(toDisposable(() => appInsightsAppender.flush())); // Ensure the AI appender is disposed so that it flushes remaining data this._register(toDisposable(() => appInsightsAppender.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
telemetryAppender = combinedAppender(appInsightsAppender, telemetryAppender); appenders.push(appInsightsAppender);
} }
telemetryService = new TelemetryService({ telemetryService = new TelemetryService({
appender: telemetryAppender, appenders,
commonProperties: resolveCommonProperties(fileService, release(), hostname(), process.arch, productService.commit, productService.version, this.configuration.machineId, productService.msftInternalDomains, installSourcePath), commonProperties: resolveCommonProperties(fileService, release(), hostname(), process.arch, productService.commit, productService.version, this.configuration.machineId, productService.msftInternalDomains, installSourcePath),
sendErrorTelemetry: true, sendErrorTelemetry: true,
piiPaths: [appRoot, extensionsPath] piiPaths: [appRoot, extensionsPath]
......
...@@ -65,10 +65,10 @@ import { IStateMainService } from 'vs/platform/state/electron-main/state'; ...@@ -65,10 +65,10 @@ import { IStateMainService } from 'vs/platform/state/electron-main/state';
import { StorageDatabaseChannel } from 'vs/platform/storage/electron-main/storageIpc'; import { StorageDatabaseChannel } from 'vs/platform/storage/electron-main/storageIpc';
import { IStorageMainService, StorageMainService } from 'vs/platform/storage/electron-main/storageMainService'; import { IStorageMainService, StorageMainService } from 'vs/platform/storage/electron-main/storageMainService';
import { resolveCommonProperties } from 'vs/platform/telemetry/common/commonProperties'; import { resolveCommonProperties } from 'vs/platform/telemetry/common/commonProperties';
import { ITelemetryService, machineIdKey, TelemetryConfiguration, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService, machineIdKey, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc'; import { TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc';
import { ITelemetryServiceConfig, TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { ITelemetryServiceConfig, TelemetryService } from 'vs/platform/telemetry/common/telemetryService';
import { NullTelemetryService, getTelemetryLevel, getTelemetryConfiguration } from 'vs/platform/telemetry/common/telemetryUtils'; import { getTelemetryLevel, NullTelemetryService, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
import { IUpdateService } from 'vs/platform/update/common/update'; import { IUpdateService } from 'vs/platform/update/common/update';
import { UpdateChannel } from 'vs/platform/update/common/updateIpc'; import { UpdateChannel } from 'vs/platform/update/common/updateIpc';
import { DarwinUpdateService } from 'vs/platform/update/electron-main/updateService.darwin'; import { DarwinUpdateService } from 'vs/platform/update/electron-main/updateService.darwin';
...@@ -531,12 +531,12 @@ export class CodeApplication extends Disposable { ...@@ -531,12 +531,12 @@ export class CodeApplication extends Disposable {
services.set(IURLService, new SyncDescriptor(NativeURLService)); services.set(IURLService, new SyncDescriptor(NativeURLService));
// Telemetry // Telemetry
if (getTelemetryLevel(this.productService, this.environmentMainService) >= TelemetryLevel.USER) { if (supportsTelemetry(this.productService, this.environmentMainService)) {
const channel = getDelayedChannel(sharedProcessReady.then(client => client.getChannel('telemetryAppender'))); const channel = getDelayedChannel(sharedProcessReady.then(client => client.getChannel('telemetryAppender')));
const appender = new TelemetryAppenderClient(channel); const appender = new TelemetryAppenderClient(channel);
const commonProperties = resolveCommonProperties(this.fileService, release(), hostname(), process.arch, this.productService.commit, this.productService.version, machineId, this.productService.msftInternalDomains, this.environmentMainService.installSourcePath); const commonProperties = resolveCommonProperties(this.fileService, release(), hostname(), process.arch, this.productService.commit, this.productService.version, machineId, this.productService.msftInternalDomains, this.environmentMainService.installSourcePath);
const piiPaths = [this.environmentMainService.appRoot, this.environmentMainService.extensionsPath]; const piiPaths = [this.environmentMainService.appRoot, this.environmentMainService.extensionsPath];
const config: ITelemetryServiceConfig = { appender, commonProperties, piiPaths, sendErrorTelemetry: true }; const config: ITelemetryServiceConfig = { appenders: [appender], commonProperties, piiPaths, sendErrorTelemetry: true };
services.set(ITelemetryService, new SyncDescriptor(TelemetryService, [config])); services.set(ITelemetryService, new SyncDescriptor(TelemetryService, [config]));
} else { } else {
...@@ -981,8 +981,8 @@ export class CodeApplication extends Disposable { ...@@ -981,8 +981,8 @@ export class CodeApplication extends Disposable {
const argvString = argvContent.value.toString(); const argvString = argvContent.value.toString();
const argvJSON = JSON.parse(stripComments(argvString)); const argvJSON = JSON.parse(stripComments(argvString));
if (argvJSON['enable-crash-reporter'] === undefined) { if (argvJSON['enable-crash-reporter'] === undefined) {
const telemetryConfig = getTelemetryConfiguration(this.configurationService); const telemetryConfig = getTelemetryLevel(this.configurationService);
const enableCrashReporterSetting = telemetryConfig === TelemetryConfiguration.ON || telemetryConfig === TelemetryConfiguration.ERROR; const enableCrashReporterSetting = telemetryConfig >= TelemetryLevel.ERROR;
const enableCrashReporter = typeof enableCrashReporterSetting === 'boolean' ? enableCrashReporterSetting : true; const enableCrashReporter = typeof enableCrashReporterSetting === 'boolean' ? enableCrashReporterSetting : true;
const additionalArgvContent = [ const additionalArgvContent = [
'', '',
...@@ -1044,3 +1044,4 @@ export class CodeApplication extends Disposable { ...@@ -1044,3 +1044,4 @@ export class CodeApplication extends Disposable {
}); });
} }
} }
...@@ -43,9 +43,9 @@ import { IProductService } from 'vs/platform/product/common/productService'; ...@@ -43,9 +43,9 @@ import { IProductService } from 'vs/platform/product/common/productService';
import { IRequestService } from 'vs/platform/request/common/request'; import { IRequestService } from 'vs/platform/request/common/request';
import { RequestService } from 'vs/platform/request/node/requestService'; import { RequestService } from 'vs/platform/request/node/requestService';
import { resolveCommonProperties } from 'vs/platform/telemetry/common/commonProperties'; import { resolveCommonProperties } from 'vs/platform/telemetry/common/commonProperties';
import { ITelemetryService, machineIdKey, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService, machineIdKey } from 'vs/platform/telemetry/common/telemetry';
import { ITelemetryServiceConfig, TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { ITelemetryServiceConfig, TelemetryService } from 'vs/platform/telemetry/common/telemetryService';
import { combinedAppender, getTelemetryLevel, NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { supportsTelemetry, NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender'; import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender';
import { buildTelemetryMessage } from 'vs/platform/telemetry/node/telemetry'; import { buildTelemetryMessage } from 'vs/platform/telemetry/node/telemetry';
...@@ -89,7 +89,10 @@ class CliMain extends Disposable { ...@@ -89,7 +89,10 @@ class CliMain extends Disposable {
await this.doRun(environmentService, extensionManagementCLIService, fileService); await this.doRun(environmentService, extensionManagementCLIService, fileService);
// Flush the remaining data in AI adapter (with 1s timeout) // Flush the remaining data in AI adapter (with 1s timeout)
return raceTimeout(combinedAppender(...appenders).flush(), 1000); await Promise.all(appenders.map(a => {
raceTimeout(a.flush(), 1000);
}));
return;
}); });
} }
...@@ -148,7 +151,7 @@ class CliMain extends Disposable { ...@@ -148,7 +151,7 @@ class CliMain extends Disposable {
// Telemetry // Telemetry
const appenders: AppInsightsAppender[] = []; const appenders: AppInsightsAppender[] = [];
if (getTelemetryLevel(productService, environmentService) >= TelemetryLevel.USER) { if (supportsTelemetry(productService, environmentService)) {
if (productService.aiConfig && productService.aiConfig.asimovKey) { if (productService.aiConfig && productService.aiConfig.asimovKey) {
appenders.push(new AppInsightsAppender('monacoworkbench', null, productService.aiConfig.asimovKey)); appenders.push(new AppInsightsAppender('monacoworkbench', null, productService.aiConfig.asimovKey));
} }
...@@ -156,7 +159,7 @@ class CliMain extends Disposable { ...@@ -156,7 +159,7 @@ class CliMain extends Disposable {
const { appRoot, extensionsPath, installSourcePath } = environmentService; const { appRoot, extensionsPath, installSourcePath } = environmentService;
const config: ITelemetryServiceConfig = { const config: ITelemetryServiceConfig = {
appender: combinedAppender(...appenders), appenders,
sendErrorTelemetry: false, sendErrorTelemetry: false,
commonProperties: (async () => { commonProperties: (async () => {
let machineId: string | undefined = undefined; let machineId: string | undefined = undefined;
......
...@@ -38,7 +38,7 @@ import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayo ...@@ -38,7 +38,7 @@ import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayo
import { ILabelService, ResourceLabelFormatter, IFormatterChangeEvent } from 'vs/platform/label/common/label'; import { ILabelService, ResourceLabelFormatter, IFormatterChangeEvent } from 'vs/platform/label/common/label';
import { INotification, INotificationHandle, INotificationService, IPromptChoice, IPromptOptions, NoOpNotification, IStatusMessageOptions, NotificationsFilter } from 'vs/platform/notification/common/notification'; import { INotification, INotificationHandle, INotificationService, IPromptChoice, IPromptOptions, NoOpNotification, IStatusMessageOptions, NotificationsFilter } from 'vs/platform/notification/common/notification';
import { IProgressRunner, IEditorProgressService } from 'vs/platform/progress/common/progress'; import { IProgressRunner, IEditorProgressService } from 'vs/platform/progress/common/progress';
import { ITelemetryInfo, ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryInfo, ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, IWorkspaceFoldersWillChangeEvent, WorkbenchState, WorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, IWorkspaceFoldersWillChangeEvent, WorkbenchState, WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces'; import { ISingleFolderWorkspaceIdentifier, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
...@@ -574,7 +574,7 @@ export class SimpleResourcePropertiesService implements ITextResourcePropertiesS ...@@ -574,7 +574,7 @@ export class SimpleResourcePropertiesService implements ITextResourcePropertiesS
export class StandaloneTelemetryService implements ITelemetryService { export class StandaloneTelemetryService implements ITelemetryService {
declare readonly _serviceBrand: undefined; declare readonly _serviceBrand: undefined;
public isOptedIn = false; public telemetryLevel = TelemetryLevel.NONE;
public sendErrorTelemetry = false; public sendErrorTelemetry = false;
public setEnabled(value: boolean): void { public setEnabled(value: boolean): void {
......
...@@ -24,8 +24,8 @@ import { IProductService } from 'vs/platform/product/common/productService'; ...@@ -24,8 +24,8 @@ import { IProductService } from 'vs/platform/product/common/productService';
import { asJson, asText, IRequestService, isSuccess } from 'vs/platform/request/common/request'; import { asJson, asText, IRequestService, isSuccess } from 'vs/platform/request/common/request';
import { getServiceMachineId } from 'vs/platform/serviceMachineId/common/serviceMachineId'; import { getServiceMachineId } from 'vs/platform/serviceMachineId/common/serviceMachineId';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { ITelemetryService, TelemetryConfiguration, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { getTelemetryConfiguration, getTelemetryLevel } from 'vs/platform/telemetry/common/telemetryUtils'; import { getTelemetryLevel, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
const CURRENT_TARGET_PLATFORM = isWeb ? TargetPlatform.WEB : getTargetPlatform(platform, arch); const CURRENT_TARGET_PLATFORM = isWeb ? TargetPlatform.WEB : getTargetPlatform(platform, arch);
...@@ -959,7 +959,7 @@ export async function resolveMarketplaceHeaders(version: string, productService: ...@@ -959,7 +959,7 @@ export async function resolveMarketplaceHeaders(version: string, productService:
'User-Agent': `VSCode ${version}` 'User-Agent': `VSCode ${version}`
}; };
const uuid = await getServiceMachineId(environmentService, fileService, storageService); const uuid = await getServiceMachineId(environmentService, fileService, storageService);
if (getTelemetryLevel(productService, environmentService) >= TelemetryLevel.USER && getTelemetryConfiguration(configurationService) === TelemetryConfiguration.ON) { if (supportsTelemetry(productService, environmentService) && getTelemetryLevel(configurationService) === TelemetryLevel.USAGE) {
headers['X-Market-User-Id'] = uuid; headers['X-Market-User-Id'] = uuid;
} }
return headers; return headers;
......
...@@ -43,13 +43,11 @@ export interface ITelemetryService { ...@@ -43,13 +43,11 @@ export interface ITelemetryService {
publicLogError2<E extends ClassifiedEvent<T> = never, T extends GDPRClassification<T> = never>(eventName: string, data?: StrictPropertyCheck<T, E>): Promise<void>; publicLogError2<E extends ClassifiedEvent<T> = never, T extends GDPRClassification<T> = never>(eventName: string, data?: StrictPropertyCheck<T, E>): Promise<void>;
setEnabled(value: boolean): void;
getTelemetryInfo(): Promise<ITelemetryInfo>; getTelemetryInfo(): Promise<ITelemetryInfo>;
setExperimentProperty(name: string, value: string): void; setExperimentProperty(name: string, value: string): void;
isOptedIn: boolean; telemetryLevel: TelemetryLevel;
} }
export interface ITelemetryEndpoint { export interface ITelemetryEndpoint {
...@@ -81,8 +79,8 @@ export const TELEMETRY_OLD_SETTING_ID = 'telemetry.enableTelemetry'; ...@@ -81,8 +79,8 @@ export const TELEMETRY_OLD_SETTING_ID = 'telemetry.enableTelemetry';
export const enum TelemetryLevel { export const enum TelemetryLevel {
NONE = 0, NONE = 0,
LOG = 1, ERROR = 2,
USER = 2 USAGE = 3
} }
export const enum TelemetryConfiguration { export const enum TelemetryConfiguration {
......
...@@ -13,11 +13,11 @@ import { ConfigurationScope, Extensions, IConfigurationRegistry } from 'vs/platf ...@@ -13,11 +13,11 @@ import { ConfigurationScope, Extensions, IConfigurationRegistry } from 'vs/platf
import product from 'vs/platform/product/common/product'; import product from 'vs/platform/product/common/product';
import { Registry } from 'vs/platform/registry/common/platform'; import { Registry } from 'vs/platform/registry/common/platform';
import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings';
import { ITelemetryData, ITelemetryInfo, ITelemetryService, TelemetryConfiguration, TELEMETRY_OLD_SETTING_ID, TELEMETRY_SECTION_ID, TELEMETRY_SETTING_ID } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryData, ITelemetryInfo, ITelemetryService, TelemetryConfiguration, TelemetryLevel, TELEMETRY_OLD_SETTING_ID, TELEMETRY_SECTION_ID, TELEMETRY_SETTING_ID } from 'vs/platform/telemetry/common/telemetry';
import { getTelemetryConfiguration, ITelemetryAppender } from 'vs/platform/telemetry/common/telemetryUtils'; import { getTelemetryLevel, ITelemetryAppender } from 'vs/platform/telemetry/common/telemetryUtils';
export interface ITelemetryServiceConfig { export interface ITelemetryServiceConfig {
appender: ITelemetryAppender; appenders: ITelemetryAppender[];
sendErrorTelemetry?: boolean; sendErrorTelemetry?: boolean;
commonProperties?: Promise<{ [name: string]: any }>; commonProperties?: Promise<{ [name: string]: any }>;
piiPaths?: string[]; piiPaths?: string[];
...@@ -30,13 +30,11 @@ export class TelemetryService implements ITelemetryService { ...@@ -30,13 +30,11 @@ export class TelemetryService implements ITelemetryService {
declare readonly _serviceBrand: undefined; declare readonly _serviceBrand: undefined;
private _appender: ITelemetryAppender; private _appenders: ITelemetryAppender[];
private _commonProperties: Promise<{ [name: string]: any; }>; private _commonProperties: Promise<{ [name: string]: any; }>;
private _experimentProperties: { [name: string]: string } = {}; private _experimentProperties: { [name: string]: string } = {};
private _piiPaths: string[]; private _piiPaths: string[];
private _userOptIn: boolean; private _telemetryLevel: TelemetryLevel;
private _errorOptIn: boolean;
private _enabled: boolean;
public readonly sendErrorTelemetry: boolean; public readonly sendErrorTelemetry: boolean;
private readonly _disposables = new DisposableStore(); private readonly _disposables = new DisposableStore();
...@@ -46,12 +44,10 @@ export class TelemetryService implements ITelemetryService { ...@@ -46,12 +44,10 @@ export class TelemetryService implements ITelemetryService {
config: ITelemetryServiceConfig, config: ITelemetryServiceConfig,
@IConfigurationService private _configurationService: IConfigurationService @IConfigurationService private _configurationService: IConfigurationService
) { ) {
this._appender = config.appender; this._appenders = config.appenders;
this._commonProperties = config.commonProperties || Promise.resolve({}); this._commonProperties = config.commonProperties || Promise.resolve({});
this._piiPaths = config.piiPaths || []; this._piiPaths = config.piiPaths || [];
this._userOptIn = true; this._telemetryLevel = TelemetryLevel.USAGE;
this._errorOptIn = true;
this._enabled = true;
this.sendErrorTelemetry = !!config.sendErrorTelemetry; this.sendErrorTelemetry = !!config.sendErrorTelemetry;
// static cleanup pattern for: `file:///DANGEROUS/PATH/resources/app/Useful/Information` // static cleanup pattern for: `file:///DANGEROUS/PATH/resources/app/Useful/Information`
...@@ -62,15 +58,15 @@ export class TelemetryService implements ITelemetryService { ...@@ -62,15 +58,15 @@ export class TelemetryService implements ITelemetryService {
} }
this._updateUserOptIn(); this._updateTelemetryLevel();
this._configurationService.onDidChangeConfiguration(this._updateUserOptIn, this, this._disposables); this._configurationService.onDidChangeConfiguration(this._updateTelemetryLevel, this, this._disposables);
type OptInClassification = { type OptInClassification = {
optIn: { classification: 'SystemMetaData', purpose: 'BusinessInsight', isMeasurement: true }; optIn: { classification: 'SystemMetaData', purpose: 'BusinessInsight', isMeasurement: true };
}; };
type OptInEvent = { type OptInEvent = {
optIn: boolean; optIn: boolean;
}; };
this.publicLog2<OptInEvent, OptInClassification>('optInStatus', { optIn: this._userOptIn }); this.publicLog2<OptInEvent, OptInClassification>('optInStatus', { optIn: this._telemetryLevel === TelemetryLevel.USAGE });
this._commonProperties.then(values => { this._commonProperties.then(values => {
const isHashedId = /^[a-f0-9]+$/i.test(values['common.machineId']); const isHashedId = /^[a-f0-9]+$/i.test(values['common.machineId']);
...@@ -95,10 +91,6 @@ export class TelemetryService implements ITelemetryService { ...@@ -95,10 +91,6 @@ export class TelemetryService implements ITelemetryService {
this._experimentProperties[name] = value; this._experimentProperties[name] = value;
} }
setEnabled(value: boolean): void {
this._enabled = value;
}
// TODO: @sbatten @lramos15 bring this code in after one iteration // TODO: @sbatten @lramos15 bring this code in after one iteration
// private _convertOldTelemetrySettingToNew(): void { // private _convertOldTelemetrySettingToNew(): void {
// const telemetryValue = this._configurationService.getValue(TELEMETRY_OLD_SETTING_ID); // const telemetryValue = this._configurationService.getValue(TELEMETRY_OLD_SETTING_ID);
...@@ -107,14 +99,12 @@ export class TelemetryService implements ITelemetryService { ...@@ -107,14 +99,12 @@ export class TelemetryService implements ITelemetryService {
// } // }
// } // }
private _updateUserOptIn(): void { private _updateTelemetryLevel(): void {
const telemetryConfig = getTelemetryConfiguration(this._configurationService); this._telemetryLevel = getTelemetryLevel(this._configurationService);
this._errorOptIn = telemetryConfig !== TelemetryConfiguration.OFF;
this._userOptIn = telemetryConfig === TelemetryConfiguration.ON;
} }
get isOptedIn(): boolean { get telemetryLevel(): TelemetryLevel {
return this._userOptIn && this._enabled; return this._telemetryLevel;
} }
async getTelemetryInfo(): Promise<ITelemetryInfo> { async getTelemetryInfo(): Promise<ITelemetryInfo> {
...@@ -134,9 +124,9 @@ export class TelemetryService implements ITelemetryService { ...@@ -134,9 +124,9 @@ export class TelemetryService implements ITelemetryService {
this._disposables.dispose(); this._disposables.dispose();
} }
publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): Promise<any> { private _log(eventName: string, eventLevel: TelemetryLevel, data?: ITelemetryData, anonymizeFilePaths?: boolean): Promise<any> {
// don't send events when the user is optout // don't send events when the user is optout
if (!this.isOptedIn) { if (this.telemetryLevel < eventLevel) {
return Promise.resolve(undefined); return Promise.resolve(undefined);
} }
...@@ -156,7 +146,8 @@ export class TelemetryService implements ITelemetryService { ...@@ -156,7 +146,8 @@ export class TelemetryService implements ITelemetryService {
return undefined; return undefined;
}); });
this._appender.log(eventName, data); // Log to the appenders of sufficient level
this._appenders.forEach(a => a.log(eventName, data));
}, err => { }, err => {
// unsure what to do now... // unsure what to do now...
...@@ -164,17 +155,21 @@ export class TelemetryService implements ITelemetryService { ...@@ -164,17 +155,21 @@ export class TelemetryService implements ITelemetryService {
}); });
} }
publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): Promise<any> {
return this._log(eventName, TelemetryLevel.USAGE, data, anonymizeFilePaths);
}
publicLog2<E extends ClassifiedEvent<T> = never, T extends GDPRClassification<T> = never>(eventName: string, data?: StrictPropertyCheck<T, E>, anonymizeFilePaths?: boolean): Promise<any> { publicLog2<E extends ClassifiedEvent<T> = never, T extends GDPRClassification<T> = never>(eventName: string, data?: StrictPropertyCheck<T, E>, anonymizeFilePaths?: boolean): Promise<any> {
return this.publicLog(eventName, data as ITelemetryData, anonymizeFilePaths); return this.publicLog(eventName, data as ITelemetryData, anonymizeFilePaths);
} }
publicLogError(errorEventName: string, data?: ITelemetryData): Promise<any> { publicLogError(errorEventName: string, data?: ITelemetryData): Promise<any> {
if (!this.sendErrorTelemetry || !this._errorOptIn) { if (!this.sendErrorTelemetry) {
return Promise.resolve(undefined); return Promise.resolve(undefined);
} }
// Send error event and anonymize paths // Send error event and anonymize paths
return this.publicLog(errorEventName, data, true); return this._log(errorEventName, TelemetryLevel.ERROR, data, true);
} }
publicLogError2<E extends ClassifiedEvent<T> = never, T extends GDPRClassification<T> = never>(eventName: string, data?: StrictPropertyCheck<T, E>): Promise<any> { publicLogError2<E extends ClassifiedEvent<T> = never, T extends GDPRClassification<T> = never>(eventName: string, data?: StrictPropertyCheck<T, E>): Promise<any> {
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { Promises } from 'vs/base/common/async';
import { IDisposable } from 'vs/base/common/lifecycle'; import { IDisposable } from 'vs/base/common/lifecycle';
import { safeStringify } from 'vs/base/common/objects'; import { safeStringify } from 'vs/base/common/objects';
import { isObject } from 'vs/base/common/types'; import { isObject } from 'vs/base/common/types';
...@@ -31,8 +30,7 @@ export const NullTelemetryService = new class implements ITelemetryService { ...@@ -31,8 +30,7 @@ export const NullTelemetryService = new class implements ITelemetryService {
} }
setExperimentProperty() { } setExperimentProperty() { }
setEnabled() { } telemetryLevel = TelemetryLevel.NONE;
isOptedIn = true;
getTelemetryInfo(): Promise<ITelemetryInfo> { getTelemetryInfo(): Promise<ITelemetryInfo> {
return Promise.resolve({ return Promise.resolve({
instanceId: 'someValue.instanceId', instanceId: 'someValue.instanceId',
...@@ -60,13 +58,6 @@ export interface ITelemetryAppender { ...@@ -60,13 +58,6 @@ export interface ITelemetryAppender {
flush(): Promise<any>; flush(): Promise<any>;
} }
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())),
};
}
export const NullAppender: ITelemetryAppender = { log: () => null, flush: () => Promise.resolve(null) }; export const NullAppender: ITelemetryAppender = { log: () => null, flush: () => Promise.resolve(null) };
...@@ -107,44 +98,40 @@ export function configurationTelemetry(telemetryService: ITelemetryService, conf ...@@ -107,44 +98,40 @@ export function configurationTelemetry(telemetryService: ITelemetryService, conf
/** /**
* Determines how telemetry is handled based on the current running configuration. * Determines how telemetry is handled based on the current running configuration.
* To log telemetry locally, the client must not disable telemetry via the CLI * To log telemetry locally, the client must not disable telemetry via the CLI
* If client is a built product and telemetry is enabled via the product.json, defer to user setting * If client is a built product and telemetry is enabled via the product.json, telemetry is supported
* Note that when running from sources, we log telemetry locally but do not send it * This function is only used to determine if telemetry contructs should occur, but is not impacted by user configuration
* *
* @param productService * @param productService
* @param environmentService * @param environmentService
* @returns NONE - telemetry is completely disabled, LOG - telemetry is logged locally but not sent, USER - verify with user setting * @returns false - telemetry is completely disabled, true - telemetry is logged locally, but may not be sent
*/ */
export function getTelemetryLevel(productService: IProductService, environmentService: IEnvironmentService): TelemetryLevel { export function supportsTelemetry(productService: IProductService, environmentService: IEnvironmentService): boolean {
if (environmentService.disableTelemetry || !productService.enableTelemetry) { return !(environmentService.disableTelemetry || !productService.enableTelemetry);
return TelemetryLevel.NONE;
}
if (!environmentService.isBuilt) {
return TelemetryLevel.LOG;
}
return TelemetryLevel.USER;
} }
/** /**
* Determines how telemetry is handled based on the current running configuration. * Determines how telemetry is handled based on the user's configuration.
* To log telemetry locally, the client must not disable telemetry via the CLI
* If client is a built product and telemetry is enabled via the product.json, defer to user setting
* Note that when running from sources, we log telemetry locally but do not send it
* *
* @param configurationService * @param configurationService
* @returns OFF, ERROR, ON * @returns OFF, ERROR, ON
*/ */
export function getTelemetryConfiguration(configurationService: IConfigurationService): TelemetryConfiguration { export function getTelemetryLevel(configurationService: IConfigurationService): TelemetryLevel {
const newConfig = configurationService.getValue<TelemetryConfiguration>(TELEMETRY_SETTING_ID); const newConfig = configurationService.getValue<TelemetryConfiguration>(TELEMETRY_SETTING_ID);
const oldConfig = configurationService.getValue(TELEMETRY_OLD_SETTING_ID); const oldConfig = configurationService.getValue(TELEMETRY_OLD_SETTING_ID);
// Check old config for disablement // Check old config for disablement
if (oldConfig !== undefined && oldConfig === false) { if (oldConfig !== undefined && oldConfig === false) {
return TelemetryConfiguration.OFF; return TelemetryLevel.NONE;
} }
return newConfig ?? TelemetryConfiguration.ON; switch (newConfig ?? TelemetryConfiguration.ON) {
case TelemetryConfiguration.ON:
return TelemetryLevel.USAGE;
case TelemetryConfiguration.ERROR:
return TelemetryLevel.ERROR;
case TelemetryConfiguration.OFF:
return TelemetryLevel.NONE;
}
} }
export interface Properties { export interface Properties {
......
...@@ -12,8 +12,6 @@ import { ICustomEndpointTelemetryService, ITelemetryData, ITelemetryEndpoint, IT ...@@ -12,8 +12,6 @@ import { ICustomEndpointTelemetryService, ITelemetryData, ITelemetryEndpoint, IT
import { TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc'; import { TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc';
import { TelemetryLogAppender } from 'vs/platform/telemetry/common/telemetryLogAppender'; import { TelemetryLogAppender } from 'vs/platform/telemetry/common/telemetryLogAppender';
import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService';
import { combinedAppender } from 'vs/platform/telemetry/common/telemetryUtils';
export class CustomEndpointTelemetryService implements ICustomEndpointTelemetryService { export class CustomEndpointTelemetryService implements ICustomEndpointTelemetryService {
declare readonly _serviceBrand: undefined; declare readonly _serviceBrand: undefined;
...@@ -48,13 +46,13 @@ export class CustomEndpointTelemetryService implements ICustomEndpointTelemetryS ...@@ -48,13 +46,13 @@ export class CustomEndpointTelemetryService implements ICustomEndpointTelemetryS
); );
const channel = client.getChannel('telemetryAppender'); const channel = client.getChannel('telemetryAppender');
const appender = combinedAppender( const appenders = [
new TelemetryAppenderClient(channel), new TelemetryAppenderClient(channel),
new TelemetryLogAppender(this.loggerService, this.environmentService, `[${endpoint.id}] `), new TelemetryLogAppender(this.loggerService, this.environmentService, `[${endpoint.id}] `),
); ];
this.customTelemetryServices.set(endpoint.id, new TelemetryService({ this.customTelemetryServices.set(endpoint.id, new TelemetryService({
appender, appenders,
sendErrorTelemetry: endpoint.sendErrorTelemetry sendErrorTelemetry: endpoint.sendErrorTelemetry
}, this.configurationService)); }, this.configurationService));
} }
......
...@@ -9,7 +9,7 @@ import * as Errors from 'vs/base/common/errors'; ...@@ -9,7 +9,7 @@ import * as Errors from 'vs/base/common/errors';
import { Emitter } from 'vs/base/common/event'; import { Emitter } from 'vs/base/common/event';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import ErrorTelemetry from 'vs/platform/telemetry/browser/errorTelemetry'; import ErrorTelemetry from 'vs/platform/telemetry/browser/errorTelemetry';
import { ITelemetryData, TelemetryConfiguration } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryData, TelemetryConfiguration, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { ITelemetryServiceConfig, TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { ITelemetryServiceConfig, TelemetryService } from 'vs/platform/telemetry/common/telemetryService';
import { ITelemetryAppender, NullAppender } from 'vs/platform/telemetry/common/telemetryUtils'; import { ITelemetryAppender, NullAppender } from 'vs/platform/telemetry/common/telemetryUtils';
...@@ -89,7 +89,7 @@ suite('TelemetryService', () => { ...@@ -89,7 +89,7 @@ suite('TelemetryService', () => {
test('Disposing', sinonTestFn(function () { test('Disposing', sinonTestFn(function () {
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new TelemetryService({ appender: testAppender }, new TestConfigurationService()); let service = new TelemetryService({ appenders: [testAppender] }, new TestConfigurationService());
return service.publicLog('testPrivateEvent').then(() => { return service.publicLog('testPrivateEvent').then(() => {
assert.strictEqual(testAppender.getEventsCount(), 3); assert.strictEqual(testAppender.getEventsCount(), 3);
...@@ -102,7 +102,7 @@ suite('TelemetryService', () => { ...@@ -102,7 +102,7 @@ suite('TelemetryService', () => {
// event reporting // event reporting
test('Simple event', sinonTestFn(function () { test('Simple event', sinonTestFn(function () {
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new TelemetryService({ appender: testAppender }, new TestConfigurationService()); let service = new TelemetryService({ appenders: [testAppender] }, new TestConfigurationService());
return service.publicLog('testEvent').then(_ => { return service.publicLog('testEvent').then(_ => {
assert.strictEqual(testAppender.getEventsCount(), 3); assert.strictEqual(testAppender.getEventsCount(), 3);
...@@ -117,7 +117,7 @@ suite('TelemetryService', () => { ...@@ -117,7 +117,7 @@ suite('TelemetryService', () => {
test('Event with data', sinonTestFn(function () { test('Event with data', sinonTestFn(function () {
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new TelemetryService({ appender: testAppender }, new TestConfigurationService()); let service = new TelemetryService({ appenders: [testAppender] }, new TestConfigurationService());
return service.publicLog('testEvent', { return service.publicLog('testEvent', {
'stringProp': 'property', 'stringProp': 'property',
...@@ -144,7 +144,7 @@ suite('TelemetryService', () => { ...@@ -144,7 +144,7 @@ suite('TelemetryService', () => {
test('common properties added to *all* events, simple event', function () { test('common properties added to *all* events, simple event', function () {
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new TelemetryService({ let service = new TelemetryService({
appender: testAppender, appenders: [testAppender],
commonProperties: Promise.resolve({ foo: 'JA!', get bar() { return Math.random(); } }) commonProperties: Promise.resolve({ foo: 'JA!', get bar() { return Math.random(); } })
}, new TestConfigurationService()); }, new TestConfigurationService());
...@@ -162,7 +162,7 @@ suite('TelemetryService', () => { ...@@ -162,7 +162,7 @@ suite('TelemetryService', () => {
test('common properties added to *all* events, event with data', function () { test('common properties added to *all* events, event with data', function () {
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new TelemetryService({ let service = new TelemetryService({
appender: testAppender, appenders: [testAppender],
commonProperties: Promise.resolve({ foo: 'JA!', get bar() { return Math.random(); } }) commonProperties: Promise.resolve({ foo: 'JA!', get bar() { return Math.random(); } })
}, new TestConfigurationService()); }, new TestConfigurationService());
...@@ -181,7 +181,7 @@ suite('TelemetryService', () => { ...@@ -181,7 +181,7 @@ suite('TelemetryService', () => {
test('TelemetryInfo comes from properties', function () { test('TelemetryInfo comes from properties', function () {
let service = new TelemetryService({ let service = new TelemetryService({
appender: NullAppender, appenders: [NullAppender],
commonProperties: Promise.resolve({ commonProperties: Promise.resolve({
sessionID: 'one', sessionID: 'one',
['common.instanceId']: 'two', ['common.instanceId']: 'two',
...@@ -200,7 +200,7 @@ suite('TelemetryService', () => { ...@@ -200,7 +200,7 @@ suite('TelemetryService', () => {
test('telemetry on by default', sinonTestFn(function () { test('telemetry on by default', sinonTestFn(function () {
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new TelemetryService({ appender: testAppender }, new TestConfigurationService()); let service = new TelemetryService({ appenders: [testAppender] }, new TestConfigurationService());
return service.publicLog('testEvent').then(() => { return service.publicLog('testEvent').then(() => {
assert.strictEqual(testAppender.getEventsCount(), 3); assert.strictEqual(testAppender.getEventsCount(), 3);
...@@ -241,7 +241,7 @@ suite('TelemetryService', () => { ...@@ -241,7 +241,7 @@ suite('TelemetryService', () => {
try { try {
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new JoinableTelemetryService({ appender: testAppender }); let service = new JoinableTelemetryService({ appenders: [testAppender] });
const errorTelemetry = new ErrorTelemetry(service); const errorTelemetry = new ErrorTelemetry(service);
...@@ -301,7 +301,7 @@ suite('TelemetryService', () => { ...@@ -301,7 +301,7 @@ suite('TelemetryService', () => {
window.onerror = errorStub; window.onerror = errorStub;
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new JoinableTelemetryService({ appender: testAppender }); let service = new JoinableTelemetryService({ appenders: [testAppender] });
const errorTelemetry = new ErrorTelemetry(service); const errorTelemetry = new ErrorTelemetry(service);
let testError = new Error('test'); let testError = new Error('test');
...@@ -330,7 +330,7 @@ suite('TelemetryService', () => { ...@@ -330,7 +330,7 @@ suite('TelemetryService', () => {
window.onerror = errorStub; window.onerror = errorStub;
let settings = new ErrorTestingSettings(); let settings = new ErrorTestingSettings();
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new JoinableTelemetryService({ appender: testAppender }); let service = new JoinableTelemetryService({ appenders: [testAppender] });
const errorTelemetry = new ErrorTelemetry(service); const errorTelemetry = new ErrorTelemetry(service);
let personInfoWithSpaces = settings.personalInfo.slice(0, 2) + ' ' + settings.personalInfo.slice(2); let personInfoWithSpaces = settings.personalInfo.slice(0, 2) + ' ' + settings.personalInfo.slice(2);
...@@ -354,7 +354,7 @@ suite('TelemetryService', () => { ...@@ -354,7 +354,7 @@ suite('TelemetryService', () => {
window.onerror = errorStub; window.onerror = errorStub;
let settings = new ErrorTestingSettings(); let settings = new ErrorTestingSettings();
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new JoinableTelemetryService({ appender: testAppender }); let service = new JoinableTelemetryService({ appenders: [testAppender] });
const errorTelemetry = new ErrorTelemetry(service); const errorTelemetry = new ErrorTelemetry(service);
let dangerousFilenameError: any = new Error('dangerousFilename'); let dangerousFilenameError: any = new Error('dangerousFilename');
...@@ -386,7 +386,7 @@ suite('TelemetryService', () => { ...@@ -386,7 +386,7 @@ suite('TelemetryService', () => {
try { try {
let settings = new ErrorTestingSettings(); let settings = new ErrorTestingSettings();
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new JoinableTelemetryService({ appender: testAppender }); let service = new JoinableTelemetryService({ appenders: [testAppender] });
const errorTelemetry = new ErrorTelemetry(service); const errorTelemetry = new ErrorTelemetry(service);
let dangerousPathWithoutImportantInfoError: any = new Error(settings.dangerousPathWithoutImportantInfo); let dangerousPathWithoutImportantInfoError: any = new Error(settings.dangerousPathWithoutImportantInfo);
...@@ -416,7 +416,7 @@ suite('TelemetryService', () => { ...@@ -416,7 +416,7 @@ suite('TelemetryService', () => {
window.onerror = errorStub; window.onerror = errorStub;
let settings = new ErrorTestingSettings(); let settings = new ErrorTestingSettings();
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new JoinableTelemetryService({ appender: testAppender }); let service = new JoinableTelemetryService({ appenders: [testAppender] });
const errorTelemetry = new ErrorTelemetry(service); const errorTelemetry = new ErrorTelemetry(service);
let dangerousPathWithoutImportantInfoError: any = new Error('dangerousPathWithoutImportantInfo'); let dangerousPathWithoutImportantInfoError: any = new Error('dangerousPathWithoutImportantInfo');
...@@ -446,7 +446,7 @@ suite('TelemetryService', () => { ...@@ -446,7 +446,7 @@ suite('TelemetryService', () => {
try { try {
let settings = new ErrorTestingSettings(); let settings = new ErrorTestingSettings();
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new JoinableTelemetryService({ appender: testAppender }); let service = new JoinableTelemetryService({ appenders: [testAppender] });
const errorTelemetry = new ErrorTelemetry(service); const errorTelemetry = new ErrorTelemetry(service);
let dangerousPathWithImportantInfoError: any = new Error(settings.dangerousPathWithImportantInfo); let dangerousPathWithImportantInfoError: any = new Error(settings.dangerousPathWithImportantInfo);
...@@ -479,7 +479,7 @@ suite('TelemetryService', () => { ...@@ -479,7 +479,7 @@ suite('TelemetryService', () => {
window.onerror = errorStub; window.onerror = errorStub;
let settings = new ErrorTestingSettings(); let settings = new ErrorTestingSettings();
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new JoinableTelemetryService({ appender: testAppender }); let service = new JoinableTelemetryService({ appenders: [testAppender] });
const errorTelemetry = new ErrorTelemetry(service); const errorTelemetry = new ErrorTelemetry(service);
let dangerousPathWithImportantInfoError: any = new Error('dangerousPathWithImportantInfo'); let dangerousPathWithImportantInfoError: any = new Error('dangerousPathWithImportantInfo');
...@@ -511,7 +511,7 @@ suite('TelemetryService', () => { ...@@ -511,7 +511,7 @@ suite('TelemetryService', () => {
try { try {
let settings = new ErrorTestingSettings(); let settings = new ErrorTestingSettings();
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new JoinableTelemetryService({ appender: testAppender }); let service = new JoinableTelemetryService({ appenders: [testAppender] });
const errorTelemetry = new ErrorTelemetry(service); const errorTelemetry = new ErrorTelemetry(service);
let dangerousPathWithImportantInfoError: any = new Error(settings.dangerousPathWithImportantInfo); let dangerousPathWithImportantInfoError: any = new Error(settings.dangerousPathWithImportantInfo);
...@@ -540,7 +540,7 @@ suite('TelemetryService', () => { ...@@ -540,7 +540,7 @@ suite('TelemetryService', () => {
window.onerror = errorStub; window.onerror = errorStub;
let settings = new ErrorTestingSettings(); let settings = new ErrorTestingSettings();
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new JoinableTelemetryService({ appender: testAppender }); let service = new JoinableTelemetryService({ appenders: [testAppender] });
const errorTelemetry = new ErrorTelemetry(service); const errorTelemetry = new ErrorTelemetry(service);
let dangerousPathWithImportantInfoError: any = new Error('dangerousPathWithImportantInfo'); let dangerousPathWithImportantInfoError: any = new Error('dangerousPathWithImportantInfo');
...@@ -569,7 +569,7 @@ suite('TelemetryService', () => { ...@@ -569,7 +569,7 @@ suite('TelemetryService', () => {
try { try {
let settings = new ErrorTestingSettings(); let settings = new ErrorTestingSettings();
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new JoinableTelemetryService({ appender: testAppender, piiPaths: [settings.personalInfo + '/resources/app/'] }); let service = new JoinableTelemetryService({ appenders: [testAppender], piiPaths: [settings.personalInfo + '/resources/app/'] });
const errorTelemetry = new ErrorTelemetry(service); const errorTelemetry = new ErrorTelemetry(service);
let dangerousPathWithImportantInfoError: any = new Error(settings.dangerousPathWithImportantInfo); let dangerousPathWithImportantInfoError: any = new Error(settings.dangerousPathWithImportantInfo);
...@@ -602,7 +602,7 @@ suite('TelemetryService', () => { ...@@ -602,7 +602,7 @@ suite('TelemetryService', () => {
window.onerror = errorStub; window.onerror = errorStub;
let settings = new ErrorTestingSettings(); let settings = new ErrorTestingSettings();
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new JoinableTelemetryService({ appender: testAppender, piiPaths: [settings.personalInfo + '/resources/app/'] }); let service = new JoinableTelemetryService({ appenders: [testAppender], piiPaths: [settings.personalInfo + '/resources/app/'] });
const errorTelemetry = new ErrorTelemetry(service); const errorTelemetry = new ErrorTelemetry(service);
let dangerousPathWithImportantInfoError: any = new Error('dangerousPathWithImportantInfo'); let dangerousPathWithImportantInfoError: any = new Error('dangerousPathWithImportantInfo');
...@@ -634,7 +634,7 @@ suite('TelemetryService', () => { ...@@ -634,7 +634,7 @@ suite('TelemetryService', () => {
try { try {
let settings = new ErrorTestingSettings(); let settings = new ErrorTestingSettings();
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new JoinableTelemetryService({ appender: testAppender }); let service = new JoinableTelemetryService({ appenders: [testAppender] });
const errorTelemetry = new ErrorTelemetry(service); const errorTelemetry = new ErrorTelemetry(service);
let missingModelError: any = new Error(settings.missingModelMessage); let missingModelError: any = new Error(settings.missingModelMessage);
...@@ -667,7 +667,7 @@ suite('TelemetryService', () => { ...@@ -667,7 +667,7 @@ suite('TelemetryService', () => {
window.onerror = errorStub; window.onerror = errorStub;
let settings = new ErrorTestingSettings(); let settings = new ErrorTestingSettings();
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new JoinableTelemetryService({ appender: testAppender }); let service = new JoinableTelemetryService({ appenders: [testAppender] });
const errorTelemetry = new ErrorTelemetry(service); const errorTelemetry = new ErrorTelemetry(service);
let missingModelError: any = new Error('missingModelMessage'); let missingModelError: any = new Error('missingModelMessage');
...@@ -700,7 +700,7 @@ suite('TelemetryService', () => { ...@@ -700,7 +700,7 @@ suite('TelemetryService', () => {
try { try {
let settings = new ErrorTestingSettings(); let settings = new ErrorTestingSettings();
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new JoinableTelemetryService({ appender: testAppender }); let service = new JoinableTelemetryService({ appenders: [testAppender] });
const errorTelemetry = new ErrorTelemetry(service); const errorTelemetry = new ErrorTelemetry(service);
let noSuchFileError: any = new Error(settings.noSuchFileMessage); let noSuchFileError: any = new Error(settings.noSuchFileMessage);
...@@ -737,7 +737,7 @@ suite('TelemetryService', () => { ...@@ -737,7 +737,7 @@ suite('TelemetryService', () => {
window.onerror = errorStub; window.onerror = errorStub;
let settings = new ErrorTestingSettings(); let settings = new ErrorTestingSettings();
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new JoinableTelemetryService({ appender: testAppender }); let service = new JoinableTelemetryService({ appenders: [testAppender] });
const errorTelemetry = new ErrorTelemetry(service); const errorTelemetry = new ErrorTelemetry(service);
let noSuchFileError: any = new Error('noSuchFileMessage'); let noSuchFileError: any = new Error('noSuchFileMessage');
...@@ -768,7 +768,7 @@ suite('TelemetryService', () => { ...@@ -768,7 +768,7 @@ suite('TelemetryService', () => {
test('Telemetry Service sends events when telemetry is on', sinonTestFn(function () { test('Telemetry Service sends events when telemetry is on', sinonTestFn(function () {
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new TelemetryService({ appender: testAppender }, new TestConfigurationService()); let service = new TelemetryService({ appenders: [testAppender] }, new TestConfigurationService());
return service.publicLog('testEvent').then(() => { return service.publicLog('testEvent').then(() => {
assert.strictEqual(testAppender.getEventsCount(), 3); assert.strictEqual(testAppender.getEventsCount(), 3);
...@@ -783,7 +783,7 @@ suite('TelemetryService', () => { ...@@ -783,7 +783,7 @@ suite('TelemetryService', () => {
let testAppender = new TestTelemetryAppender(); let testAppender = new TestTelemetryAppender();
let service = new TelemetryService({ let service = new TelemetryService({
appender: testAppender appenders: [testAppender]
}, new class extends TestConfigurationService { }, new class extends TestConfigurationService {
override onDidChangeConfiguration = emitter.event; override onDidChangeConfiguration = emitter.event;
override getValue() { override getValue() {
...@@ -791,15 +791,15 @@ suite('TelemetryService', () => { ...@@ -791,15 +791,15 @@ suite('TelemetryService', () => {
} }
}()); }());
assert.strictEqual(service.isOptedIn, false); assert.strictEqual(service.telemetryLevel, TelemetryLevel.NONE);
telemetryLevel = TelemetryConfiguration.ON; telemetryLevel = TelemetryConfiguration.ON;
emitter.fire({}); emitter.fire({});
assert.strictEqual(service.isOptedIn, true); assert.strictEqual(service.telemetryLevel, TelemetryLevel.USAGE);
telemetryLevel = TelemetryConfiguration.ERROR; telemetryLevel = TelemetryConfiguration.ERROR;
emitter.fire({}); emitter.fire({});
assert.strictEqual(service.isOptedIn, false); assert.strictEqual(service.telemetryLevel, TelemetryLevel.ERROR);
service.dispose(); service.dispose();
}); });
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { ITelemetryService, TelemetryConfiguration, TelemetryLevel, TELEMETRY_SETTING_ID } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService, TelemetryLevel, TELEMETRY_SETTING_ID } from 'vs/platform/telemetry/common/telemetry';
import { MainThreadTelemetryShape, MainContext, IExtHostContext, ExtHostTelemetryShape, ExtHostContext } from '../common/extHost.protocol'; import { MainThreadTelemetryShape, MainContext, IExtHostContext, ExtHostTelemetryShape, ExtHostContext } from '../common/extHost.protocol';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings';
...@@ -11,7 +11,7 @@ import { Disposable } from 'vs/base/common/lifecycle'; ...@@ -11,7 +11,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IProductService } from 'vs/platform/product/common/productService'; import { IProductService } from 'vs/platform/product/common/productService';
import { getTelemetryConfiguration, getTelemetryLevel } from 'vs/platform/telemetry/common/telemetryUtils'; import { getTelemetryLevel, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
@extHostNamedCustomer(MainContext.MainThreadTelemetry) @extHostNamedCustomer(MainContext.MainThreadTelemetry)
export class MainThreadTelemetry extends Disposable implements MainThreadTelemetryShape { export class MainThreadTelemetry extends Disposable implements MainThreadTelemetryShape {
...@@ -30,7 +30,7 @@ export class MainThreadTelemetry extends Disposable implements MainThreadTelemet ...@@ -30,7 +30,7 @@ export class MainThreadTelemetry extends Disposable implements MainThreadTelemet
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTelemetry); this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTelemetry);
if (getTelemetryLevel(this._productService, this._environmenService) >= TelemetryLevel.LOG) { if (supportsTelemetry(this._productService, this._environmenService)) {
this._register(this._configurationService.onDidChangeConfiguration(e => { this._register(this._configurationService.onDidChangeConfiguration(e => {
if (e.affectedKeys.includes(TELEMETRY_SETTING_ID)) { if (e.affectedKeys.includes(TELEMETRY_SETTING_ID)) {
this._proxy.$onDidChangeTelemetryEnabled(this.telemetryEnabled); this._proxy.$onDidChangeTelemetryEnabled(this.telemetryEnabled);
...@@ -42,11 +42,11 @@ export class MainThreadTelemetry extends Disposable implements MainThreadTelemet ...@@ -42,11 +42,11 @@ export class MainThreadTelemetry extends Disposable implements MainThreadTelemet
} }
private get telemetryEnabled(): boolean { private get telemetryEnabled(): boolean {
if (getTelemetryLevel(this._productService, this._environmenService) < TelemetryLevel.USER) { if (!supportsTelemetry(this._productService, this._environmenService)) {
return false; return false;
} }
return getTelemetryConfiguration(this._configurationService) === TelemetryConfiguration.ON; return getTelemetryLevel(this._configurationService) === TelemetryLevel.USAGE;
} }
$publicLog(eventName: string, data: any = Object.create(null)): void { $publicLog(eventName: string, data: any = Object.create(null)): void {
......
...@@ -21,7 +21,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; ...@@ -21,7 +21,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { RunOnceScheduler, Queue } from 'vs/base/common/async'; import { RunOnceScheduler, Queue } from 'vs/base/common/async';
import { generateUuid } from 'vs/base/common/uuid'; import { generateUuid } from 'vs/base/common/uuid';
import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IHostService } from 'vs/workbench/services/host/browser/host';
import { ICustomEndpointTelemetryService, ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ICustomEndpointTelemetryService, ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { normalizeDriveLetter } from 'vs/base/common/labels'; import { normalizeDriveLetter } from 'vs/base/common/labels';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ReplModel } from 'vs/workbench/contrib/debug/common/replModel'; import { ReplModel } from 'vs/workbench/contrib/debug/common/replModel';
...@@ -1039,7 +1039,7 @@ export class DebugSession implements IDebugSession { ...@@ -1039,7 +1039,7 @@ export class DebugSession implements IDebugSession {
// only log telemetry events from debug adapter if the debug extension provided the telemetry key // only log telemetry events from debug adapter if the debug extension provided the telemetry key
// and the user opted in telemetry // and the user opted in telemetry
const telemetryEndpoint = this.raw.dbgr.getCustomTelemetryEndpoint(); const telemetryEndpoint = this.raw.dbgr.getCustomTelemetryEndpoint();
if (telemetryEndpoint && this.telemetryService.isOptedIn) { if (telemetryEndpoint && this.telemetryService.telemetryLevel !== TelemetryLevel.NONE) {
// __GDPR__TODO__ We're sending events in the name of the debug extension and we can not ensure that those are declared correctly. // __GDPR__TODO__ We're sending events in the name of the debug extension and we can not ensure that those are declared correctly.
let data = event.body.data; let data = event.body.data;
if (!telemetryEndpoint.sendErrorTelemetry && event.body.data) { if (!telemetryEndpoint.sendErrorTelemetry && event.body.data) {
......
...@@ -22,11 +22,10 @@ import { isWeb } from 'vs/base/common/platform'; ...@@ -22,11 +22,10 @@ import { isWeb } from 'vs/base/common/platform';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { LogsDataCleaner } from 'vs/workbench/contrib/logs/common/logsDataCleaner'; import { LogsDataCleaner } from 'vs/workbench/contrib/logs/common/logsDataCleaner';
import { IOutputService } from 'vs/workbench/contrib/output/common/output'; import { IOutputService } from 'vs/workbench/contrib/output/common/output';
import { getTelemetryLevel } from 'vs/platform/telemetry/common/telemetryUtils'; import { supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
import { IProductService } from 'vs/platform/product/common/productService'; import { IProductService } from 'vs/platform/product/common/productService';
import { timeout } from 'vs/base/common/async'; import { timeout } from 'vs/base/common/async';
import { getErrorMessage } from 'vs/base/common/errors'; import { getErrorMessage } from 'vs/base/common/errors';
import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
const workbenchActionsRegistry = Registry.as<IWorkbenchActionRegistry>(WorkbenchActionExtensions.WorkbenchActions); const workbenchActionsRegistry = Registry.as<IWorkbenchActionRegistry>(WorkbenchActionExtensions.WorkbenchActions);
workbenchActionsRegistry.registerWorkbenchAction(SyncActionDescriptor.from(SetLogLevelAction), 'Developer: Set Log Level...', CATEGORIES.Developer.value); workbenchActionsRegistry.registerWorkbenchAction(SyncActionDescriptor.from(SetLogLevelAction), 'Developer: Set Log Level...', CATEGORIES.Developer.value);
...@@ -54,7 +53,7 @@ class LogOutputChannels extends Disposable implements IWorkbenchContribution { ...@@ -54,7 +53,7 @@ class LogOutputChannels extends Disposable implements IWorkbenchContribution {
this.registerLogChannel(Constants.rendererLogChannelId, nls.localize('rendererLog', "Window"), this.environmentService.logFile); this.registerLogChannel(Constants.rendererLogChannelId, nls.localize('rendererLog', "Window"), this.environmentService.logFile);
const registerTelemetryChannel = () => { const registerTelemetryChannel = () => {
if (getTelemetryLevel(this.productService, this.environmentService) >= TelemetryLevel.LOG && this.logService.getLevel() === LogLevel.Trace) { if (supportsTelemetry(this.productService, this.environmentService) && this.logService.getLevel() === LogLevel.Trace) {
this.registerLogChannel(Constants.telemetryLogChannelId, nls.localize('telemetryLog', "Telemetry"), this.environmentService.telemetryLogResource); this.registerLogChannel(Constants.telemetryLogChannelId, nls.localize('telemetryLog', "Telemetry"), this.environmentService.telemetryLogResource);
return true; return true;
} }
......
...@@ -29,8 +29,8 @@ import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remot ...@@ -29,8 +29,8 @@ import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remot
import { IDownloadService } from 'vs/platform/download/common/download'; import { IDownloadService } from 'vs/platform/download/common/download';
import { OpenLocalFileFolderCommand, OpenLocalFileCommand, OpenLocalFolderCommand, SaveLocalFileCommand, RemoteFileDialogContext } from 'vs/workbench/services/dialogs/browser/simpleFileDialog'; import { OpenLocalFileFolderCommand, OpenLocalFileCommand, OpenLocalFolderCommand, SaveLocalFileCommand, RemoteFileDialogContext } from 'vs/workbench/services/dialogs/browser/simpleFileDialog';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { TelemetryConfiguration, TELEMETRY_SETTING_ID } from 'vs/platform/telemetry/common/telemetry'; import { TelemetryLevel, TELEMETRY_SETTING_ID } from 'vs/platform/telemetry/common/telemetry';
import { getTelemetryConfiguration } from 'vs/platform/telemetry/common/telemetryUtils'; import { getTelemetryLevel } from 'vs/platform/telemetry/common/telemetryUtils';
class RemoteChannelsContribution implements IWorkbenchContribution { class RemoteChannelsContribution implements IWorkbenchContribution {
...@@ -113,7 +113,7 @@ class RemoteTelemetryEnablementUpdater extends Disposable implements IWorkbenchC ...@@ -113,7 +113,7 @@ class RemoteTelemetryEnablementUpdater extends Disposable implements IWorkbenchC
} }
private updateRemoteTelemetryEnablement(): Promise<void> { private updateRemoteTelemetryEnablement(): Promise<void> {
if (getTelemetryConfiguration(this.configurationService) === TelemetryConfiguration.OFF) { if (getTelemetryLevel(this.configurationService) === TelemetryLevel.NONE) {
return this.remoteAgentService.disableTelemetry(); return this.remoteAgentService.disableTelemetry();
} }
......
...@@ -7,7 +7,7 @@ import { sha1Hex } from 'vs/base/browser/hash'; ...@@ -7,7 +7,7 @@ import { sha1Hex } from 'vs/base/browser/hash';
import { onUnexpectedError } from 'vs/base/common/errors'; import { onUnexpectedError } from 'vs/base/common/errors';
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { IFileService, IFileStat } from 'vs/platform/files/common/files'; import { IFileService, IFileStat } from 'vs/platform/files/common/files';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { ITextFileService, } from 'vs/workbench/services/textfile/common/textfiles'; import { ITextFileService, } from 'vs/workbench/services/textfile/common/textfiles';
...@@ -36,7 +36,7 @@ export class WorkspaceTags implements IWorkbenchContribution { ...@@ -36,7 +36,7 @@ export class WorkspaceTags implements IWorkbenchContribution {
@IProductService private readonly productService: IProductService, @IProductService private readonly productService: IProductService,
@INativeHostService private readonly nativeHostService: INativeHostService @INativeHostService private readonly nativeHostService: INativeHostService
) { ) {
if (this.telemetryService.isOptedIn) { if (this.telemetryService.telemetryLevel === TelemetryLevel.USAGE) {
this.report(); this.report();
} }
} }
......
...@@ -22,14 +22,14 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; ...@@ -22,14 +22,14 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IProductService } from 'vs/platform/product/common/productService'; import { IProductService } from 'vs/platform/product/common/productService';
import { asText, IRequestService } from 'vs/platform/request/common/request'; import { asText, IRequestService } from 'vs/platform/request/common/request';
import { ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { DEFAULT_MARKDOWN_STYLES, renderMarkdownDocument } from 'vs/workbench/contrib/markdown/browser/markdownDocumentRenderer'; import { DEFAULT_MARKDOWN_STYLES, renderMarkdownDocument } from 'vs/workbench/contrib/markdown/browser/markdownDocumentRenderer';
import { WebviewInput } from 'vs/workbench/contrib/webviewPanel/browser/webviewEditorInput'; import { WebviewInput } from 'vs/workbench/contrib/webviewPanel/browser/webviewEditorInput';
import { IWebviewWorkbenchService } from 'vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService'; import { IWebviewWorkbenchService } from 'vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { ACTIVE_GROUP, IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ACTIVE_GROUP, IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { getTelemetryLevel } from 'vs/platform/telemetry/common/telemetryUtils'; import { supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
export class ReleaseNotesManager { export class ReleaseNotesManager {
...@@ -195,7 +195,7 @@ export class ReleaseNotesManager { ...@@ -195,7 +195,7 @@ export class ReleaseNotesManager {
} }
private async addGAParameters(uri: URI, origin: string, experiment = '1'): Promise<URI> { private async addGAParameters(uri: URI, origin: string, experiment = '1'): Promise<URI> {
if (getTelemetryLevel(this._productService, this._environmentService) >= TelemetryLevel.USER) { if (supportsTelemetry(this._productService, this._environmentService)) {
if (uri.scheme === 'https' && uri.authority === 'code.visualstudio.com') { if (uri.scheme === 'https' && uri.authority === 'code.visualstudio.com') {
const info = await this._telemetryService.getTelemetryInfo(); const info = await this._telemetryService.getTelemetryInfo();
......
...@@ -17,7 +17,7 @@ import { IThemeService, registerThemingParticipant, ThemeIcon } from 'vs/platfor ...@@ -17,7 +17,7 @@ import { IThemeService, registerThemingParticipant, ThemeIcon } from 'vs/platfor
import { welcomePageBackground, welcomePageProgressBackground, welcomePageProgressForeground, welcomePageTileBackground, welcomePageTileHoverBackground, welcomePageTileShadow } from 'vs/workbench/contrib/welcome/gettingStarted/browser/gettingStartedColors'; import { welcomePageBackground, welcomePageProgressBackground, welcomePageProgressForeground, welcomePageTileBackground, welcomePageTileHoverBackground, welcomePageTileShadow } from 'vs/workbench/contrib/welcome/gettingStarted/browser/gettingStartedColors';
import { activeContrastBorder, buttonBackground, buttonForeground, buttonHoverBackground, contrastBorder, descriptionForeground, focusBorder, foreground, textLinkActiveForeground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry'; import { activeContrastBorder, buttonBackground, buttonForeground, buttonHoverBackground, contrastBorder, descriptionForeground, focusBorder, foreground, textLinkActiveForeground, textLinkForeground } from 'vs/platform/theme/common/colorRegistry';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { firstSessionDateStorageKey, ITelemetryService, TelemetryConfiguration } from 'vs/platform/telemetry/common/telemetry'; import { firstSessionDateStorageKey, ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { gettingStartedCheckedCodicon, gettingStartedUncheckedCodicon } from 'vs/workbench/contrib/welcome/gettingStarted/browser/gettingStartedIcons'; import { gettingStartedCheckedCodicon, gettingStartedUncheckedCodicon } from 'vs/workbench/contrib/welcome/gettingStarted/browser/gettingStartedIcons';
import { IOpenerService, matchesScheme } from 'vs/platform/opener/common/opener'; import { IOpenerService, matchesScheme } from 'vs/platform/opener/common/opener';
...@@ -67,7 +67,7 @@ import { GettingStartedIndexList } from './gettingStartedList'; ...@@ -67,7 +67,7 @@ import { GettingStartedIndexList } from './gettingStartedList';
import product from 'vs/platform/product/common/product'; import product from 'vs/platform/product/common/product';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes'; import { KeyCode } from 'vs/base/common/keyCodes';
import { getTelemetryConfiguration } from 'vs/platform/telemetry/common/telemetryUtils'; import { getTelemetryLevel } from 'vs/platform/telemetry/common/telemetryUtils';
const SLIDE_TRANSITION_TIME_MS = 250; const SLIDE_TRANSITION_TIME_MS = 250;
const configurationKey = 'workbench.startupEditor'; const configurationKey = 'workbench.startupEditor';
...@@ -1392,7 +1392,7 @@ export class GettingStartedPage extends EditorPane { ...@@ -1392,7 +1392,7 @@ export class GettingStartedPage extends EditorPane {
const stepListComponent = this.detailsScrollbar.getDomNode(); const stepListComponent = this.detailsScrollbar.getDomNode();
const categoryFooter = $('.getting-started-footer'); const categoryFooter = $('.getting-started-footer');
if (this.editorInput.showTelemetryNotice && getTelemetryConfiguration(this.configurationService) !== TelemetryConfiguration.OFF && product.enableTelemetry) { if (this.editorInput.showTelemetryNotice && getTelemetryLevel(this.configurationService) !== TelemetryLevel.NONE && product.enableTelemetry) {
const mdRenderer = this._register(this.instantiationService.createInstance(MarkdownRenderer, {})); const mdRenderer = this._register(this.instantiationService.createInstance(MarkdownRenderer, {}));
const privacyStatementCopy = localize('privacy statement', "privacy statement"); const privacyStatementCopy = localize('privacy statement', "privacy statement");
......
...@@ -22,8 +22,8 @@ import { GettingStartedInput, gettingStartedInputTypeId } from 'vs/workbench/con ...@@ -22,8 +22,8 @@ import { GettingStartedInput, gettingStartedInputTypeId } from 'vs/workbench/con
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import product from 'vs/platform/product/common/product'; import product from 'vs/platform/product/common/product';
import { getTelemetryConfiguration } from 'vs/platform/telemetry/common/telemetryUtils'; import { getTelemetryLevel } from 'vs/platform/telemetry/common/telemetryUtils';
import { TelemetryConfiguration } from 'vs/platform/telemetry/common/telemetry'; import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
const configurationKey = 'workbench.startupEditor'; const configurationKey = 'workbench.startupEditor';
const oldConfigurationKey = 'workbench.welcome.enabled'; const oldConfigurationKey = 'workbench.welcome.enabled';
...@@ -52,7 +52,7 @@ export class WelcomePageContribution implements IWorkbenchContribution { ...@@ -52,7 +52,7 @@ export class WelcomePageContribution implements IWorkbenchContribution {
// Always open Welcome page for first-launch, no matter what is open or which startupEditor is set. // Always open Welcome page for first-launch, no matter what is open or which startupEditor is set.
if ( if (
product.enableTelemetry product.enableTelemetry
&& getTelemetryConfiguration(this.configurationService) !== TelemetryConfiguration.OFF && getTelemetryLevel(this.configurationService) !== TelemetryLevel.NONE
&& !this.environmentService.skipWelcome && !this.environmentService.skipWelcome
&& !this.storageService.get(telemetryOptOutStorageKey, StorageScope.GLOBAL) && !this.storageService.get(telemetryOptOutStorageKey, StorageScope.GLOBAL)
) { ) {
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import * as platform from 'vs/base/common/platform'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import * as platform from 'vs/base/common/platform';
import type { IKeyValueStorage, IExperimentationTelemetry, IExperimentationFilterProvider, ExperimentationService as TASClient } from 'tas-client-umd'; import type { IKeyValueStorage, IExperimentationTelemetry, IExperimentationFilterProvider, ExperimentationService as TASClient } from 'tas-client-umd';
import { MementoObject, Memento } from 'vs/workbench/common/memento'; import { MementoObject, Memento } from 'vs/workbench/common/memento';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { ITelemetryData } from 'vs/base/common/actions'; import { ITelemetryData } from 'vs/base/common/actions';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
...@@ -199,7 +199,7 @@ export class ExperimentService implements ITASExperimentService { ...@@ -199,7 +199,7 @@ export class ExperimentService implements ITASExperimentService {
@IProductService private productService: IProductService @IProductService private productService: IProductService
) { ) {
if (productService.tasConfig && this.experimentsEnabled && this.telemetryService.isOptedIn) { if (productService.tasConfig && this.experimentsEnabled && this.telemetryService.telemetryLevel === TelemetryLevel.USAGE) {
this.tasClient = this.setupTASClient(); this.tasClient = this.setupTASClient();
} }
......
...@@ -14,9 +14,9 @@ import { getServiceMachineId } from 'vs/platform/serviceMachineId/common/service ...@@ -14,9 +14,9 @@ import { getServiceMachineId } from 'vs/platform/serviceMachineId/common/service
import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { isWeb } from 'vs/base/common/platform'; import { isWeb } from 'vs/base/common/platform';
import { ILogService } from 'vs/platform/log/common/log'; import { ILogService } from 'vs/platform/log/common/log';
import { getTelemetryConfiguration, getTelemetryLevel } from 'vs/platform/telemetry/common/telemetryUtils'; import { getTelemetryLevel, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { TelemetryConfiguration, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
class ExtensionResourceLoaderService implements IExtensionResourceLoaderService { class ExtensionResourceLoaderService implements IExtensionResourceLoaderService {
...@@ -52,7 +52,7 @@ class ExtensionResourceLoaderService implements IExtensionResourceLoaderService ...@@ -52,7 +52,7 @@ class ExtensionResourceLoaderService implements IExtensionResourceLoaderService
'X-Client-Name': `${this._productService.applicationName}${isWeb ? '-web' : ''}`, 'X-Client-Name': `${this._productService.applicationName}${isWeb ? '-web' : ''}`,
'X-Client-Version': this._productService.version 'X-Client-Version': this._productService.version
}; };
if (getTelemetryLevel(this._productService, this._environmentService) >= TelemetryLevel.USER && getTelemetryConfiguration(this._configurationService) === TelemetryConfiguration.ON) { if (supportsTelemetry(this._productService, this._environmentService) && getTelemetryLevel(this._configurationService) === TelemetryLevel.USAGE) {
requestInit.headers['X-Machine-Id'] = machineId; requestInit.headers['X-Machine-Id'] = machineId;
} }
if (this._productService.commit) { if (this._productService.commit) {
......
...@@ -11,10 +11,10 @@ import { ILoggerService } from 'vs/platform/log/common/log'; ...@@ -11,10 +11,10 @@ import { ILoggerService } from 'vs/platform/log/common/log';
import { IProductService } from 'vs/platform/product/common/productService'; import { IProductService } from 'vs/platform/product/common/productService';
import { IStorageService } from 'vs/platform/storage/common/storage'; import { IStorageService } from 'vs/platform/storage/common/storage';
import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings';
import { ITelemetryData, ITelemetryInfo, ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryData, ITelemetryInfo, ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { TelemetryLogAppender } from 'vs/platform/telemetry/common/telemetryLogAppender'; import { TelemetryLogAppender } from 'vs/platform/telemetry/common/telemetryLogAppender';
import { ITelemetryServiceConfig, TelemetryService as BaseTelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { ITelemetryServiceConfig, TelemetryService as BaseTelemetryService } from 'vs/platform/telemetry/common/telemetryService';
import { combinedAppender, ITelemetryAppender, NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { ITelemetryAppender, NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { resolveWorkbenchCommonProperties } from 'vs/workbench/services/telemetry/browser/workbenchCommonProperties'; import { resolveWorkbenchCommonProperties } from 'vs/workbench/services/telemetry/browser/workbenchCommonProperties';
...@@ -117,7 +117,7 @@ export class TelemetryService extends Disposable implements ITelemetryService { ...@@ -117,7 +117,7 @@ export class TelemetryService extends Disposable implements ITelemetryService {
// If remote server is present send telemetry through that, else use the client side appender // 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 telemetryProvider: ITelemetryAppender = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : new WebAppInsightsAppender('monacoworkbench', productService.aiConfig?.asimovKey);
const config: ITelemetryServiceConfig = { const config: ITelemetryServiceConfig = {
appender: combinedAppender(new WebTelemetryAppender(telemetryProvider), new TelemetryLogAppender(loggerService, environmentService)), appenders: [new WebTelemetryAppender(telemetryProvider), new TelemetryLogAppender(loggerService, environmentService)],
commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.remoteAuthority, productService.embedderIdentifier, environmentService.options && environmentService.options.resolveCommonTelemetryProperties), commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.remoteAuthority, productService.embedderIdentifier, environmentService.options && environmentService.options.resolveCommonTelemetryProperties),
sendErrorTelemetry: false, sendErrorTelemetry: false,
}; };
...@@ -128,16 +128,12 @@ export class TelemetryService extends Disposable implements ITelemetryService { ...@@ -128,16 +128,12 @@ export class TelemetryService extends Disposable implements ITelemetryService {
} }
} }
setEnabled(value: boolean): void {
return this.impl.setEnabled(value);
}
setExperimentProperty(name: string, value: string): void { setExperimentProperty(name: string, value: string): void {
return this.impl.setExperimentProperty(name, value); return this.impl.setExperimentProperty(name, value);
} }
get isOptedIn(): boolean { get telemetryLevel(): TelemetryLevel {
return this.impl.isOptedIn; return this.impl.telemetryLevel;
} }
publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): Promise<void> { publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): Promise<void> {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { ITelemetryService, ITelemetryInfo, ITelemetryData, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService, ITelemetryInfo, ITelemetryData, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { getTelemetryLevel, NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { supportsTelemetry, NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { Disposable } from 'vs/base/common/lifecycle'; import { Disposable } from 'vs/base/common/lifecycle';
import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService'; import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService';
...@@ -35,10 +35,10 @@ export class TelemetryService extends Disposable implements ITelemetryService { ...@@ -35,10 +35,10 @@ export class TelemetryService extends Disposable implements ITelemetryService {
) { ) {
super(); super();
if (getTelemetryLevel(productService, environmentService) >= TelemetryLevel.LOG) { if (supportsTelemetry(productService, environmentService)) {
const channel = sharedProcessService.getChannel('telemetryAppender'); const channel = sharedProcessService.getChannel('telemetryAppender');
const config: ITelemetryServiceConfig = { const config: ITelemetryServiceConfig = {
appender: new TelemetryAppenderClient(channel), appenders: [new TelemetryAppenderClient(channel)],
commonProperties: resolveWorkbenchCommonProperties(storageService, fileService, environmentService.os.release, environmentService.os.hostname, productService.commit, productService.version, environmentService.machineId, productService.msftInternalDomains, environmentService.installSourcePath, environmentService.remoteAuthority), commonProperties: resolveWorkbenchCommonProperties(storageService, fileService, environmentService.os.release, environmentService.os.hostname, productService.commit, productService.version, environmentService.machineId, productService.msftInternalDomains, environmentService.installSourcePath, environmentService.remoteAuthority),
piiPaths: [environmentService.appRoot, environmentService.extensionsPath], piiPaths: [environmentService.appRoot, environmentService.extensionsPath],
sendErrorTelemetry: true sendErrorTelemetry: true
...@@ -52,16 +52,12 @@ export class TelemetryService extends Disposable implements ITelemetryService { ...@@ -52,16 +52,12 @@ export class TelemetryService extends Disposable implements ITelemetryService {
this.sendErrorTelemetry = this.impl.sendErrorTelemetry; this.sendErrorTelemetry = this.impl.sendErrorTelemetry;
} }
setEnabled(value: boolean): void {
return this.impl.setEnabled(value);
}
setExperimentProperty(name: string, value: string): void { setExperimentProperty(name: string, value: string): void {
return this.impl.setExperimentProperty(name, value); return this.impl.setExperimentProperty(name, value);
} }
get isOptedIn(): boolean { get telemetryLevel(): TelemetryLevel {
return this.impl.isOptedIn; return this.impl.telemetryLevel;
} }
publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): Promise<void> { publicLog(eventName: string, data?: ITelemetryData, anonymizeFilePaths?: boolean): Promise<void> {
......
...@@ -24,7 +24,7 @@ import { ILogService, NullLogService } from 'vs/platform/log/common/log'; ...@@ -24,7 +24,7 @@ import { ILogService, NullLogService } from 'vs/platform/log/common/log';
import { INotificationService } from 'vs/platform/notification/common/notification'; import { INotificationService } from 'vs/platform/notification/common/notification';
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings'; import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings';
import { ITelemetryInfo, ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryInfo, ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo'; import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService'; import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService';
...@@ -162,7 +162,7 @@ suite.skip('TextSearch performance (integration)', () => { ...@@ -162,7 +162,7 @@ suite.skip('TextSearch performance (integration)', () => {
class TestTelemetryService implements ITelemetryService { class TestTelemetryService implements ITelemetryService {
public _serviceBrand: undefined; public _serviceBrand: undefined;
public isOptedIn = true; public telemetryLevel = TelemetryLevel.USAGE;
public sendErrorTelemetry = true; public sendErrorTelemetry = true;
public events: any[] = []; public events: any[] = [];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册