diff --git a/src/controllers/executionPlanWebviewController.ts b/src/controllers/executionPlanWebviewController.ts index 10de7f76f5..7f5c36a125 100644 --- a/src/controllers/executionPlanWebviewController.ts +++ b/src/controllers/executionPlanWebviewController.ts @@ -76,6 +76,7 @@ export class ExecutionPlanWebviewController extends ReactWebviewPanelController< state, this.executionPlanService, [this.executionPlanContents], + "SqlplanFile", ); return { ...state, diff --git a/src/controllers/mainController.ts b/src/controllers/mainController.ts index 7673d2f13a..cc247e7c7c 100644 --- a/src/controllers/mainController.ts +++ b/src/controllers/mainController.ts @@ -604,6 +604,13 @@ export default class MainController implements vscode.Disposable { await this.sanitizeConnectionProfiles(); await this.loadTokenCache(); Utils.logDebug("activated."); + + // capture basic metadata + sendActionEvent(TelemetryViews.General, TelemetryActions.Activated, { + isExperimental: this.isExperimentalEnabled.toString(), + isRichExperiences: this.isRichExperiencesEnabled.toString(), + }); + this._initialized = true; return true; } diff --git a/src/controllers/sharedExecutionPlanUtils.ts b/src/controllers/sharedExecutionPlanUtils.ts index f78bc21a9c..38123dac90 100644 --- a/src/controllers/sharedExecutionPlanUtils.ts +++ b/src/controllers/sharedExecutionPlanUtils.ts @@ -33,7 +33,7 @@ export async function saveExecutionPlan( const saveUri = await vscode.window.showSaveDialog({ defaultUri: await getUniqueFilePath(folder, `plan`, sqlPlanLanguageId), filters: { - [executionPlanFileFilter]: [`.${sqlPlanLanguageId}`], + [executionPlanFileFilter]: [`${sqlPlanLanguageId}`], }, }); @@ -86,10 +86,15 @@ export async function updateTotalCost( }; } +/** + * Creates the execution plan graph state from XML, and loads them into `state` + * @param source the UI making the call, for telemetry purposes. + */ export async function createExecutionPlanGraphs( state: QueryResultWebviewState | ExecutionPlanWebviewState, executionPlanService: ExecutionPlanService, xmlPlans: string[], + source: "SqlplanFile" | "QueryResults", ) { let newState = { ...state.executionPlanState, @@ -105,23 +110,25 @@ export async function createExecutionPlanGraphs( (await executionPlanService.getExecutionPlan(planFile)).graphs, ); newState.loadState = ApiStatus.Loaded; - - sendActionEvent( - TelemetryViews.ExecutionPlan, - TelemetryActions.OpenExecutionPlan, - {}, - { - numberOfPlans: - state.executionPlanState.executionPlanGraphs.length, - loadTimeInMs: performance.now() - startTime, - }, - ); } catch (e) { // malformed xml newState.loadState = ApiStatus.Error; newState.errorMessage = getErrorMessage(e); } } + + sendActionEvent( + TelemetryViews.ExecutionPlan, + TelemetryActions.OpenExecutionPlan, + { + source: source, + }, + { + numberOfPlans: state.executionPlanState.executionPlanGraphs.length, + loadTimeInMs: performance.now() - startTime, + }, + ); + state.executionPlanState = newState; state.executionPlanState.totalCost = calculateTotalCost(state); diff --git a/src/queryResult/utils.ts b/src/queryResult/utils.ts index 3add5d0c75..7ab497dda6 100644 --- a/src/queryResult/utils.ts +++ b/src/queryResult/utils.ts @@ -298,6 +298,7 @@ export function registerCommonRequestHandlers( Object.values( currentResultState.executionPlanState.xmlPlans, ), + "QueryResults", )) as qr.QueryResultWebviewState; state.executionPlanState.loadState = ApiStatus.Loaded; state.tabStates.resultPaneTab = diff --git a/src/sharedInterfaces/telemetry.ts b/src/sharedInterfaces/telemetry.ts index 075143e26c..717fcba9a3 100644 --- a/src/sharedInterfaces/telemetry.ts +++ b/src/sharedInterfaces/telemetry.ts @@ -21,6 +21,7 @@ export enum TelemetryViews { } export enum TelemetryActions { + Activated = "Activated", GenerateScript = "GenerateScript", Refresh = "Refresh", CreateProject = "CreateProject", diff --git a/test/unit/executionPlanWebviewController.test.ts b/test/unit/executionPlanWebviewController.test.ts index 54f2787cb4..2a8747edfa 100644 --- a/test/unit/executionPlanWebviewController.test.ts +++ b/test/unit/executionPlanWebviewController.test.ts @@ -114,6 +114,7 @@ suite("ExecutionPlanWebviewController", () => { mockInitialState, controller.executionPlanService, [controller.executionPlanContents], + "SqlplanFile", ], "createExecutionPlanGraphs should be called with correct arguments", ); @@ -402,6 +403,7 @@ suite("Execution Plan Utilities", () => { mockInitialState, mockExecutionPlanService, [executionPlanContents], + "Tests" as never, ); const planFile: ep.ExecutionPlanGraphInfo = { @@ -428,6 +430,7 @@ suite("Execution Plan Utilities", () => { mockInitialState, mockExecutionPlanService, [executionPlanContents], + "Tests" as never, ); const planFile: ep.ExecutionPlanGraphInfo = {