From 22a6f7a8f2c0dcf2dcefe5d04dc4e5c028c17a38 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Thu, 16 Feb 2017 08:15:28 -0800 Subject: [PATCH] Tag editor action telemetry in walk-through (fixes #19888) --- src/vs/editor/common/commonCodeEditor.ts | 4 +++ src/vs/editor/common/editorCommon.ts | 5 ++++ .../editor/common/editorCommonExtensions.ts | 6 ++-- .../editor/contrib/folding/browser/folding.ts | 2 +- .../contrib/gotoError/browser/gotoError.ts | 2 +- .../contrib/suggest/browser/suggestWidget.ts | 4 +-- src/vs/platform/telemetry/common/telemetry.ts | 1 + .../electron-browser/walkThroughPart.ts | 28 ++++++++++++++++++- .../walkThrough/node/walkThroughInput.ts | 6 ++-- 9 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/common/commonCodeEditor.ts b/src/vs/editor/common/commonCodeEditor.ts index 914e55b30c3..0b366dbd89e 100644 --- a/src/vs/editor/common/commonCodeEditor.ts +++ b/src/vs/editor/common/commonCodeEditor.ts @@ -1006,6 +1006,10 @@ export abstract class CommonCodeEditor extends EventEmitter implements editorCom protected abstract _registerDecorationType(key: string, options: editorCommon.IDecorationRenderOptions, parentTypeKey?: string): void; protected abstract _removeDecorationType(key: string): void; protected abstract _resolveDecorationOptions(typeKey: string, writable: boolean): editorCommon.IModelDecorationOptions; + + public getTelemetryData(): { [key: string]: any; } { + return null; + } } class EditorContextKeysManager extends Disposable { diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index 7fe393ab654..c5706ab0c3a 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -4039,6 +4039,11 @@ export interface ICommonCodeEditor extends IEditor { * Get the layout info for the editor. */ getLayoutInfo(): EditorLayoutInfo; + + /** + * @internal + */ + getTelemetryData(): { [key: string]: any; }; } export interface ICommonDiffEditor extends IEditor { diff --git a/src/vs/editor/common/editorCommonExtensions.ts b/src/vs/editor/common/editorCommonExtensions.ts index f31cc29e5dc..6278efb3461 100644 --- a/src/vs/editor/common/editorCommonExtensions.ts +++ b/src/vs/editor/common/editorCommonExtensions.ts @@ -62,12 +62,12 @@ export abstract class EditorAction extends ConfigEditorCommand { } public runEditorCommand(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor, args: any): void | TPromise { - this.reportTelemetry(accessor); + this.reportTelemetry(accessor, editor); return this.run(accessor, editor, args); } - protected reportTelemetry(accessor: ServicesAccessor) { - accessor.get(ITelemetryService).publicLog('editorActionInvoked', { name: this.label, id: this.id }); + protected reportTelemetry(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor) { + accessor.get(ITelemetryService).publicLog('editorActionInvoked', { name: this.label, id: this.id, ...editor.getTelemetryData() }); } public abstract run(accessor: ServicesAccessor, editor: editorCommon.ICommonCodeEditor, args: any): void | TPromise; diff --git a/src/vs/editor/contrib/folding/browser/folding.ts b/src/vs/editor/contrib/folding/browser/folding.ts index c93d00bd5d7..7edee439119 100644 --- a/src/vs/editor/contrib/folding/browser/folding.ts +++ b/src/vs/editor/contrib/folding/browser/folding.ts @@ -505,7 +505,7 @@ abstract class FoldingAction extends EditorAction { if (!foldingController) { return; } - this.reportTelemetry(accessor); + this.reportTelemetry(accessor, editor); this.invoke(foldingController, editor, args); } diff --git a/src/vs/editor/contrib/gotoError/browser/gotoError.ts b/src/vs/editor/contrib/gotoError/browser/gotoError.ts index fe68bf1d150..c759d8b45de 100644 --- a/src/vs/editor/contrib/gotoError/browser/gotoError.ts +++ b/src/vs/editor/contrib/gotoError/browser/gotoError.ts @@ -322,7 +322,7 @@ class MarkerNavigationAction extends EditorAction { } let model = controller.getOrCreateModel(); - telemetryService.publicLog('zoneWidgetShown', { mode: 'go to error' }); + telemetryService.publicLog('zoneWidgetShown', { mode: 'go to error', ...editor.getTelemetryData() }); if (model) { if (this._isNext) { model.next(); diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts index aada91728c4..99f7bc879d7 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts @@ -593,7 +593,7 @@ export class SuggestWidget implements IContentWidget, IDelegate } else { const { stats } = this.completionModel; stats['wasAutomaticallyTriggered'] = !!isAuto; - this.telemetryService.publicLog('suggestWidget', stats); + this.telemetryService.publicLog('suggestWidget', { ...stats, ...this.editor.getTelemetryData() }); this.list.splice(0, this.list.length, this.completionModel.items); this.list.setFocus([this.completionModel.topScoreIdx]); @@ -694,7 +694,7 @@ export class SuggestWidget implements IContentWidget, IDelegate this.setState(State.Details); this.editor.focus(); - this.telemetryService.publicLog('suggestWidget:toggleDetails'); + this.telemetryService.publicLog('suggestWidget:toggleDetails', this.editor.getTelemetryData()); } private show(): void { diff --git a/src/vs/platform/telemetry/common/telemetry.ts b/src/vs/platform/telemetry/common/telemetry.ts index f1959d63000..f25457dc146 100644 --- a/src/vs/platform/telemetry/common/telemetry.ts +++ b/src/vs/platform/telemetry/common/telemetry.ts @@ -17,6 +17,7 @@ export interface ITelemetryInfo { export interface ITelemetryData { from?: string; + target?: string; [key: string]: any; } diff --git a/src/vs/workbench/parts/welcome/walkThrough/electron-browser/walkThroughPart.ts b/src/vs/workbench/parts/welcome/walkThrough/electron-browser/walkThroughPart.ts index 4ff47689a62..26eed57db85 100644 --- a/src/vs/workbench/parts/welcome/walkThrough/electron-browser/walkThroughPart.ts +++ b/src/vs/workbench/parts/welcome/walkThrough/electron-browser/walkThroughPart.ts @@ -36,6 +36,8 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { once } from 'vs/base/common/event'; import SCMPreview from 'vs/workbench/parts/scm/browser/scmPreview'; import { isObject } from 'vs/base/common/types'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { ICodeEditorService } from 'vs/editor/common/services/codeEditorService'; export const WALK_THROUGH_FOCUS = new RawContextKey('interactivePlaygroundFocus', false); @@ -57,6 +59,25 @@ interface IWalkThroughEditorViewStates { 2?: IWalkThroughEditorViewState; } +class WalkThroughCodeEditor extends CodeEditor { + + constructor( + domElement: HTMLElement, + options: IEditorOptions, + private telemetryData: Object, + @IInstantiationService instantiationService: IInstantiationService, + @ICodeEditorService codeEditorService: ICodeEditorService, + @ICommandService commandService: ICommandService, + @IContextKeyService contextKeyService: IContextKeyService + ) { + super(domElement, options, instantiationService, codeEditorService, commandService, contextKeyService); + } + + getTelemetryData() { + return this.telemetryData; + } +} + export class WalkThroughPart extends BaseEditor { static ID: string = 'workbench.editor.walkThroughPart'; @@ -308,7 +329,12 @@ export class WalkThroughPart extends BaseEditor { const id = `snippet-${model.uri.fragment}`; const div = innerContent.querySelector(`#${id.replace(/\./g, '\\.')}`) as HTMLElement; - const editor = this.instantiationService.createInstance(CodeEditor, div, this.getEditorOptions(snippet.textEditorModel.getModeId())); + const options = this.getEditorOptions(snippet.textEditorModel.getModeId()); + const telemetryData = { + target: this.input instanceof WalkThroughInput ? this.input.getTelemetryFrom() : undefined, + snippet: i + }; + const editor = this.instantiationService.createInstance(WalkThroughCodeEditor, div, options, telemetryData); editor.setModel(model); this.contentDisposables.push(editor); diff --git a/src/vs/workbench/parts/welcome/walkThrough/node/walkThroughInput.ts b/src/vs/workbench/parts/welcome/walkThrough/node/walkThroughInput.ts index 7d4b0ac2146..05884194876 100644 --- a/src/vs/workbench/parts/welcome/walkThrough/node/walkThroughInput.ts +++ b/src/vs/workbench/parts/welcome/walkThrough/node/walkThroughInput.ts @@ -88,7 +88,7 @@ export class WalkThroughInput extends EditorInput { getTelemetryDescriptor(): { [key: string]: any; } { const descriptor = super.getTelemetryDescriptor(); - descriptor['resourceTag'] = this.getTelemetryFrom(); + descriptor['target'] = this.getTelemetryFrom(); descriptor['resource'] = telemetryURIDescriptor(this.resource); return descriptor; } @@ -175,7 +175,7 @@ export class WalkThroughInput extends EditorInput { if (!this.resolveTime) { this.resolveTime = Date.now(); this.telemetryService.publicLog('resolvingInput', { - resourceTag: this.getTelemetryFrom(), + target: this.getTelemetryFrom(), }); } } @@ -183,7 +183,7 @@ export class WalkThroughInput extends EditorInput { private disposeTelemetry(reason?: ShutdownReason) { if (this.resolveTime) { this.telemetryService.publicLog('disposingInput', { - resourceTag: this.getTelemetryFrom(), + target: this.getTelemetryFrom(), timeSpent: (Date.now() - this.resolveTime) / 60, reason: reason ? ShutdownReason[reason] : 'DISPOSE', maxTopScroll: this.maxTopScroll,