mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
cleanup dacpac extension telemetry (#18778)
* cleanup dacpac extension telemetry * Add helper function and missing action
This commit is contained in:
@@ -14,10 +14,14 @@ let packageInfo = Utils.getPackageInfo(packageJson);
|
|||||||
export const TelemetryReporter = new AdsTelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
|
export const TelemetryReporter = new AdsTelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
|
||||||
|
|
||||||
export enum TelemetryViews {
|
export enum TelemetryViews {
|
||||||
DataTierApplicationWizard = 'DataTierApplicationWizard',
|
DataTierApplicationWizard = 'DataTierApplicationWizard'
|
||||||
DeployDacpac = 'DeployDacpac',
|
}
|
||||||
DeployPlanPage = 'DeployPlanPage',
|
|
||||||
ExportBacpac = 'ExportBacpac',
|
export enum TelemetryAction {
|
||||||
ExtractDacpac = 'ExtractDacpac',
|
DeployDacpac = 'DeployDacpacOperation',
|
||||||
ImportBacpac = 'ImportBacpac'
|
GenerateScript = 'GenerateDeployScriptOperation',
|
||||||
|
GenerateDeployPlan = 'GenerateDeployPlan',
|
||||||
|
ExtractDacpac = 'ExtractDacpacOperation',
|
||||||
|
ExportBacpac = 'ExportBacpacOperation',
|
||||||
|
ImportBacpac = 'ImportBacpacOperation'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,10 +17,9 @@ import { ExtractConfigPage } from './pages/extractConfigPage';
|
|||||||
import { ImportConfigPage } from './pages/importConfigPage';
|
import { ImportConfigPage } from './pages/importConfigPage';
|
||||||
import { DacFxDataModel } from './api/models';
|
import { DacFxDataModel } from './api/models';
|
||||||
import { BasePage } from './api/basePage';
|
import { BasePage } from './api/basePage';
|
||||||
import { TelemetryReporter, TelemetryViews } from '../telemetry';
|
import { TelemetryAction, TelemetryReporter, TelemetryViews } from '../telemetry';
|
||||||
import { TelemetryEventMeasures, TelemetryEventProperties } from '@microsoft/ads-extension-telemetry';
|
import { TelemetryEventMeasures, TelemetryEventProperties } from '@microsoft/ads-extension-telemetry';
|
||||||
|
|
||||||
const msSqlProvider = 'MSSQL';
|
|
||||||
class Page {
|
class Page {
|
||||||
wizardPage: azdata.window.WizardPage;
|
wizardPage: azdata.window.WizardPage;
|
||||||
dacFxPage: BasePage;
|
dacFxPage: BasePage;
|
||||||
@@ -313,155 +312,123 @@ export class DataTierApplicationWizard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async deploy(): Promise<mssql.DacFxResult> {
|
public async deploy(): Promise<mssql.DacFxResult> {
|
||||||
const deployStartTime = new Date().getTime();
|
|
||||||
let service: mssql.IDacFxService;
|
|
||||||
let ownerUri: string;
|
|
||||||
let result: mssql.DacFxResult;
|
|
||||||
let additionalProps: TelemetryEventProperties = {};
|
let additionalProps: TelemetryEventProperties = {};
|
||||||
let additionalMeasurements: TelemetryEventMeasures = {};
|
let additionalMeasurements: TelemetryEventMeasures = {};
|
||||||
try {
|
|
||||||
service = await this.getService(msSqlProvider);
|
|
||||||
ownerUri = await azdata.connection.getUriForConnection(this.model.server.connectionId);
|
|
||||||
result = await service.deployDacpac(this.model.filePath, this.model.database, this.model.upgradeExisting, ownerUri, azdata.TaskExecutionMode.execute);
|
|
||||||
} catch (e) {
|
|
||||||
additionalProps.exceptionOccurred = 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
// If result is null which means exception occured, will be adding additional props to the Telemetry
|
const service = await this.getService();
|
||||||
if (!result) {
|
const ownerUri = await azdata.connection.getUriForConnection(this.model.server.connectionId);
|
||||||
additionalProps = { ...additionalProps, ...this.getDacServiceArgsAsProps(service, this.model.database, this.model.filePath, ownerUri) };
|
|
||||||
}
|
const deployStartTime = new Date().getTime();
|
||||||
additionalProps.deploymentStatus = result?.success.toString();
|
const result = await service.deployDacpac(this.model.filePath, this.model.database, this.model.upgradeExisting, ownerUri, azdata.TaskExecutionMode.execute);
|
||||||
|
|
||||||
|
additionalMeasurements.totalDurationMs = (new Date().getTime() - deployStartTime);
|
||||||
|
additionalMeasurements.deployDacpacFileSizeBytes = await utils.tryGetFileSize(this.model.filePath);
|
||||||
additionalProps.upgradeExistingDatabase = this.model.upgradeExisting.toString();
|
additionalProps.upgradeExistingDatabase = this.model.upgradeExisting.toString();
|
||||||
additionalProps.potentialDataLoss = this.model.potentialDataLoss.toString();
|
additionalProps.potentialDataLoss = this.model.potentialDataLoss.toString();
|
||||||
|
|
||||||
additionalMeasurements.deployDacpacFileSizeBytes = await utils.tryGetFileSize(this.model.filePath);
|
this.sendDacFxOperationTelemetryEvent(result, TelemetryAction.DeployDacpac, additionalProps, additionalMeasurements);
|
||||||
additionalMeasurements.totalDurationMs = (new Date().getTime() - deployStartTime);
|
|
||||||
|
|
||||||
// Deploy Dacpac: 'Deploy button' clicked in deploy summary page, Reporting the event selection to the telemetry
|
|
||||||
this.sendDacServiceTelemetryEvent(TelemetryViews.DeployDacpac, 'DeployDacpacOperation', additionalProps, additionalMeasurements);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async extract(): Promise<mssql.DacFxResult> {
|
private async extract(): Promise<mssql.DacFxResult> {
|
||||||
const extractStartTime = new Date().getTime();
|
|
||||||
let service: mssql.IDacFxService;
|
|
||||||
let ownerUri: string;
|
|
||||||
let result: mssql.DacFxResult;
|
|
||||||
let additionalProps: TelemetryEventProperties = {};
|
|
||||||
let additionalMeasurements: TelemetryEventMeasures = {};
|
let additionalMeasurements: TelemetryEventMeasures = {};
|
||||||
try {
|
|
||||||
service = await this.getService(msSqlProvider);
|
|
||||||
ownerUri = await azdata.connection.getUriForConnection(this.model.server.connectionId);
|
|
||||||
result = await service.extractDacpac(this.model.database, this.model.filePath, this.model.database, this.model.version, ownerUri, azdata.TaskExecutionMode.execute);
|
|
||||||
} catch (e) {
|
|
||||||
additionalProps.exceptionOccurred = 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
// If result is null which means exception occured, will be adding additional props to the Telemetry
|
const service = await this.getService();
|
||||||
if (!result) {
|
const ownerUri = await azdata.connection.getUriForConnection(this.model.server.connectionId);
|
||||||
additionalProps = { ...additionalProps, ...this.getDacServiceArgsAsProps(service, this.model.database, this.model.filePath, ownerUri) };
|
|
||||||
}
|
const extractStartTime = new Date().getTime();
|
||||||
additionalProps.extractStatus = result?.success.toString();
|
const result = await service.extractDacpac(this.model.database, this.model.filePath, this.model.database, this.model.version, ownerUri, azdata.TaskExecutionMode.execute);
|
||||||
additionalMeasurements.extractedDacpacFileSizeBytes = await utils.tryGetFileSize(this.model.filePath);
|
|
||||||
additionalMeasurements.totalDurationMs = (new Date().getTime() - extractStartTime);
|
additionalMeasurements.totalDurationMs = (new Date().getTime() - extractStartTime);
|
||||||
// Extract Dacpac: 'Extract button' clicked in extract summary page, Reporting the event selection to the telemetry
|
additionalMeasurements.extractedDacpacFileSizeBytes = await utils.tryGetFileSize(this.model.filePath);
|
||||||
this.sendDacServiceTelemetryEvent(TelemetryViews.ExtractDacpac, 'ExtractDacpacOperation', additionalProps, additionalMeasurements);
|
|
||||||
|
this.sendDacFxOperationTelemetryEvent(result, TelemetryAction.ExtractDacpac, undefined, additionalMeasurements);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async export(): Promise<mssql.DacFxResult> {
|
private async export(): Promise<mssql.DacFxResult> {
|
||||||
const exportStartTime = new Date().getTime();
|
|
||||||
let service: mssql.IDacFxService;
|
|
||||||
let ownerUri: string;
|
|
||||||
let result: mssql.DacFxResult;
|
|
||||||
let additionalProps: TelemetryEventProperties = {};
|
|
||||||
let additionalMeasurements: TelemetryEventMeasures = {};
|
let additionalMeasurements: TelemetryEventMeasures = {};
|
||||||
try {
|
|
||||||
service = await this.getService(msSqlProvider);
|
|
||||||
ownerUri = await azdata.connection.getUriForConnection(this.model.server.connectionId);
|
|
||||||
result = await service.exportBacpac(this.model.database, this.model.filePath, ownerUri, azdata.TaskExecutionMode.execute);
|
|
||||||
} catch (e) {
|
|
||||||
additionalProps.exceptionOccurred = 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
// If result is null which means exception occured, will be adding additional props to the Telemetry
|
const service = await this.getService();
|
||||||
if (!result) {
|
const ownerUri = await azdata.connection.getUriForConnection(this.model.server.connectionId);
|
||||||
additionalProps = { ...additionalProps, ...this.getDacServiceArgsAsProps(service, this.model.database, this.model.filePath, ownerUri) };
|
|
||||||
}
|
const exportStartTime = new Date().getTime();
|
||||||
additionalProps.exportStatus = result?.success.toString();
|
const result = await service.exportBacpac(this.model.database, this.model.filePath, ownerUri, azdata.TaskExecutionMode.execute);
|
||||||
additionalMeasurements.exportedBacpacFileSizeBytes = await utils.tryGetFileSize(this.model.filePath);
|
|
||||||
additionalMeasurements.totalDurationMs = (new Date().getTime() - exportStartTime);
|
additionalMeasurements.totalDurationMs = (new Date().getTime() - exportStartTime);
|
||||||
// Export Bacpac: 'Export button' clicked in Export summary page, Reporting the event selection to the telemetry
|
additionalMeasurements.exportedBacpacFileSizeBytes = await utils.tryGetFileSize(this.model.filePath);
|
||||||
this.sendDacServiceTelemetryEvent(TelemetryViews.ExportBacpac, 'ExportBacpacOperation', additionalProps, additionalMeasurements);
|
|
||||||
|
this.sendDacFxOperationTelemetryEvent(result, TelemetryAction.ExportBacpac, undefined, additionalMeasurements);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async import(): Promise<mssql.DacFxResult> {
|
private async import(): Promise<mssql.DacFxResult> {
|
||||||
const importStartTime = new Date().getTime();
|
|
||||||
let service: mssql.IDacFxService;
|
|
||||||
let ownerUri: string;
|
|
||||||
let result: mssql.DacFxResult;
|
|
||||||
let additionalProps: TelemetryEventProperties = {};
|
|
||||||
let additionalMeasurements: TelemetryEventMeasures = {};
|
let additionalMeasurements: TelemetryEventMeasures = {};
|
||||||
try {
|
|
||||||
service = await this.getService(msSqlProvider);
|
|
||||||
ownerUri = await azdata.connection.getUriForConnection(this.model.server.connectionId);
|
|
||||||
result = await service.importBacpac(this.model.filePath, this.model.database, ownerUri, azdata.TaskExecutionMode.execute);
|
|
||||||
} catch (e) {
|
|
||||||
additionalProps.exceptionOccurred = 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
// If result is null which means exception occured, will be adding additional props to the Telemetry
|
const service = await this.getService();
|
||||||
if (!result) {
|
const ownerUri = await azdata.connection.getUriForConnection(this.model.server.connectionId);
|
||||||
additionalProps = { ...additionalProps, ...this.getDacServiceArgsAsProps(service, this.model.database, this.model.filePath, ownerUri) };
|
|
||||||
}
|
const importStartTime = new Date().getTime();
|
||||||
additionalProps.importStatus = result?.success.toString();
|
const result = await service.importBacpac(this.model.filePath, this.model.database, ownerUri, azdata.TaskExecutionMode.execute);
|
||||||
additionalMeasurements.importedBacpacFileSizeBytes = await utils.tryGetFileSize(this.model.filePath);
|
|
||||||
additionalMeasurements.totalDurationMs = (new Date().getTime() - importStartTime);
|
additionalMeasurements.totalDurationMs = (new Date().getTime() - importStartTime);
|
||||||
// Import Bacpac: 'Import button' clicked in Import summary page, Reporting the event selection to the telemetry
|
additionalMeasurements.importedBacpacFileSizeBytes = await utils.tryGetFileSize(this.model.filePath);
|
||||||
this.sendDacServiceTelemetryEvent(TelemetryViews.ImportBacpac, 'ImportBacpacOperation', additionalProps, additionalMeasurements);
|
|
||||||
|
this.sendDacFxOperationTelemetryEvent(result, TelemetryAction.ImportBacpac, undefined, additionalMeasurements);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async generateDeployScript(): Promise<mssql.DacFxResult> {
|
public async generateDeployScript(): Promise<mssql.DacFxResult> {
|
||||||
const genScriptStartTime = new Date().getTime();
|
|
||||||
let service: mssql.IDacFxService;
|
|
||||||
let ownerUri: string;
|
|
||||||
let result: mssql.DacFxResult;
|
|
||||||
let additionalProps: TelemetryEventProperties = {};
|
let additionalProps: TelemetryEventProperties = {};
|
||||||
let additionalMeasurements: TelemetryEventMeasures = {};
|
let additionalMeasurements: TelemetryEventMeasures = {};
|
||||||
try {
|
this.wizard.message = {
|
||||||
this.wizard.message = {
|
text: loc.generatingScriptMessage,
|
||||||
text: loc.generatingScriptMessage,
|
level: azdata.window.MessageLevel.Information
|
||||||
level: azdata.window.MessageLevel.Information,
|
};
|
||||||
description: ''
|
|
||||||
};
|
|
||||||
|
|
||||||
service = await this.getService(msSqlProvider);
|
const service = await this.getService();
|
||||||
ownerUri = await azdata.connection.getUriForConnection(this.model.server.connectionId);
|
const ownerUri = await azdata.connection.getUriForConnection(this.model.server.connectionId);
|
||||||
result = await service.generateDeployScript(this.model.filePath, this.model.database, ownerUri, azdata.TaskExecutionMode.script);
|
|
||||||
} catch (e) {
|
|
||||||
additionalProps.exceptionOccurred = 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!result || !result.success) {
|
const genScriptStartTime = new Date().getTime();
|
||||||
vscode.window.showErrorMessage(loc.generateDeployErrorMessage(result?.errorMessage));
|
const result = await service.generateDeployScript(this.model.filePath, this.model.database, ownerUri, azdata.TaskExecutionMode.script);
|
||||||
}
|
|
||||||
|
|
||||||
// If result is null which means exception occured, will be adding additional props to the Telemetry
|
|
||||||
if (!result) {
|
|
||||||
additionalProps = { ...additionalProps, ...this.getDacServiceArgsAsProps(service, this.model.database, this.model.filePath, ownerUri) };
|
|
||||||
}
|
|
||||||
additionalProps.isScriptGenerated = result?.success.toString();
|
|
||||||
additionalProps.potentialDataLoss = this.model.potentialDataLoss.toString();
|
|
||||||
additionalMeasurements.deployDacpacFileSizeBytes = await utils.tryGetFileSize(this.model.filePath);
|
|
||||||
additionalMeasurements.totalDurationMs = (new Date().getTime() - genScriptStartTime);
|
additionalMeasurements.totalDurationMs = (new Date().getTime() - genScriptStartTime);
|
||||||
// Deploy Dacpac 'generate script' button clicked in DeployPlanPage, Reporting the event selection to the telemetry with fail/sucess status
|
additionalMeasurements.deployDacpacFileSizeBytes = await utils.tryGetFileSize(this.model.filePath);
|
||||||
this.sendDacServiceTelemetryEvent(TelemetryViews.DeployDacpac, 'GenerateDeployScriptOperation', additionalProps, additionalMeasurements);
|
additionalProps.potentialDataLoss = this.model.potentialDataLoss.toString();
|
||||||
|
|
||||||
|
this.sendDacFxOperationTelemetryEvent(result, TelemetryAction.GenerateScript, undefined, additionalMeasurements);
|
||||||
|
|
||||||
|
if (!result?.success && result.errorMessage) {
|
||||||
|
vscode.window.showErrorMessage(loc.generateDeployErrorMessage(result.errorMessage));
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async generateDeployPlan(): Promise<string> {
|
||||||
|
let additionalMeasurements: TelemetryEventMeasures = {};
|
||||||
|
|
||||||
|
const service = await this.getService();
|
||||||
|
const ownerUri = await azdata.connection.getUriForConnection(this.model.server.connectionId);
|
||||||
|
|
||||||
|
const deployPlanStartTime = new Date().getTime();
|
||||||
|
const result = await service.generateDeployPlan(this.model.filePath, this.model.database, ownerUri, azdata.TaskExecutionMode.execute);
|
||||||
|
|
||||||
|
additionalMeasurements.totalDurationMs = (new Date().getTime() - deployPlanStartTime);
|
||||||
|
|
||||||
|
this.sendDacFxOperationTelemetryEvent(result, TelemetryAction.GenerateDeployPlan, undefined, additionalMeasurements);
|
||||||
|
|
||||||
|
if (!result?.success && result.errorMessage) {
|
||||||
|
vscode.window.showErrorMessage(loc.deployPlanErrorMessage(result.errorMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.report;
|
||||||
|
}
|
||||||
|
|
||||||
public getPage(idx: number): Page {
|
public getPage(idx: number): Page {
|
||||||
let page: Page;
|
let page: Page;
|
||||||
|
|
||||||
@@ -501,56 +468,24 @@ export class DataTierApplicationWizard {
|
|||||||
|| (this.selectedOperation === Operation.deploy) && idx === DeployOperationPath.summary;
|
|| (this.selectedOperation === Operation.deploy) && idx === DeployOperationPath.summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async generateDeployPlan(): Promise<string> {
|
private async getService(): Promise<mssql.IDacFxService> {
|
||||||
const deployPlanStartTime = new Date().getTime();
|
|
||||||
let service: mssql.IDacFxService;
|
|
||||||
let ownerUri: string;
|
|
||||||
let result: mssql.GenerateDeployPlanResult;
|
|
||||||
let additionalProps: TelemetryEventProperties = {};
|
|
||||||
let additionalMeasurements: TelemetryEventMeasures = {};
|
|
||||||
try {
|
|
||||||
service = await this.getService(msSqlProvider);
|
|
||||||
ownerUri = await azdata.connection.getUriForConnection(this.model.server.connectionId);
|
|
||||||
result = await service.generateDeployPlan(this.model.filePath, this.model.database, ownerUri, azdata.TaskExecutionMode.execute);
|
|
||||||
} catch (e) {
|
|
||||||
additionalProps.exceptionOccurred = 'true';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!result || !result.success) {
|
|
||||||
vscode.window.showErrorMessage(loc.deployPlanErrorMessage(result?.errorMessage));
|
|
||||||
}
|
|
||||||
|
|
||||||
// If result is null which means exception occured, will be adding additional props to the Telemetry
|
|
||||||
if (!result) {
|
|
||||||
additionalProps = { ...additionalProps, ...this.getDacServiceArgsAsProps(service, this.model.database, this.model.filePath, ownerUri) };
|
|
||||||
}
|
|
||||||
additionalProps.isPlanGenerated = result?.success.toString();
|
|
||||||
additionalMeasurements.totalDurationMs = (new Date().getTime() - deployPlanStartTime);
|
|
||||||
// send Generate deploy plan error/succes telemetry event
|
|
||||||
this.sendDacServiceTelemetryEvent(TelemetryViews.DeployPlanPage, 'GenerateDeployPlanOperation', additionalProps, additionalMeasurements);
|
|
||||||
return result.report;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async getService(providerName: string): Promise<mssql.IDacFxService> {
|
|
||||||
if (!this.dacfxService) {
|
if (!this.dacfxService) {
|
||||||
this.dacfxService = (vscode.extensions.getExtension(mssql.extension.name).exports as mssql.IExtension).dacFx;
|
this.dacfxService = (vscode.extensions.getExtension(mssql.extension.name).exports as mssql.IExtension).dacFx;
|
||||||
}
|
}
|
||||||
return this.dacfxService;
|
return this.dacfxService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getDacServiceArgsAsProps(service: mssql.IDacFxService, database: string, filePath: string, ownerUri: string): { [k: string]: string } {
|
private sendDacFxOperationTelemetryEvent(result: azdata.ResultStatus, telemetryAction: string, additionalProps: TelemetryEventProperties, additionalMeasurements: TelemetryEventMeasures): void {
|
||||||
return {
|
if (result?.success) {
|
||||||
isServiceExist: (!!service).toString(),
|
TelemetryReporter.createActionEvent(TelemetryViews.DataTierApplicationWizard, telemetryAction)
|
||||||
isDatabaseExists: (!!database).toString(),
|
.withAdditionalProperties(additionalProps)
|
||||||
isFilePathExist: (!!filePath).toString(),
|
.withAdditionalMeasurements(additionalMeasurements)
|
||||||
isOwnerUriExist: (!!ownerUri).toString()
|
.send();
|
||||||
};
|
} else {
|
||||||
}
|
TelemetryReporter.createErrorEvent(TelemetryViews.DataTierApplicationWizard, telemetryAction)
|
||||||
|
.withAdditionalProperties(additionalProps)
|
||||||
private sendDacServiceTelemetryEvent(telemetryView: string, telemetryAction: string, additionalProps: TelemetryEventProperties, additionalMeasurements: TelemetryEventMeasures): void {
|
.withAdditionalMeasurements(additionalMeasurements)
|
||||||
TelemetryReporter.createActionEvent(telemetryView, telemetryAction)
|
.send();
|
||||||
.withAdditionalProperties(additionalProps)
|
}
|
||||||
.withAdditionalMeasurements(additionalMeasurements)
|
|
||||||
.send();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user