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

More strongly typed telemetry (#77412)

* More strongly typed telemetry

* Updated update service to not duplicate typings
上级 f41d90ab
......@@ -520,14 +520,17 @@ export class DiagnosticsService implements IDiagnosticsService {
if (folderUri.scheme === 'file') {
const folder = folderUri.fsPath;
collectWorkspaceStats(folder, ['node_modules', '.git']).then(stats => {
/* __GDPR__
"workspace.stats" : {
"fileTypes" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"configTypes" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"launchConfigs" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('workspace.stats', {
type WorkspaceStatsClassification = {
fileTypes: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
configTypes: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
launchConfigs: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
type WorkspaceStatsEvent = {
fileTypes: WorkspaceStatItem[];
configTypes: WorkspaceStatItem[];
launchConfigs: WorkspaceStatItem[];
};
this.telemetryService.publicLog2<WorkspaceStatsEvent, WorkspaceStatsClassification>('workspace.stats', {
fileTypes: stats.fileTypes,
configTypes: stats.configFiles,
launchConfigs: stats.launchConfigFiles
......
......@@ -411,13 +411,15 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
let text = options.text || '';
const pageSize = getOrDefault(options, o => o.pageSize, 50);
/* __GDPR__
"galleryService:query" : {
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"text": { "classification": "CustomerContent", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('galleryService:query', { type, text });
type GalleryServiceQueryClassification = {
type: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
text: { classification: 'CustomerContent', purpose: 'FeatureInsight' };
};
type GalleryServiceQueryEvent = {
type: string;
text: string;
};
this.telemetryService.publicLog2<GalleryServiceQueryEvent, GalleryServiceQueryClassification>('galleryService:query', { type, text });
let query = new Query()
.withFlags(Flags.IncludeLatestVersionOnly, Flags.IncludeAssetUri, Flags.IncludeStatistics, Flags.IncludeFiles, Flags.IncludeVersionProperties)
......
......@@ -18,6 +18,10 @@ export function createUpdateURL(platform: string, quality: string): string {
return `${product.updateUrl}/api/update/${platform}/${quality}/${product.commit}`;
}
export type UpdateNotAvailableClassification = {
explicit: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
export abstract class AbstractUpdateService implements IUpdateService {
_serviceBrand: any;
......
......@@ -13,7 +13,7 @@ import { State, IUpdate, StateType, UpdateType } from 'vs/platform/update/common
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ILogService } from 'vs/platform/log/common/log';
import { AbstractUpdateService, createUpdateURL } from 'vs/platform/update/electron-main/abstractUpdateService';
import { AbstractUpdateService, createUpdateURL, UpdateNotAvailableClassification } from 'vs/platform/update/electron-main/abstractUpdateService';
import { IRequestService } from 'vs/platform/request/common/request';
export class DarwinUpdateService extends AbstractUpdateService {
......@@ -81,12 +81,10 @@ export class DarwinUpdateService extends AbstractUpdateService {
return;
}
/* __GDPR__
"update:downloaded" : {
"version" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('update:downloaded', { version: update.version });
type UpdateDownloadedClassification = {
version: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
};
this.telemetryService.publicLog2<{ version: String }, UpdateDownloadedClassification>('update:downloaded', { version: update.version });
this.setState(State.Ready(update));
}
......@@ -95,13 +93,7 @@ export class DarwinUpdateService extends AbstractUpdateService {
if (this.state.type !== StateType.CheckingForUpdates) {
return;
}
/* __GDPR__
"update:notAvailable" : {
"explicit" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('update:notAvailable', { explicit: !!this.state.context });
this.telemetryService.publicLog2<{ explicit: boolean }, UpdateNotAvailableClassification>('update:notAvailable', { explicit: !!this.state.context });
this.setState(State.Idle(UpdateType.Archive));
}
......
......@@ -10,7 +10,7 @@ import { State, IUpdate, AvailableForDownload, UpdateType } from 'vs/platform/up
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ILogService } from 'vs/platform/log/common/log';
import { createUpdateURL, AbstractUpdateService } from 'vs/platform/update/electron-main/abstractUpdateService';
import { createUpdateURL, AbstractUpdateService, UpdateNotAvailableClassification } from 'vs/platform/update/electron-main/abstractUpdateService';
import { IRequestService, asJson } from 'vs/platform/request/common/request';
import { shell } from 'electron';
import { CancellationToken } from 'vs/base/common/cancellation';
......@@ -40,17 +40,11 @@ export class LinuxUpdateService extends AbstractUpdateService {
}
this.setState(State.CheckingForUpdates(context));
this.requestService.request({ url: this.url }, CancellationToken.None)
.then<IUpdate>(asJson)
.then(update => {
if (!update || !update.url || !update.version || !update.productVersion) {
/* __GDPR__
"update:notAvailable" : {
"explicit" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('update:notAvailable', { explicit: !!context });
this.telemetryService.publicLog2<{ explicit: boolean }, UpdateNotAvailableClassification>('update:notAvailable', { explicit: !!context });
this.setState(State.Idle(UpdateType.Archive));
} else {
......@@ -59,14 +53,7 @@ export class LinuxUpdateService extends AbstractUpdateService {
})
.then(undefined, err => {
this.logService.error(err);
/* __GDPR__
"update:notAvailable" : {
"explicit" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('update:notAvailable', { explicit: !!context });
this.telemetryService.publicLog2<{ explicit: boolean }, UpdateNotAvailableClassification>('update:notAvailable', { explicit: !!context });
// only show message when explicitly checking for updates
const message: string | undefined = !!context ? (err.message || err) : undefined;
this.setState(State.Idle(UpdateType.Archive, message));
......
......@@ -13,6 +13,7 @@ import * as path from 'vs/base/common/path';
import { realpath, watch } from 'fs';
import { spawn } from 'child_process';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { UpdateNotAvailableClassification } from 'vs/platform/update/electron-main/abstractUpdateService';
abstract class AbstractUpdateService2 implements IUpdateService {
......@@ -159,29 +160,17 @@ export class SnapUpdateService extends AbstractUpdateService2 {
protected doCheckForUpdates(context: any): void {
this.setState(State.CheckingForUpdates(context));
this.isUpdateAvailable().then(result => {
if (result) {
this.setState(State.Ready({ version: 'something', productVersion: 'something' }));
} else {
/* __GDPR__
"update:notAvailable" : {
"explicit" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('update:notAvailable', { explicit: !!context });
this.telemetryService.publicLog2<{ explicit: boolean }, UpdateNotAvailableClassification>('update:notAvailable', { explicit: !!context });
this.setState(State.Idle(UpdateType.Snap));
}
}, err => {
this.logService.error(err);
/* __GDPR__
"update:notAvailable" : {
"explicit" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('update:notAvailable', { explicit: !!context });
this.telemetryService.publicLog2<{ explicit: boolean }, UpdateNotAvailableClassification>('update:notAvailable', { explicit: !!context });
this.setState(State.Idle(UpdateType.Snap, err.message || err));
});
}
......
......@@ -14,7 +14,7 @@ import { State, IUpdate, StateType, AvailableForDownload, UpdateType } from 'vs/
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ILogService } from 'vs/platform/log/common/log';
import { createUpdateURL, AbstractUpdateService } from 'vs/platform/update/electron-main/abstractUpdateService';
import { createUpdateURL, AbstractUpdateService, UpdateNotAvailableClassification } from 'vs/platform/update/electron-main/abstractUpdateService';
import { IRequestService, asJson } from 'vs/platform/request/common/request';
import { checksum } from 'vs/base/node/crypto';
import { tmpdir } from 'os';
......@@ -168,12 +168,7 @@ export class Win32UpdateService extends AbstractUpdateService {
})
.then(undefined, err => {
this.logService.error(err);
/* __GDPR__
"update:notAvailable" : {
"explicit" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('update:notAvailable', { explicit: !!context });
this.telemetryService.publicLog2<{ explicit: boolean }, UpdateNotAvailableClassification>('update:notAvailable', { explicit: !!context });
// only show message when explicitly checking for updates
const message: string | undefined = !!context ? (err.message || err) : undefined;
......
......@@ -231,23 +231,19 @@ export class OpenNodeModuleFactory implements INodeModuleFactory {
if (!this._extensionId) {
return;
}
/* __GDPR__
"shimming.open" : {
"extension": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this._mainThreadTelemerty.$publicLog('shimming.open', { extension: this._extensionId });
type ShimmingOpenClassification = {
extension: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
};
this._mainThreadTelemerty.$publicLog2<{ extension: string }, ShimmingOpenClassification>('shimming.open', { extension: this._extensionId });
}
private sendNoForwardTelemetry(): void {
if (!this._extensionId) {
return;
}
/* __GDPR__
"shimming.open.call.noForward" : {
"extension": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this._mainThreadTelemerty.$publicLog('shimming.open.call.noForward', { extension: this._extensionId });
type ShimmingOpenCallNoForwardClassification = {
extension: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
};
this._mainThreadTelemerty.$publicLog2<{ extension: string }, ShimmingOpenCallNoForwardClassification>('shimming.open.call.noForward', { extension: this._extensionId });
}
}
......@@ -220,12 +220,10 @@ export class ExperimentService extends Disposable implements IExperimentService
});
return Promise.all(promises).then(() => {
/* __GDPR__
"experiments" : {
"experiments" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('experiments', { experiments: this._experiments });
type ExperimentsClassification = {
experiments: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
};
this.telemetryService.publicLog2<{ experiments: IExperiment[] }, ExperimentsClassification>('experiments', { experiments: this._experiments });
});
});
}
......
......@@ -168,8 +168,6 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
private static readonly IgnoreTask010DonotShowAgain_key = 'workbench.tasks.ignoreTask010Shown';
private static CustomizationTelemetryEventName: string = 'taskService.customize';
public static TemplateTelemetryEventName: string = 'taskService.template';
public _serviceBrand: any;
public static OutputChannelId: string = 'tasks';
public static OutputChannelLabel: string = nls.localize('tasks', "Tasks");
......@@ -2057,14 +2055,16 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
content = content.replace(/(\n)(\t+)/g, (_, s1, s2) => s1 + strings.repeat(' ', s2.length * editorConfig.editor.tabSize));
}
configFileCreated = true;
/* __GDPR__
"taskService.template" : {
"templateId" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"autoDetect" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
type TaskServiceTemplateClassification = {
templateId?: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
autoDetect: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
type TaskServiceEvent = {
templateId?: string;
autoDetect: boolean;
};
return this.textFileService.create(resource, content).then((result): URI => {
this.telemetryService.publicLog(AbstractTaskService.TemplateTelemetryEventName, {
this.telemetryService.publicLog2<TaskServiceEvent, TaskServiceTemplateClassification>('taskService.template', {
templateId: selection.id,
autoDetect: selection.autoDetect
});
......
......@@ -5,7 +5,7 @@
import { Registry } from 'vs/platform/registry/common/platform';
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry, IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { LifecyclePhase, ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { LifecyclePhase, ILifecycleService, StartupKind } from 'vs/platform/lifecycle/common/lifecycle';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IActivityBarService } from 'vs/workbench/services/activityBar/browser/activityBarService';
......@@ -39,27 +39,41 @@ export class TelemetryContribution extends Disposable implements IWorkbenchContr
const { filesToOpenOrCreate, filesToDiff } = environmentService.configuration;
const activeViewlet = viewletService.getActiveViewlet();
/* __GDPR__
"workspaceLoad" : {
"userAgent" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"windowSize.innerHeight": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"windowSize.innerWidth": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"windowSize.outerHeight": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"windowSize.outerWidth": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"emptyWorkbench": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workbench.filesToOpenOrCreate": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"workbench.filesToDiff": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"customKeybindingsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"theme": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"language": { "classification": "SystemMetaData", "purpose": "BusinessInsight" },
"pinnedViewlets": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"restoredViewlet": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"restoredEditors": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"pinnedViewlets": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"startupKind": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
telemetryService.publicLog('workspaceLoad', {
type WindowSizeFragment = {
innerHeight: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
innerWidth: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
outerHeight: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
outerWidth: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
type WorkspaceLoadClassification = {
userAgent: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
emptyWorkbench: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
windowSize: WindowSizeFragment;
'workbench.filesToOpenOrCreate': { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
'workbench.filesToDiff': { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
customKeybindingsCount: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
theme: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
language: { classification: 'SystemMetaData', purpose: 'BusinessInsight' };
pinnedViewlets: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
restoredViewlet?: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
restoredEditors: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
startupKind: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
type WorkspaceLoadEvent = {
userAgent: string;
windowSize: { innerHeight: number, innerWidth: number, outerHeight: number, outerWidth: number };
emptyWorkbench: boolean;
'workbench.filesToOpenOrCreate': number;
'workbench.filesToDiff': number;
customKeybindingsCount: number;
theme: string;
language: string;
pinnedViewlets: string[];
restoredViewlet?: string;
restoredEditors: number;
startupKind: StartupKind;
};
telemetryService.publicLog2<WorkspaceLoadEvent, WorkspaceLoadClassification>('workspaceLoad', {
userAgent: navigator.userAgent,
windowSize: { innerHeight: window.innerHeight, innerWidth: window.innerWidth, outerHeight: window.outerHeight, outerWidth: window.outerWidth },
emptyWorkbench: contextService.getWorkbenchState() === WorkbenchState.EMPTY,
......
......@@ -109,12 +109,14 @@ export class TelemetryOptOut implements IWorkbenchContribution {
}
const logTelemetry = (optout?: boolean) => {
/* __GDPR__
"experiments:optout" : {
"optOut": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('experiments:optout', typeof optout === 'boolean' ? { optout } : {});
type ExperimentsOptOutClassification = {
optout?: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
type ExperimentsOptOutEvent = {
optout?: boolean;
};
this.telemetryService.publicLog2<ExperimentsOptOutEvent, ExperimentsOptOutClassification>('experiments:optout', typeof optout === 'boolean' ? { optout } : {});
};
queryPromise.then(() => {
......
......@@ -356,43 +356,33 @@ export class WalkThroughPart extends BaseEditor {
}
}));
type WalkThroughSnippetInteractionClassification = {
from?: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
type: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
snippet: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
type WalkThroughSnippetInteractionEvent = {
from?: string,
type: string,
snippet: number
};
this.contentDisposables.push(Event.once(editor.onMouseDown)(() => {
/* __GDPR__
"walkThroughSnippetInteraction" : {
"from" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"type": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"snippet": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('walkThroughSnippetInteraction', {
this.telemetryService.publicLog2<WalkThroughSnippetInteractionEvent, WalkThroughSnippetInteractionClassification>('walkThroughSnippetInteraction', {
from: this.input instanceof WalkThroughInput ? this.input.getTelemetryFrom() : undefined,
type: 'mouseDown',
snippet: i
});
}));
this.contentDisposables.push(Event.once(editor.onKeyDown)(() => {
/* __GDPR__
"walkThroughSnippetInteraction" : {
"from" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"type": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"snippet": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('walkThroughSnippetInteraction', {
this.telemetryService.publicLog2<WalkThroughSnippetInteractionEvent, WalkThroughSnippetInteractionClassification>('walkThroughSnippetInteraction', {
from: this.input instanceof WalkThroughInput ? this.input.getTelemetryFrom() : undefined,
type: 'keyDown',
snippet: i
});
}));
this.contentDisposables.push(Event.once(editor.onDidChangeModelContent)(() => {
/* __GDPR__
"walkThroughSnippetInteraction" : {
"from" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"type": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"snippet": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('walkThroughSnippetInteraction', {
this.telemetryService.publicLog2<WalkThroughSnippetInteractionEvent, WalkThroughSnippetInteractionClassification>('walkThroughSnippetInteraction', {
from: this.input instanceof WalkThroughInput ? this.input.getTelemetryFrom() : undefined,
type: 'changeModelContent',
snippet: i
......
......@@ -135,13 +135,11 @@ export class ElectronWindow extends Disposable {
try {
await this.commandService.executeCommand(request.id, ...args);
/* __GDPR__
"commandExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('commandExecuted', { id: request.id, from: request.from });
type CommandExecutedClassifcation = {
id: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
from: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
};
this.telemetryService.publicLog2<{ id: String, from: String }, CommandExecutedClassifcation>('commandExecuted', { id: request.id, from: request.from });
} catch (error) {
this.notificationService.error(error);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册