mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-20 09:35:38 -05:00
telemetry for tde user actions (#22474)
* telemetry for user actions * remove unused action * try catch around admin function
This commit is contained in:
@@ -13,6 +13,7 @@ import * as constants from '../constants/strings';
|
||||
import { logError, TelemetryViews } from '../telemetry';
|
||||
import { AdsMigrationStatus } from '../dashboard/tabBase';
|
||||
import { getMigrationMode, getMigrationStatus, getMigrationTargetType, hasRestoreBlockingReason, PipelineStatusCodes } from '../constants/helper';
|
||||
import * as os from 'os';
|
||||
|
||||
export type TargetServerType = azure.SqlVMServer | azureResource.AzureSqlManagedInstance | azure.AzureSqlDatabaseServer;
|
||||
|
||||
@@ -923,3 +924,20 @@ export async function promptUserForFolder(): Promise<string> {
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
export function isWindows(): boolean { return (os.platform() === 'win32') }
|
||||
|
||||
export async function isAdmin(): Promise<boolean> {
|
||||
let isAdmin: boolean = false;
|
||||
try {
|
||||
if (isWindows()) {
|
||||
isAdmin = (await import('native-is-elevated'))();
|
||||
} else {
|
||||
isAdmin = process.getuid() === 0;
|
||||
}
|
||||
} catch (e) {
|
||||
//Ignore error and return false;
|
||||
}
|
||||
|
||||
return isAdmin;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
import * as azdata from 'azdata';
|
||||
import * as vscode from 'vscode';
|
||||
import * as constants from '../../constants/strings';
|
||||
import { logError, TelemetryErrorName, TelemetryViews } from '../../telemetry';
|
||||
import * as utils from '../../api/utils';
|
||||
import { logError, TelemetryAction, TelemetryViews, sendSqlMigrationActionEvent, getTelemetryProps } from '../../telemetry';
|
||||
import { EOL } from 'os';
|
||||
import { MigrationStateModel, OperationResult } from '../../models/stateMachine';
|
||||
import { IconPathHelper } from '../../constants/iconPathHelper';
|
||||
@@ -317,12 +318,28 @@ export class TdeMigrationDialog {
|
||||
};
|
||||
|
||||
this._model.tdeMigrationConfig.setTdeMigrationResult(this._tdeMigrationResult); // Set value on success.
|
||||
|
||||
sendSqlMigrationActionEvent(
|
||||
TelemetryViews.TdeMigrationDialog,
|
||||
TelemetryAction.TdeMigrationSuccess,
|
||||
{
|
||||
...getTelemetryProps(this._model)
|
||||
},
|
||||
{}
|
||||
);
|
||||
}
|
||||
else {
|
||||
this._dialog!.okButton.enabled = false;
|
||||
const errorDetails = operationResult.errors.join(EOL);
|
||||
|
||||
logError(TelemetryViews.MigrationLocalStorage, TelemetryErrorName.StartMigrationFailed, errorDetails);
|
||||
sendSqlMigrationActionEvent(
|
||||
TelemetryViews.TdeMigrationDialog,
|
||||
TelemetryAction.TdeMigrationFailures,
|
||||
{
|
||||
...getTelemetryProps(this._model),
|
||||
'runningAsAdmin': (await utils.isAdmin()).toString()
|
||||
},
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
this._startMigrationLoader.loading = false;
|
||||
@@ -339,6 +356,8 @@ export class TdeMigrationDialog {
|
||||
this._copyButton.enabled = false;
|
||||
this._dialog!.okButton.enabled = false;
|
||||
this._progressReportText.value = '';
|
||||
|
||||
logError(TelemetryViews.TdeMigrationDialog, TelemetryAction.TdeMigrationClientException, error);
|
||||
}
|
||||
|
||||
this._headingText.value = constants.TDE_MIGRATE_RESULTS_HEADING_COMPLETED;
|
||||
@@ -433,13 +452,17 @@ export class TdeMigrationDialog {
|
||||
}
|
||||
}
|
||||
|
||||
private async _updateTableResultRow(dbName: string, succeeded: boolean, message: string): Promise<void> {
|
||||
private async _updateTableResultRow(dbName: string, succeeded: boolean, message: string, statusCode: string): Promise<void> {
|
||||
if (!this._dbRowsMap.has(dbName)) {
|
||||
return; //Table not found
|
||||
}
|
||||
|
||||
this._updateValidationResultRow(dbName, succeeded, message);
|
||||
|
||||
if (!succeeded) {
|
||||
logError(TelemetryViews.TdeMigrationDialog, statusCode, {});
|
||||
}
|
||||
|
||||
// Update the table
|
||||
await this._updateTableData();
|
||||
|
||||
@@ -522,7 +545,4 @@ export class TdeMigrationDialog {
|
||||
return IconPathHelper.notStartedMigration;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -947,7 +947,7 @@ export class MigrationStateModel implements Model, vscode.Disposable {
|
||||
|
||||
public async startTdeMigration(
|
||||
accessToken: string,
|
||||
reportUpdate: (dbName: string, succeeded: boolean, message: string) => Promise<void>): Promise<OperationResult<TdeMigrationDbResult[]>> {
|
||||
reportUpdate: (dbName: string, succeeded: boolean, message: string, statusCode: string) => Promise<void>): Promise<OperationResult<TdeMigrationDbResult[]>> {
|
||||
|
||||
const tdeEnabledDatabases = this.tdeMigrationConfig.getTdeEnabledDatabases();
|
||||
const connectionString = await getSourceConnectionString();
|
||||
|
||||
@@ -500,7 +500,7 @@ export interface ISqlMigrationService {
|
||||
targetManagedInstanceName: string,
|
||||
networkSharePath: string,
|
||||
accessToken: string,
|
||||
reportUpdate: (dbName: string, succeeded: boolean, message: string) => void): Promise<TdeMigrationResult | undefined>;
|
||||
reportUpdate: (dbName: string, succeeded: boolean, message: string, statusCode: string) => void): Promise<TdeMigrationResult | undefined>;
|
||||
}
|
||||
|
||||
export interface TdeMigrationRequest {
|
||||
@@ -547,4 +547,5 @@ export interface TdeMigrateProgressParams {
|
||||
name: string;
|
||||
success: boolean;
|
||||
message: string;
|
||||
statusCode: string;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ export abstract class MigrationExtensionService extends SqlOpsFeature<undefined>
|
||||
}
|
||||
|
||||
export class SqlMigrationService extends MigrationExtensionService implements contracts.ISqlMigrationService {
|
||||
private _reportUpdate: ((dbName: string, succeeded: boolean, error: string) => void) | undefined = undefined;
|
||||
private _reportUpdate: ((dbName: string, succeeded: boolean, error: string, statusCode: string) => void) | undefined = undefined;
|
||||
|
||||
override providerId = ApiType.SqlMigrationProvider;
|
||||
|
||||
@@ -58,7 +58,7 @@ export class SqlMigrationService extends MigrationExtensionService implements co
|
||||
if (this._reportUpdate === undefined) {
|
||||
return;
|
||||
}
|
||||
this._reportUpdate(e.name, e.success, e.message);
|
||||
this._reportUpdate(e.name, e.success, e.message, e.statusCode ?? '');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ export class SqlMigrationService extends MigrationExtensionService implements co
|
||||
targetManagedInstanceName: string,
|
||||
networkSharePath: string,
|
||||
accessToken: string,
|
||||
reportUpdate: (dbName: string, succeeded: boolean, message: string) => void): Promise<contracts.TdeMigrationResult | undefined> {
|
||||
reportUpdate: (dbName: string, succeeded: boolean, message: string, statusCode: string) => void): Promise<contracts.TdeMigrationResult | undefined> {
|
||||
|
||||
this._reportUpdate = reportUpdate;
|
||||
let params: contracts.TdeMigrationParams = {
|
||||
@@ -306,7 +306,7 @@ export class SqlMigrationService extends MigrationExtensionService implements co
|
||||
|
||||
try {
|
||||
// This call needs to be awaited so, the updates are sent during the execution of the task.
|
||||
// If the task is not await, the finally block will execute and no update will be sent.
|
||||
// If the task is not awaited, the finally block will execute and no updates will be sent.
|
||||
const result = await this._client.sendRequest(contracts.TdeMigrateRequest.type, params);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ export enum TelemetryViews {
|
||||
LoginMigrationSelectorPage = 'LoginMigrationSelectorPage',
|
||||
LoginMigrationStatusPage = 'LoginMigrationStatusPage',
|
||||
TdeConfigurationDialog = 'TdeConfigurationDialog',
|
||||
TdeMigrationDialog = 'TdeMigrationDialog',
|
||||
ValidIrDialog = 'validIrDialog',
|
||||
}
|
||||
|
||||
@@ -76,10 +77,11 @@ export enum TelemetryAction {
|
||||
OpenLoginMigrationWizard = 'OpenLoginMigrationWizard',
|
||||
LoginMigrationStarted = 'LoginMigrationStarted',
|
||||
LoginMigrationCompleted = 'LoginMigrationCompleted',
|
||||
}
|
||||
|
||||
export enum TelemetryErrorName {
|
||||
StartMigrationFailed = 'StartMigrationFailed'
|
||||
TdeMigrationSuccess = 'TdeMigrationSuccess',
|
||||
TdeMigrationFailures = 'TdeMigrationFailures',
|
||||
TdeMigrationClientException = 'TdeMigrationClientException',
|
||||
TdeConfigurationUseADS = 'TdeConfigurationUseADS',
|
||||
TdeConfigurationIgnoreADS = 'TdeConfigurationIgnoreADS'
|
||||
}
|
||||
|
||||
export function logError(telemetryView: TelemetryViews, err: string, error: any): void {
|
||||
|
||||
@@ -18,10 +18,9 @@ import { IconPath, IconPathHelper } from '../constants/iconPathHelper';
|
||||
import { WIZARD_INPUT_COMPONENT_WIDTH } from './wizardController';
|
||||
import * as styles from '../constants/styles';
|
||||
import { SkuEditParametersDialog } from '../dialog/skuRecommendationResults/skuEditParametersDialog';
|
||||
import { logError, TelemetryViews } from '../telemetry';
|
||||
import { logError, TelemetryViews, TelemetryAction, sendSqlMigrationActionEvent, getTelemetryProps } from '../telemetry';
|
||||
import { TdeConfigurationDialog } from '../dialog/tdeConfiguration/tdeConfigurationDialog';
|
||||
import { TdeMigrationModel } from '../models/tdeModels';
|
||||
import * as os from 'os';
|
||||
import { getSourceConnectionProfile } from '../api/sqlUtils';
|
||||
|
||||
export interface Product {
|
||||
@@ -817,7 +816,7 @@ export class SKURecommendationPage extends MigrationWizardPage {
|
||||
if (this._matchWithEncryptedDatabases(encryptedDbFound)) {
|
||||
this.migrationStateModel.tdeMigrationConfig = this._previousMiTdeMigrationConfig;
|
||||
} else {
|
||||
if (os.platform() !== 'win32') //Only available for windows for now.
|
||||
if (!utils.isWindows()) //Only available for windows for now.
|
||||
return;
|
||||
|
||||
//Set encrypted databases
|
||||
@@ -843,6 +842,17 @@ export class SKURecommendationPage extends MigrationWizardPage {
|
||||
const tdeMsg = (this.migrationStateModel.tdeMigrationConfig.isTdeMigrationMethodAdsConfirmed()) ? constants.TDE_WIZARD_MSG_TDE : constants.TDE_WIZARD_MSG_MANUAL;
|
||||
this._tdedatabaseSelectedHelperText.value = constants.TDE_MSG_DATABASES_SELECTED(this.migrationStateModel.tdeMigrationConfig.getTdeEnabledDatabasesCount(), tdeMsg);
|
||||
|
||||
const tdeTelemetryAction = (this.migrationStateModel.tdeMigrationConfig.isTdeMigrationMethodAdsConfirmed()) ? TelemetryAction.TdeConfigurationUseADS : TelemetryAction.TdeConfigurationIgnoreADS;
|
||||
|
||||
sendSqlMigrationActionEvent(
|
||||
TelemetryViews.TdeConfigurationDialog,
|
||||
tdeTelemetryAction,
|
||||
{
|
||||
...getTelemetryProps(this.migrationStateModel)
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
return this._tdeEditButton.focus();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user