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

View File

@@ -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,