Add more Notebook telemetry events (#14755)

* initial checkin

* telemetry for search in notebooks

* telemetry for move notebook

* address comments

* feedback changes

* fix tests paasing NullAdsTelemetryService

* move changeKernel telemetry higher up

* remove telemetry service

* Fix new Notebook events (#14982)

* Notebook telemetry fixes

* update2

* Move event location

* remove service

* remove unused

Co-authored-by: chgagnon <chgagnon@microsoft.com>
This commit is contained in:
Maddy
2021-04-05 16:08:39 -07:00
committed by GitHub
parent d8b2df5dbc
commit 43db30d1da
9 changed files with 61 additions and 18 deletions

View File

@@ -28,6 +28,8 @@ import { INotebookService } from 'sql/workbench/services/notebook/browser/notebo
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { CellContext } from 'sql/workbench/contrib/notebook/browser/cellViews/codeActions';
import { URI } from 'vs/base/common/uri';
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
const msgLoading = localize('loading', "Loading kernels...");
@@ -49,7 +51,8 @@ export class AddCellAction extends Action {
constructor(
id: string, label: string, cssClass: string,
@INotebookService private _notebookService: INotebookService
@INotebookService private _notebookService: INotebookService,
@IAdsTelemetryService private _telemetryService: IAdsTelemetryService,
) {
super(id, label, cssClass);
}
@@ -71,6 +74,9 @@ export class AddCellAction extends Action {
const index = editor.cells?.findIndex(cell => cell.active) ?? 0;
editor.addCell(this.cellType, index);
}
this._telemetryService.createActionEvent(TelemetryKeys.TelemetryView.Notebook, TelemetryKeys.NbTelemetryAction.AddCell)
.withAdditionalProperties({ cell_type: this.cellType })
.send();
}
}
@@ -212,12 +218,14 @@ export class RunAllCellsAction extends Action {
constructor(
id: string, label: string, cssClass: string,
@INotificationService private notificationService: INotificationService,
@INotebookService private _notebookService: INotebookService
@INotebookService private _notebookService: INotebookService,
@IAdsTelemetryService private _telemetryService: IAdsTelemetryService,
) {
super(id, label, cssClass);
}
public async run(context: URI): Promise<boolean> {
try {
this._telemetryService.sendActionEvent(TelemetryKeys.TelemetryView.Notebook, TelemetryKeys.NbTelemetryAction.RunAll);
const editor = this._notebookService.findNotebookEditor(context);
await editor.runAllCells();
return true;
@@ -372,7 +380,8 @@ const kernelDropdownElementId = 'kernel-dropdown';
export class KernelsDropdown extends SelectBox {
private model: NotebookModel;
private _showAllKernels: boolean = false;
constructor(container: HTMLElement, contextViewProvider: IContextViewProvider, modelReady: Promise<INotebookModel>, @IConfigurationService private _configurationService: IConfigurationService) {
constructor(container: HTMLElement, contextViewProvider: IContextViewProvider, modelReady: Promise<INotebookModel>, @IConfigurationService private _configurationService: IConfigurationService,
) {
super([msgLoading], msgLoading, contextViewProvider, container, { labelText: kernelLabel, labelOnTop: false, ariaLabel: kernelLabel, id: kernelDropdownElementId } as ISelectBoxOptionsWithLabel);
if (modelReady) {
@@ -641,13 +650,17 @@ export class NewNotebookAction extends Action {
id: string,
label: string,
@ICommandService private commandService: ICommandService,
@IObjectExplorerService private objectExplorerService: IObjectExplorerService
@IObjectExplorerService private objectExplorerService: IObjectExplorerService,
@IAdsTelemetryService private _telemetryService: IAdsTelemetryService,
) {
super(id, label);
this.class = 'notebook-action new-notebook';
}
async run(context?: azdata.ObjectExplorerContext): Promise<void> {
this._telemetryService.createActionEvent(TelemetryKeys.TelemetryView.Notebook, TelemetryKeys.NbTelemetryAction.NewNotebookFromConnections)
.withConnectionInfo(context?.connectionProfile)
.send();
let connProfile: azdata.IConnectionProfile;
if (context && context.nodeInfo) {
let node = await this.objectExplorerService.getTreeNode(context.connectionProfile.id, context.nodeInfo.nodePath);

View File

@@ -39,6 +39,8 @@ import { NotebookSearchView } from 'sql/workbench/contrib/notebook/browser/noteb
import * as path from 'vs/base/common/path';
import { URI } from 'vs/base/common/uri';
import { TreeViewPane } from 'vs/workbench/browser/parts/views/treeView';
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
export const VIEWLET_ID = 'workbench.view.notebooks';
@@ -124,7 +126,8 @@ export class NotebookExplorerViewPaneContainer extends ViewPaneContainer {
@IMenuService private menuService: IMenuService,
@IContextKeyService private contextKeyService: IContextKeyService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IFileService private readonly fileService: IFileService
@IFileService private readonly fileService: IFileService,
@IAdsTelemetryService private _telemetryService: IAdsTelemetryService
) {
super(VIEWLET_ID, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService);
this.inputBoxFocused = Constants.InputBoxFocusedKey.bindTo(this.contextKeyService);
@@ -255,6 +258,9 @@ export class NotebookExplorerViewPaneContainer extends ViewPaneContainer {
onQueryValidationError(err);
return;
}
this._telemetryService.createActionEvent(TelemetryKeys.TelemetryView.Notebook, TelemetryKeys.TelemetryAction.SearchStarted)
.withAdditionalProperties({ triggeredOnType: triggeredOnType })
.send();
this.validateQuery(query).then(() => {
if (this.views.length > 1) {

View File

@@ -43,6 +43,8 @@ import { searchClearIcon, searchCollapseAllIcon, searchExpandAllIcon, searchStop
import { Action, IAction } from 'vs/base/common/actions';
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { Memento } from 'vs/workbench/common/memento';
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
const $ = dom.$;
@@ -82,6 +84,7 @@ export class NotebookSearchView extends SearchView {
@IOpenerService openerService: IOpenerService,
@ITelemetryService telemetryService: ITelemetryService,
@ICommandService readonly commandService: ICommandService,
@IAdsTelemetryService private _telemetryService: IAdsTelemetryService,
) {
super(options, fileService, editorService, progressService, notificationService, dialogService, contextViewService, instantiationService, viewDescriptorService, configurationService, contextService, searchWorkbenchService, contextKeyService, replaceService, textFileService, preferencesService, themeService, searchHistoryService, contextMenuService, menuService, accessibilityService, keybindingService, storageService, openerService, telemetryService);
@@ -239,6 +242,7 @@ export class NotebookSearchView extends SearchView {
}
public startSearch(query: ITextQuery, excludePatternText: string, includePatternText: string, triggeredOnType: boolean, searchWidget: NotebookSearchWidget): Thenable<void> {
let start = new Date().getTime();
let progressComplete: () => void;
this.progressService.withProgress({ location: this.getProgressLocation(), delay: triggeredOnType ? 300 : 0 }, _progress => {
return new Promise<void>(resolve => progressComplete = resolve);
@@ -253,6 +257,12 @@ export class NotebookSearchView extends SearchView {
}, 2000);
const onComplete = async (completed?: ISearchComplete) => {
let end = new Date().getTime();
this._telemetryService.createActionEvent(TelemetryKeys.TelemetryView.Notebook, TelemetryKeys.TelemetryAction.SearchCompleted)
.withAdditionalProperties({ resultsReturned: completed.results.length })
.withAdditionalMeasurements({ timeTakenMs: end - start })
.send();
clearTimeout(slowTimer);
this.state = SearchUIState.Idle;

View File

@@ -24,6 +24,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
import { URI } from 'vs/base/common/uri';
import { NullAdsTelemetryService } from 'sql/platform/telemetry/common/adsTelemetryService';
import { MockQuickInputService } from 'sql/workbench/contrib/notebook/test/common/quickInputServiceMock';
class TestClientSession extends ClientSessionStub {
@@ -125,7 +126,7 @@ suite('Notebook Actions', function (): void {
let actualCellType: CellType;
let action = new AddCellAction('TestId', 'TestLabel', 'TestClass', mockNotebookService.object);
let action = new AddCellAction('TestId', 'TestLabel', 'TestClass', mockNotebookService.object, new NullAdsTelemetryService());
action.cellType = testCellType;
// Normal use case
@@ -192,7 +193,7 @@ suite('Notebook Actions', function (): void {
let mockNotification = TypeMoq.Mock.ofType<INotificationService>(TestNotificationService);
mockNotification.setup(n => n.notify(TypeMoq.It.isAny()));
let action = new RunAllCellsAction('TestId', 'TestLabel', 'TestClass', mockNotification.object, mockNotebookService.object);
let action = new RunAllCellsAction('TestId', 'TestLabel', 'TestClass', mockNotification.object, mockNotebookService.object, new NullAdsTelemetryService());
// Normal use case
mockNotebookEditor.setup(c => c.runAllCells()).returns(() => Promise.resolve(true));
@@ -252,7 +253,7 @@ suite('Notebook Actions', function (): void {
return Promise.resolve(true);
});
let action = new NewNotebookAction('TestId', 'TestLabel', mockCommandService.object, undefined);
let action = new NewNotebookAction('TestId', 'TestLabel', mockCommandService.object, undefined, new NullAdsTelemetryService());
action.run(undefined);
assert.strictEqual(actualCmdId, NewNotebookAction.INTERNAL_NEW_NOTEBOOK_CMD_ID);

View File

@@ -20,6 +20,6 @@ export class ModelFactory implements IModelFactory {
}
public createClientSession(options: IClientSessionOptions): IClientSession {
return new ClientSession(options);
return this.instantiationService.createInstance(ClientSession, options);
}
}

View File

@@ -971,6 +971,12 @@ export class NotebookModel extends Disposable implements INotebookModel {
if (kernel.info) {
this.updateLanguageInfo(kernel.info.language_info);
}
this.adstelemetryService.createActionEvent(TelemetryKeys.TelemetryView.Notebook, TelemetryKeys.NbTelemetryAction.KernelChanged)
.withAdditionalProperties({
name: kernel.name,
alias: kernelAlias || ''
})
.send();
this._kernelChangedEmitter.fire({
newValue: kernel,
oldValue: undefined,