Initial Strict Typing Support for Telemetry Events (#75785)

* Added command line information to display details about collected telemetry

* Telemetry tooling exploration

* Changing telemetry calls to be strongly typed

* Fixed an event definition

* Removed telemetry command

* More removing of telemetry command

* Fixed compilation errors

* Forgotten property

* Updated typings so diff was aligned
This commit is contained in:
Logan Ramos
2019-07-01 14:37:43 -07:00
committed by GitHub
parent 71bd9c68e6
commit 26d0bbd5d9
25 changed files with 199 additions and 256 deletions
+10
View File
@@ -12,6 +12,16 @@ export interface ITelemetryData {
[key: string]: any;
}
export type WBActionExecutedClassification = {
id: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
from: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
};
export type WBActionExecutedEvent = {
id: string;
from: string;
};
export interface IAction extends IDisposable {
id: string;
label: string;
@@ -676,12 +676,14 @@ export class IssueReporter extends Disposable {
private logSearchError(error: Error) {
this.logService.warn('issueReporter#search ', error.message);
/* __GDPR__
"issueReporterSearchError" : {
"message" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }
}
*/
this.telemetryService.publicLog('issueReporterSearchError', { message: error.message });
type IssueReporterSearchErrorClassification = {
message: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' }
};
type IssueReporterSearchError = {
message: string;
};
this.telemetryService.publicLog2<IssueReporterSearchError, IssueReporterSearchErrorClassification>('issueReporterSearchError', { message: error.message });
}
private setUpTypes(): void {
@@ -873,13 +875,15 @@ export class IssueReporter extends Disposable {
return false;
}
/* __GDPR__
"issueReporterSubmit" : {
"issueType" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"numSimilarIssuesDisplayed" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('issueReporterSubmit', { issueType: this.issueReporterModel.getData().issueType, numSimilarIssuesDisplayed: this.numberOfSearchResultsDisplayed });
type IssueReporterSubmitClassification = {
issueType: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
numSimilarIssuesDisplayed: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
type IssueReporterSubmitEvent = {
issueType: any;
numSimilarIssuesDisplayed: number;
};
this.telemetryService.publicLog2<IssueReporterSubmitEvent, IssueReporterSubmitClassification>('issueReporterSubmit', { issueType: this.issueReporterModel.getData().issueType, numSimilarIssuesDisplayed: this.numberOfSearchResultsDisplayed });
this.hasBeenSubmitted = true;
const baseUrl = this.getIssueUrlWithTitle((<HTMLInputElement>this.getElementById('issue-title')).value);
@@ -1106,11 +1110,7 @@ export class IssueReporter extends Disposable {
// Exclude right click
if (event.which < 3) {
shell.openExternal((<HTMLAnchorElement>event.target).href);
/* __GDPR__
"issueReporterViewSimilarIssue" : { }
*/
this.telemetryService.publicLog('issueReporterViewSimilarIssue');
this.telemetryService.publicLog2('issueReporterViewSimilarIssue');
}
}
@@ -1121,12 +1121,13 @@ export class IssueReporter extends Disposable {
} else {
const error = new Error(`${elementId} not found.`);
this.logService.error(error);
/* __GDPR__
"issueReporterGetElementError" : {
"message" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }
}
*/
this.telemetryService.publicLog('issueReporterGetElementError', { message: error.message });
type IssueReporterGetElementErrorClassification = {
message: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' };
};
type IssueReporterGetElementErrorEvent = {
message: string;
};
this.telemetryService.publicLog2<IssueReporterGetElementErrorEvent, IssueReporterGetElementErrorClassification>('issueReporterGetElementError', { message: error.message });
return undefined;
}
+7 -8
View File
@@ -1709,14 +1709,13 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
private onWindowError(window: ICodeWindow, error: WindowError): void {
this.logService.error(error === WindowError.CRASHED ? '[VS Code]: render process crashed!' : '[VS Code]: detected unresponsive');
/* __GDPR__
"windowerror" : {
"type" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('windowerror', { type: error });
type WindowErrorClassification = {
type: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
};
type WindowErrorEvent = {
type: WindowError;
};
this.telemetryService.publicLog2<WindowErrorEvent, WindowErrorClassification>('windowerror', { type: error });
// Unresponsive
if (error === WindowError.UNRESPONSIVE) {
if (window.isExtensionDevelopmentHost || window.isExtensionTestHost || (window.win && window.win.webContents && window.win.webContents.isDevToolsOpened())) {
@@ -6,7 +6,7 @@
import 'vs/css!./contextMenuHandler';
import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
import { ActionRunner, IRunEvent } from 'vs/base/common/actions';
import { ActionRunner, IRunEvent, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { Menu } from 'vs/base/browser/ui/menu/menu';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
@@ -132,13 +132,7 @@ export class ContextMenuHandler {
private onActionRun(e: IRunEvent): void {
if (this.telemetryService) {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: e.action.id, from: 'contextMenu' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: e.action.id, from: 'contextMenu' });
}
this.contextViewService.hideContextView(false);
@@ -647,21 +647,26 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
}
const message = getErrorMessage(err);
/* __GDPR__
"galleryService:requestError" : {
"url" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"cdn": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"message": { "classification": "CallstackOrException", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('galleryService:requestError', { url, cdn: true, message });
/* __GDPR__
"galleryService:cdnFallback" : {
"url" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"message": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('galleryService:cdnFallback', { url, message });
type GalleryServiceREClassification = {
url: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
cdn: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
message: { classification: 'CallstackOrException', purpose: 'FeatureInsight' };
};
type GalleryServiceREServiceEvent = {
url: string;
cdn: boolean;
message: string;
};
this.telemetryService.publicLog2<GalleryServiceREServiceEvent, GalleryServiceREClassification>('galleryService:requestError', { url, cdn: true, message });
type GalleryServiceCDNFBClassification = {
url: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
message: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
};
type GalleryServiceCDNFBEvent = {
url: string;
message: string;
};
this.telemetryService.publicLog2<GalleryServiceCDNFBEvent, GalleryServiceCDNFBClassification>('galleryService:cdnFallback', { url, message });
const fallbackOptions = assign({}, options, { url: fallbackUrl });
return this.requestService.request(fallbackOptions, token).then(undefined, err => {
@@ -670,14 +675,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
}
const message = getErrorMessage(err);
/* __GDPR__
"galleryService:requestError" : {
"url" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"cdn": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"message": { "classification": "CallstackOrException", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('galleryService:requestError', { url: fallbackUrl, cdn: false, message });
this.telemetryService.publicLog2<GalleryServiceREServiceEvent, GalleryServiceREClassification>('galleryService:requestError', { url: fallbackUrl, cdn: false, message });
return Promise.reject(err);
});
});
@@ -16,6 +16,7 @@ import { IResolveResult, KeybindingResolver } from 'vs/platform/keybinding/commo
import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
interface CurrentChord {
keypress: string;
@@ -195,13 +196,7 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
} else {
this._commandService.executeCommand(resolveResult.commandId, resolveResult.commandArgs).then(undefined, err => this._notificationService.warn(err));
}
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this._telemetryService.publicLog('workbenchActionExecuted', { id: resolveResult.commandId, from: 'keybinding' });
this._telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: resolveResult.commandId, from: 'keybinding' });
}
return shouldPreventDefault;
@@ -21,6 +21,7 @@ import { IMenubarData, IMenubarKeybinding, MenubarMenuItem, isMenubarMenuItemSep
import { URI } from 'vs/base/common/uri';
import { IStateService } from 'vs/platform/state/common/state';
import { ILifecycleService } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
import { WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
const telemetryFrom = 'menu';
@@ -783,13 +784,7 @@ export class Menubar {
}
private reportMenuActionTelemetry(id: string): void {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id, from: telemetryFrom });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id, from: telemetryFrom });
}
private mnemonicLabel(label: string): string {
@@ -9,21 +9,16 @@ import { dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { safeStringify } from 'vs/base/common/objects';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
/* __GDPR__FRAGMENT__
"ErrorEvent" : {
"stack": { "classification": "CustomerContent", "purpose": "PerformanceAndHealth" },
"message" : { "classification": "CustomerContent", "purpose": "PerformanceAndHealth" },
"filename" : { "classification": "CustomerContent", "purpose": "PerformanceAndHealth" },
"callstack": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
"msg" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
"file" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
"line": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"column": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"uncaught_error_name": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
"uncaught_error_msg": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
"count": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth", "isMeasurement": true }
}
*/
type ErrorEventFragment = {
callstack: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' };
msg?: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' };
file?: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' };
line?: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth', isMeasurement: true };
column?: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth', isMeasurement: true };
uncaught_error_name?: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' };
uncaught_error_msg?: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' };
count?: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth', isMeasurement: true };
};
export interface ErrorEvent {
callstack: string;
msg?: string;
@@ -124,12 +119,8 @@ export default abstract class BaseErrorTelemetry {
private _flushBuffer(): void {
for (let error of this._buffer) {
/* __GDPR__
"UnhandledError" : {
"${include}": [ "${ErrorEvent}" ]
}
*/
this._telemetryService.publicLog('UnhandledError', error, true);
type UnhandledErrorClassification = {} & ErrorEventFragment;
this._telemetryService.publicLog2<ErrorEvent, UnhandledErrorClassification>('UnhandledError', error, true);
}
this._buffer.length = 0;
}
@@ -23,4 +23,4 @@ export type StrictPropertyCheckError = 'Type of classified event does not match
export type StrictPropertyCheck<T extends IGDPRProperty, E> = StrictPropertyChecker<E, ClassifiedEvent<T>, StrictPropertyCheckError>;
export type GDPRClassification<T> = { [_ in keyof T]: IPropertyData | IGDPRProperty | undefined };
export type GDPRClassification<T> = { [_ in keyof T]: IPropertyData | IGDPRProperty | undefined };
@@ -57,12 +57,13 @@ export class TelemetryService implements ITelemetryService {
if (this._configurationService) {
this._updateUserOptIn();
this._configurationService.onDidChangeConfiguration(this._updateUserOptIn, this, this._disposables);
/* __GDPR__
"optInStatus" : {
"optIn" : { "classification": "SystemMetaData", "purpose": "BusinessInsight", "isMeasurement": true }
}
*/
this.publicLog('optInStatus', { optIn: this._userOptIn });
type OptInClass = {
optIn: { classification: 'SystemMetaData', purpose: 'BusinessInsight', isMeasurement: true };
};
type OptInEvent = {
optIn: boolean;
};
this.publicLog2<OptInEvent, OptInClass>('optInStatus', { optIn: this._userOptIn });
this._commonProperties.then(values => {
const isHashedId = /^[a-f0-9]+$/i.test(values['common.machineId']);
@@ -195,23 +195,27 @@ const configurationValueWhitelist = [
export function configurationTelemetry(telemetryService: ITelemetryService, configurationService: IConfigurationService): IDisposable {
return configurationService.onDidChangeConfiguration(event => {
if (event.source !== ConfigurationTarget.DEFAULT) {
/* __GDPR__
"updateConfiguration" : {
"configurationSource" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"configurationKeys": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
telemetryService.publicLog('updateConfiguration', {
type UpdateConfigClassification = {
configurationSource: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
configurationKeys: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
};
type UpdateConfigEvent = {
configurationSource: string;
configurationKeys: string[];
};
telemetryService.publicLog2<UpdateConfigEvent, UpdateConfigClassification>('updateConfiguration', {
configurationSource: ConfigurationTargetToString(event.source),
configurationKeys: flattenKeys(event.sourceConfig)
});
/* __GDPR__
"updateConfigurationValues" : {
"configurationSource" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"configurationValues": { "classification": "CustomerContent", "purpose": "FeatureInsight" }
}
*/
telemetryService.publicLog('updateConfigurationValues', {
type UpdateConfigValClassification = {
configurationSource: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
configurationValues: { classification: 'CustomerContent', purpose: 'FeatureInsight' };
};
type UpdateConfigValEvent = {
configurationSource: string;
configurationValues: { [key: string]: any }[];
};
telemetryService.publicLog2<UpdateConfigValEvent, UpdateConfigValClassification>('updateConfigurationValues', {
configurationSource: ConfigurationTargetToString(event.source),
configurationValues: flattenValues(event.sourceConfig, configurationValueWhitelist)
});
@@ -222,12 +226,13 @@ export function configurationTelemetry(telemetryService: ITelemetryService, conf
export function keybindingsTelemetry(telemetryService: ITelemetryService, keybindingService: IKeybindingService): IDisposable {
return keybindingService.onDidUpdateKeybindings(event => {
if (event.source === KeybindingSource.User && event.keybindings) {
/* __GDPR__
"updateKeybindings" : {
"bindings": { "classification": "CustomerContent", "purpose": "FeatureInsight" }
}
*/
telemetryService.publicLog('updateKeybindings', {
type UpdateKBClassification = {
bindings: { classification: 'CustomerContent', purpose: 'FeatureInsight' };
};
type UpdateKBEvents = {
bindings: { key: string, command: string, when: string | undefined, args: boolean | undefined }[];
};
telemetryService.publicLog2<UpdateKBEvents, UpdateKBClassification>('updateKeybindings', {
bindings: event.keybindings.map(binding => ({
key: binding.key,
command: binding.command,
@@ -44,14 +44,13 @@ export interface IExtensionAPI {
// _extensionAPIBrand: any;
}
/* __GDPR__FRAGMENT__
"ExtensionActivationTimes" : {
"startup": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"codeLoadingTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"activateCallTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"activateResolvedTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }
}
*/
export type ExtensionActivationTimesFragment = {
startup?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
codeLoadingTime?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
activateCallTime?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
activateResolvedTime?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
};
export class ExtensionActivationTimes {
public static readonly NONE = new ExtensionActivationTimes(false, -1, -1, -1);
@@ -15,7 +15,7 @@ import { createApiFactory, IExtensionApiFactory } from 'vs/workbench/api/node/ex
import { NodeModuleRequireInterceptor, VSCodeNodeModuleFactory, KeytarNodeModuleFactory, OpenNodeModuleFactory } from 'vs/workbench/api/node/extHostRequireInterceptor';
import { ExtHostExtensionServiceShape, IEnvironment, IInitData, IMainContext, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IResolveAuthorityResult } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration';
import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionModule, HostExtension } from 'vs/workbench/api/common/extHostExtensionActivator';
import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionModule, HostExtension, ExtensionActivationTimesFragment } from 'vs/workbench/api/common/extHostExtensionActivator';
import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService';
import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage';
import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
@@ -51,6 +51,16 @@ export interface IHostUtils {
realpath(path: string): Promise<string>;
}
type TelemetryActivationEventFragment = {
id: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' };
name: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' };
extensionVersion: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' };
publisherDisplayName: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
activationEvents: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
isBuiltin: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
reason: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
};
export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
private static readonly WORKSPACE_CONTAINS_TIMEOUT = 7000;
@@ -313,23 +323,32 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this._mainThreadTelemetryProxy.$publicLog('extensionActivationTimes', {
type ExtensionActivationTimesClassification = {
outcome: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
} & TelemetryActivationEventFragment & ExtensionActivationTimesFragment;
type ExtensionActivationTimesEvent = {
outcome: string
} & ActivationTimesEvent & TelemetryActivationEvent;
type ActivationTimesEvent = {
startup?: boolean;
codeLoadingTime?: number;
activateCallTime?: number;
activateResolvedTime?: number;
};
this._mainThreadTelemetryProxy.$publicLog2<ExtensionActivationTimesEvent, ExtensionActivationTimesClassification>('extensionActivationTimes', {
...event,
...(activationTimes || {}),
outcome,
outcome
});
}
private _doActivateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise<ActivatedExtension> {
const event = getTelemetryActivationEvent(extensionDescription, reason);
/* __GDPR__
"activatePlugin" : {
"${include}": [
"${TelemetryActivationEvent}"
]
}
*/
this._mainThreadTelemetryProxy.$publicLog('activatePlugin', event);
type ActivatePluginClassification = {} & TelemetryActivationEventFragment;
this._mainThreadTelemetryProxy.$publicLog2<TelemetryActivationEvent, ActivatePluginClassification>('activatePlugin', event);
if (!extensionDescription.main) {
// Treat the extension as being empty => NOT AN ERROR CASE
return Promise.resolve(new EmptyExtension(ExtensionActivationTimes.NONE));
@@ -736,22 +755,20 @@ function loadCommonJSModule<T>(logService: ILogService, modulePath: string, acti
return Promise.resolve(r);
}
function getTelemetryActivationEvent(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): any {
type TelemetryActivationEvent = {
id: string;
name: string;
extensionVersion: string;
publisherDisplayName: string;
activationEvents: string | null;
isBuiltin: boolean;
reason: string;
};
function getTelemetryActivationEvent(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): TelemetryActivationEvent {
const reasonStr = reason instanceof ExtensionActivatedByEvent ? reason.activationEvent :
reason instanceof ExtensionActivatedByAPI ? 'api' :
'';
/* __GDPR__FRAGMENT__
"TelemetryActivationEvent" : {
"id": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
"name": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
"extensionVersion": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
"publisherDisplayName": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"activationEvents": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"isBuiltin": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"reason": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
const event = {
id: extensionDescription.identifier.value,
name: extensionDescription.name,
@@ -14,7 +14,7 @@ import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { IActionViewItem, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
import { prepareActions } from 'vs/workbench/browser/actions';
import { IAction } from 'vs/base/common/actions';
import { IAction, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { Part, IPartOptions } from 'vs/workbench/browser/part';
import { Composite, CompositeRegistry } from 'vs/workbench/browser/composite';
import { IComposite } from 'vs/workbench/common/composite';
@@ -259,13 +259,7 @@ export abstract class CompositePart<T extends Composite> extends Part {
// Log in telemetry
if (this.telemetryService) {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: e.action.id, from: this.nameForTelemetry });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: e.action.id, from: this.nameForTelemetry });
}
});
@@ -8,7 +8,7 @@ import { addDisposableListener, Dimension, EventType } from 'vs/base/browser/dom
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { ActionsOrientation, IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { IAction, IRunEvent } from 'vs/base/common/actions';
import { IAction, IRunEvent, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import * as arrays from 'vs/base/common/arrays';
import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
import { dispose, DisposableStore } from 'vs/base/common/lifecycle';
@@ -152,13 +152,7 @@ export abstract class TitleControl extends Themable {
// Log in telemetry
if (this.telemetryService) {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: e.action.id, from: 'editorPart' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: e.action.id, from: 'editorPart' });
}
}));
}
@@ -6,7 +6,7 @@
import 'vs/css!./media/notificationsActions';
import { INotificationViewItem } from 'vs/workbench/common/notifications';
import { localize } from 'vs/nls';
import { Action, IAction, ActionRunner } from 'vs/base/common/actions';
import { Action, IAction, ActionRunner, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { CLEAR_NOTIFICATION, EXPAND_NOTIFICATION, COLLAPSE_NOTIFICATION, CLEAR_ALL_NOTIFICATIONS, HIDE_NOTIFICATIONS_CENTER } from 'vs/workbench/browser/parts/notifications/notificationsCommands';
@@ -161,14 +161,7 @@ export class NotificationActionRunner extends ActionRunner {
}
protected async runAction(action: IAction, context: INotificationViewItem): Promise<any> {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: action.id, from: 'message' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: action.id, from: 'message' });
// Run and make sure to notify on any error again
try {
@@ -15,7 +15,7 @@ import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiat
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { StatusbarAlignment, IStatusbarService, IStatusbarEntry, IStatusbarEntryAccessor } from 'vs/platform/statusbar/common/statusbar';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { Action, IAction } from 'vs/base/common/actions';
import { Action, IAction, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector, ThemeColor } from 'vs/platform/theme/common/themeService';
import { STATUS_BAR_BACKGROUND, STATUS_BAR_FOREGROUND, STATUS_BAR_NO_FOLDER_BACKGROUND, STATUS_BAR_ITEM_HOVER_BACKGROUND, STATUS_BAR_ITEM_ACTIVE_BACKGROUND, STATUS_BAR_PROMINENT_ITEM_FOREGROUND, STATUS_BAR_PROMINENT_ITEM_BACKGROUND, STATUS_BAR_PROMINENT_ITEM_HOVER_BACKGROUND, STATUS_BAR_BORDER, STATUS_BAR_NO_FOLDER_FOREGROUND, STATUS_BAR_NO_FOLDER_BORDER } from 'vs/workbench/common/theme';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
@@ -725,13 +725,7 @@ class StatusbarEntryItem extends Disposable {
activeTextEditorWidget.focus();
}
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id, from: 'status bar' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id, from: 'status bar' });
try {
await this.commandService.executeCommand(id, ...args);
} catch (error) {
@@ -9,7 +9,7 @@ import * as browser from 'vs/base/browser/browser';
import * as dom from 'vs/base/browser/dom';
import * as arrays from 'vs/base/common/arrays';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { IAction, IRunEvent } from 'vs/base/common/actions';
import { IAction, IRunEvent, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { ActionBar, ActionsOrientation, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
@@ -134,13 +134,7 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution {
// log in telemetry
if (this.telemetryService) {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: e.action.id, from: 'debugActionsWidget' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: e.action.id, from: 'debugActionsWidget' });
}
}));
this._register(dom.addDisposableListener(window, dom.EventType.RESIZE, () => this.setCoordinates()));
@@ -17,6 +17,7 @@ import { editorWidgetBackground, editorWidgetForeground, widgetShadow, inputBord
import { IAnchor } from 'vs/base/browser/ui/contextview/contextview';
import { Button } from 'vs/base/browser/ui/button/button';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar';
import { IProductService } from 'vs/platform/product/common/product';
@@ -212,14 +213,7 @@ export class FeedbackDropdown extends Dropdown {
const actionId = 'workbench.action.openIssueReporter';
this.commandService.executeCommand(actionId);
this.hide();
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: actionId, from: 'feedback' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: actionId, from: 'feedback' });
}));
// Contact: Request a Feature
@@ -6,7 +6,7 @@
import * as nls from 'vs/nls';
import { URI } from 'vs/base/common/uri';
import * as perf from 'vs/base/common/performance';
import { Action, IAction } from 'vs/base/common/actions';
import { Action, IAction, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { memoize } from 'vs/base/common/decorators';
import { IFilesConfiguration, ExplorerFolderContext, FilesExplorerFocusedContext, ExplorerFocusedContext, ExplorerRootContext, ExplorerResourceReadonlyContext, IExplorerService, ExplorerResourceCut, ExplorerResourceMoveableToTrash } from 'vs/workbench/contrib/files/common/files';
import { NewFolderAction, NewFileAction, FileCopiedContext, RefreshExplorerView, CollapseExplorerView } from 'vs/workbench/contrib/files/browser/fileActions';
@@ -326,13 +326,7 @@ export class ExplorerView extends ViewletPanel {
// Do not react if clicking on directories
return;
}
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: 'workbench.files.openFile', from: 'explorer' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: 'workbench.files.openFile', from: 'explorer' });
this.editorService.openEditor({ resource: selection[0].resource, options: { preserveFocus: e.editorOptions.preserveFocus, pinned: e.editorOptions.pinned } }, e.sideBySide ? SIDE_GROUP : ACTIVE_GROUP)
.then(undefined, onUnexpectedError);
}
@@ -5,7 +5,7 @@
import * as nls from 'vs/nls';
import { RunOnceScheduler } from 'vs/base/common/async';
import { IAction, ActionRunner } from 'vs/base/common/actions';
import { IAction, ActionRunner, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import * as dom from 'vs/base/browser/dom';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@@ -345,13 +345,7 @@ export class OpenEditorsView extends ViewletPanel {
private openEditor(element: OpenEditor, options: { preserveFocus: boolean; pinned: boolean; sideBySide: boolean; }): void {
if (element) {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: 'workbench.files.openFile', from: 'openEditors' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: 'workbench.files.openFile', from: 'openEditors' });
const preserveActivateGroup = options.sideBySide && options.preserveFocus; // needed for https://github.com/Microsoft/vscode/issues/42399
if (!preserveActivateGroup) {
@@ -7,7 +7,7 @@ import * as nls from 'vs/nls';
import * as arrays from 'vs/base/common/arrays';
import * as types from 'vs/base/common/types';
import { Language } from 'vs/base/common/platform';
import { Action } from 'vs/base/common/actions';
import { Action, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { Mode, IEntryRunContext, IAutoFocus, IModel, IQuickNavigateConfiguration } from 'vs/base/parts/quickopen/common/quickOpen';
import { QuickOpenEntryGroup, IHighlight, QuickOpenModel, QuickOpenEntry } from 'vs/base/parts/quickopen/browser/quickOpenModel';
import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
@@ -297,13 +297,7 @@ abstract class BaseCommandEntry extends QuickOpenEntryGroup {
setTimeout(async () => {
if (action && (!(action instanceof Action) || action.enabled)) {
try {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: action.id, from: 'quick open' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: action.id, from: 'quick open' });
const promise = action.run();
if (promise) {
@@ -17,7 +17,7 @@ import { IWindowService, IURIToOpen } from 'vs/platform/windows/common/windows';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
import { localize } from 'vs/nls';
import { Action } from 'vs/base/common/actions';
import { Action, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { Schemas } from 'vs/base/common/network';
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
@@ -360,13 +360,7 @@ class WelcomePage extends Disposable {
a.setAttribute('aria-label', localize('welcomePage.openFolderWithPath', "Open folder {0} with path {1}", name, parentPath));
a.href = 'javascript:void(0)';
a.addEventListener('click', e => {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', {
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', {
id: 'openRecentFolder',
from: telemetryFrom
});
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IAction, IActionRunner, ActionRunner } from 'vs/base/common/actions';
import { IAction, IActionRunner, ActionRunner, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import * as dom from 'vs/base/browser/dom';
import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView';
@@ -173,13 +173,7 @@ class NativeContextMenuService extends Disposable implements IContextMenuService
}
private async runAction(actionRunner: IActionRunner, actionToRun: IAction, delegate: IContextMenuDelegate, event: IContextMenuEvent): Promise<void> {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: actionToRun.id, from: 'contextMenu' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: actionToRun.id, from: 'contextMenu' });
const context = delegate.getActionsContext ? delegate.getActionsContext(event) : event;
@@ -438,16 +438,21 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
if (themeData) {
let key = themeType + themeData.extensionId;
if (!this.themeExtensionsActivated.get(key)) {
/* __GDPR__
"activatePlugin" : {
"id" : { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
"name": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
"isBuiltin": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"publisherDisplayName": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"themeId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('activatePlugin', {
type ActivatePluginClassification = {
id: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' };
name: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' };
isBuiltin: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
publisherDisplayName: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
themeId: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' };
};
type ActivatePluginEvent = {
id: string;
name: string;
isBuiltin: boolean;
publisherDisplayName: string;
themeId: string;
};
this.telemetryService.publicLog2<ActivatePluginEvent, ActivatePluginClassification>('activatePlugin', {
id: themeData.extensionId,
name: themeData.extensionName,
isBuiltin: themeData.extensionIsBuiltin,