From 1903388b6bb48c38f28ecbb21dd7accf4d3ea00e Mon Sep 17 00:00:00 2001 From: Drew Skwiers-Koballa Date: Mon, 14 Dec 2020 20:47:04 -0800 Subject: [PATCH] Server Reports extension: fix for start and stop xevent sessions (#13565) * fix for start and stop xevent sessions * vscode.open for help URL * setup info messages for localization @kburtram - I could use an assist on updating the v# and publishing the vsix, but there's no rush this can wait until after the holidays --- samples/serverReports/package.json | 5 ++- samples/serverReports/src/constants.ts | 8 ++++ .../src/controllers/mainController.ts | 44 +++++++++++-------- samples/serverReports/src/sql/startEvent.sql | 18 ++++---- samples/serverReports/src/sql/stopEvent.sql | 1 + samples/serverReports/yarn.lock | 5 +++ 6 files changed, 52 insertions(+), 29 deletions(-) diff --git a/samples/serverReports/package.json b/samples/serverReports/package.json index 0472a3c7c3..9d83f2ec68 100644 --- a/samples/serverReports/package.json +++ b/samples/serverReports/package.json @@ -48,7 +48,7 @@ }, { "command": "tempdb.pauseEvent", - "title": "Pause", + "title": "Toggle Auto Refresh", "icon": { "light": "./out/src/media/insights.svg", "dark": "./out/src/media/insights_inverse.svg" @@ -387,7 +387,8 @@ "dependencies": { "fs-extra": "^8.1.0", "handlebars": "^4.5.3", - "openurl": "^1.1.1" + "openurl": "^1.1.1", + "vscode-nls": "^5.0.0" }, "devDependencies": { "azdata": "^1.0.0", diff --git a/samples/serverReports/src/constants.ts b/samples/serverReports/src/constants.ts index 2042cedd8f..f9fb5efb97 100644 --- a/samples/serverReports/src/constants.ts +++ b/samples/serverReports/src/constants.ts @@ -4,6 +4,14 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; +import * as nls from 'vscode-nls'; +const localize = nls.loadMessageBundle(); + +// TempDB Messages +export const XEventsFailed = localize('XEventsFailed', 'XEvents operation failed.'); +export const XEventsStarted = localize('XEventsStarted', 'XEvents sessions started for PageContention and ObjectContention.'); +export const XEventsNotSupported = localize('XEventsNotSupported', 'XEvents sessions not supported.'); +export const XEventsStopped = localize('XEventsStopped', 'XEvents sessions PageContention and ObjectContention removed.'); // CONFIG VALUES /////////////////////////////////////////////////////////// export const extensionConfigSectionName = 'server-reports'; export const configLogDebugInfo = 'logDebugInfo'; diff --git a/samples/serverReports/src/controllers/mainController.ts b/samples/serverReports/src/controllers/mainController.ts index 135193cbbd..6818ff7797 100644 --- a/samples/serverReports/src/controllers/mainController.ts +++ b/samples/serverReports/src/controllers/mainController.ts @@ -8,16 +8,16 @@ import * as azdata from 'azdata'; import * as Utils from '../utils'; import ControllerBase from './controllerBase'; -import * as fs from 'fs'; +import { promises } from 'fs'; import * as path from 'path'; import * as vscode from 'vscode'; -import * as openurl from 'openurl'; - +import * as constants from '../constants'; /** * The main controller class that initializes the extension */ export default class MainController extends ControllerBase { + private autoRefreshState: boolean = false; public apiWrapper; // PUBLIC METHODS ////////////////////////////////////////////////////// @@ -38,26 +38,34 @@ export default class MainController extends ControllerBase { } private openurl(link: string): void { - openurl.open(link); + vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(link)); } - private onExecute(connection: azdata.IConnectionProfile, fileName: string): void { + private async onExecute(connection: azdata.IConnectionProfile, fileName: string): Promise { // Command to start/stop autorefresh and run the query - vscode.commands.executeCommand('azdata.widget.setAutoRefreshState', 'type-of-contention', connection.id, true); - vscode.commands.executeCommand('azdata.widget.setAutoRefreshState', 'metadata-contention', connection.id, true); - vscode.commands.executeCommand('azdata.widget.setAutoRefreshState', 'allocation-contention', connection.id, true); - let sqlContent = fs.readFileSync(path.join(__dirname, '..', 'sql', fileName)).toString(); - vscode.workspace.openTextDocument({ language: 'sql', content: sqlContent }).then(doc => { - vscode.window.showTextDocument(doc, vscode.ViewColumn.Active, false).then(() => { - let filePath = doc.uri.toString(); - azdata.queryeditor.connect(filePath, connection.id).then(() => azdata.queryeditor.runQuery(filePath, undefined, false)); - }); - }); + let connectionUri = await azdata.connection.getUriForConnection(connection.id); + let connectionProvider = azdata.dataprotocol.getProvider(connection.providerName, azdata.DataProviderType.ConnectionProvider); + connectionProvider.changeDatabase(connectionUri, 'tempdb'); + let queryProvider = azdata.dataprotocol.getProvider(connection.providerName, azdata.DataProviderType.QueryProvider); + let sqlContent: string = await promises.readFile(path.join(__dirname, '..', 'sql', fileName), {encoding: 'utf8'}); + let seResult = await queryProvider.runQueryAndReturn(connectionUri, sqlContent); + if (seResult.rowCount > 0 && seResult.rows[0][0].displayValue === '0') { + vscode.window.showInformationMessage( ( fileName === 'startEvent.sql' ) ? constants.XEventsStarted : constants.XEventsStopped ); + this.autoRefreshState = ( fileName === 'startEvent.sql' ) ? true : false; + vscode.commands.executeCommand('azdata.widget.setAutoRefreshState', 'type-of-contention', connection.id, this.autoRefreshState); + vscode.commands.executeCommand('azdata.widget.setAutoRefreshState', 'metadata-contention', connection.id, this.autoRefreshState); + vscode.commands.executeCommand('azdata.widget.setAutoRefreshState', 'allocation-contention', connection.id, this.autoRefreshState); + } else if (seResult.rowCount > 0 && seResult.rows[0][0].displayValue === '1') { + vscode.window.showErrorMessage(constants.XEventsNotSupported); + } else { + vscode.window.showErrorMessage(constants.XEventsFailed); + } } private stopAutoRefresh(connection: azdata.IConnectionProfile): void { - vscode.commands.executeCommand('azdata.widget.setAutoRefreshState', 'type-of-contention', connection.id, false); - vscode.commands.executeCommand('azdata.widget.setAutoRefreshState', 'metadata-contention', connection.id, false); - vscode.commands.executeCommand('azdata.widget.setAutoRefreshState', 'allocation-contention', connection.id, false); + this.autoRefreshState = !this.autoRefreshState === true; + vscode.commands.executeCommand('azdata.widget.setAutoRefreshState', 'type-of-contention', connection.id, this.autoRefreshState); + vscode.commands.executeCommand('azdata.widget.setAutoRefreshState', 'metadata-contention', connection.id, this.autoRefreshState); + vscode.commands.executeCommand('azdata.widget.setAutoRefreshState', 'allocation-contention', connection.id, this.autoRefreshState); } } diff --git a/samples/serverReports/src/sql/startEvent.sql b/samples/serverReports/src/sql/startEvent.sql index 91af2a6ba9..c5367923a4 100644 --- a/samples/serverReports/src/sql/startEvent.sql +++ b/samples/serverReports/src/sql/startEvent.sql @@ -1,6 +1,4 @@ --Starts the XEvents sessions and creates the functions needed to find object id and give name to the page types -use tempdb - BEGIN TRY IF NOT EXISTS (SELECT * FROM sys.dm_xe_sessions WHERE name = 'PageContention') BEGIN @@ -8,7 +6,7 @@ IF NOT EXISTS (SELECT * FROM sys.dm_xe_sessions WHERE name = 'PageContention') ADD EVENT latch_suspend_end( WHERE class = 28 AND (page_type_id = 8 - OR page_type_id = 9 + OR page_type_id = 9 OR page_type_id = 11)) ADD TARGET package0.histogram(SET slots=16, filtering_event_name=N'latch_suspend_end', source=N'page_type_id', source_type=(0)) ALTER EVENT SESSION [PageContention] ON SERVER @@ -24,9 +22,11 @@ IF NOT EXISTS (SELECT * FROM sys.dm_xe_sessions WHERE name = 'ObjectContention' ALTER EVENT SESSION [ObjectContention] ON SERVER STATE = START END +SELECT 0 AS RESULTCODE END TRY BEGIN CATCH PRINT 'XEvent fields not supported' + SELECT 1 AS RESULTCODE END CATCH GO @@ -38,7 +38,7 @@ CREATE FUNCTION [dbo].[isSystemTable] (@alloc bigint) RETURNS bigint AS BEGIN - + DECLARE @index BIGINT; DECLARE @objId BIGINT; @@ -47,7 +47,7 @@ AS BEGIN CONVERT (FLOAT, @alloc) * (1 / POWER (2.0, 48)) ); - SELECT @objId = + SELECT @objId = CONVERT (BIGINT, CONVERT (FLOAT, @alloc - (@index * CONVERT (BIGINT, POWER (2.0, 48)))) * (1 / POWER (2.0, 16)) @@ -55,9 +55,9 @@ AS BEGIN IF (@objId > 0 AND @objId <= 100 AND @index <= 255) return @objId - + return 0 - + END GO @@ -74,7 +74,7 @@ AS BEGIN ELSE IF @pageTypeId = 9 return 'SGAM_PAGE' ELSE IF @pageTypeId = 11 - return 'PFS_PAGE' + return 'PFS_PAGE' return '' END -GO \ No newline at end of file +GO diff --git a/samples/serverReports/src/sql/stopEvent.sql b/samples/serverReports/src/sql/stopEvent.sql index 3e12e9f61a..857e353fca 100644 --- a/samples/serverReports/src/sql/stopEvent.sql +++ b/samples/serverReports/src/sql/stopEvent.sql @@ -1,3 +1,4 @@ --Stops the XEvent Sessions DROP EVENT SESSION [PageContention] ON SERVER DROP EVENT SESSION [ObjectContention] ON SERVER +SELECT 0 AS RESULTCODE diff --git a/samples/serverReports/yarn.lock b/samples/serverReports/yarn.lock index 0e3811e4ad..71b8cb2224 100644 --- a/samples/serverReports/yarn.lock +++ b/samples/serverReports/yarn.lock @@ -3973,6 +3973,11 @@ vsce@1.36.2: yauzl "^2.3.1" yazl "^2.2.2" +vscode-nls@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.0.tgz#99f0da0bd9ea7cda44e565a74c54b1f2bc257840" + integrity sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA== + vscode-test@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/vscode-test/-/vscode-test-0.1.5.tgz#250534f90e78d37a84419a00f9bd15341e1a4f8f"