mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 11:01:37 -05:00
Profiler view templates (#1915)
* Initial view template framework * Removing some templates, reordering drop down * Fixing comments and formatting * Adding issue reference for commented code
This commit is contained in:
committed by
GitHub
parent
d2b5043972
commit
1327120024
@@ -13,7 +13,7 @@ import * as nls from 'vs/nls';
|
|||||||
|
|
||||||
import { ProfilerInput } from 'sql/parts/profiler/editor/profilerInput';
|
import { ProfilerInput } from 'sql/parts/profiler/editor/profilerInput';
|
||||||
import { ProfilerEditor } from 'sql/parts/profiler/editor/profilerEditor';
|
import { ProfilerEditor } from 'sql/parts/profiler/editor/profilerEditor';
|
||||||
import { PROFILER_SESSION_TEMPLATE_SETTINGS, IProfilerSessionTemplate } from 'sql/parts/profiler/service/interfaces';
|
import { PROFILER_VIEW_TEMPLATE_SETTINGS, IProfilerViewTemplate } from 'sql/parts/profiler/service/interfaces';
|
||||||
|
|
||||||
const profilerDescriptor = new EditorDescriptor(
|
const profilerDescriptor = new EditorDescriptor(
|
||||||
ProfilerEditor,
|
ProfilerEditor,
|
||||||
@@ -24,8 +24,8 @@ const profilerDescriptor = new EditorDescriptor(
|
|||||||
Registry.as<IEditorRegistry>(EditorExtensions.Editors)
|
Registry.as<IEditorRegistry>(EditorExtensions.Editors)
|
||||||
.registerEditor(profilerDescriptor, [new SyncDescriptor(ProfilerInput)]);
|
.registerEditor(profilerDescriptor, [new SyncDescriptor(ProfilerInput)]);
|
||||||
|
|
||||||
const profilerSessionTemplateSchema: IJSONSchema = {
|
const profilerViewTemplateSchema: IJSONSchema = {
|
||||||
description: nls.localize('profiler.settings.sessionTemplates', "Specifies session templates"),
|
description: nls.localize('profiler.settings.viewTemplates', "Specifies view templates"),
|
||||||
type: 'array',
|
type: 'array',
|
||||||
items: <IJSONSchema>{
|
items: <IJSONSchema>{
|
||||||
type: 'object',
|
type: 'object',
|
||||||
@@ -35,73 +35,202 @@ const profilerSessionTemplateSchema: IJSONSchema = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
default: <Array<IProfilerSessionTemplate>>[
|
default: <Array<IProfilerViewTemplate>>[
|
||||||
{
|
{
|
||||||
name: 'Standard',
|
name: 'Standard View',
|
||||||
events: [
|
columns: [
|
||||||
{
|
{
|
||||||
name: 'Audit Login',
|
name: 'EventClass',
|
||||||
optionalColumns: ['TextData', 'ApplicationName', 'NTUserName', 'LoginName', 'ClientProcessID', 'SPID', 'StartTime', 'BinaryData']
|
eventsMapped: ['name']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Audit Logout',
|
name: 'TextData',
|
||||||
optionalColumns: ['ApplicationName', 'NTUserName', 'LoginName', 'CPU', 'Reads', 'Writes', 'Duration', 'ClientProcessID', 'SPID', 'StartTime', 'EndTime']
|
eventsMapped: ['options_text', 'batch_text']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ExistingConnection',
|
name: 'ApplicationName',
|
||||||
optionalColumns: ['TextData', 'ApplicationName', 'NTUserName', 'LoginName', 'Duration', 'ClientProcessID', 'SPID', 'StartTime', 'EndTime', 'BinaryData']
|
width: '1',
|
||||||
|
eventsMapped: ['client_app_name']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'RPC:Completed',
|
name: 'NTUserName',
|
||||||
optionalColumns: ['TextData', 'ApplicationName', 'NTUserName', 'LoginName', 'CPU', 'Reads', 'Writes', 'Duration', 'ClientProcessID', 'SPID', 'StartTime', 'EndTime', 'BinaryData']
|
eventsMapped: ['nt_username']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'SQL:BatchCompleted',
|
name: 'LoginName',
|
||||||
optionalColumns: ['TextData', 'ApplicationName', 'NTUserName', 'LoginName', 'CPU', 'Reads', 'Writes', 'Duration', 'ClientProcessID', 'SPID', 'StartTime', 'EndTime', 'BinaryData']
|
eventsMapped: ['server_principal_name']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'SQL:BatchStarting',
|
name: 'ClientProcessID',
|
||||||
optionalColumns: ['TextData', 'ApplicationName', 'NTUserName', 'LoginName', 'ClientProcessID', 'SPID', 'StartTime']
|
eventsMapped: ['client_pid']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'SPID',
|
||||||
|
eventsMapped: ['session_id']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'StartTime',
|
||||||
|
eventsMapped: ['timestamp']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CPU',
|
||||||
|
eventsMapped: ['cpu_time']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Reads',
|
||||||
|
eventsMapped: ['logical_reads']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Writes',
|
||||||
|
eventsMapped: ['writes']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Duration',
|
||||||
|
eventsMapped: ['duration']
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
view: {
|
|
||||||
events: [
|
|
||||||
{
|
|
||||||
name: 'Audit Login',
|
|
||||||
columns: ['TextData', 'ApplicationName', 'NTUserName', 'LoginName', 'ClientProcessID', 'SPID', 'StartTime']
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Audit Logout',
|
name: 'TSQL View',
|
||||||
columns: ['ApplicationName', 'NTUserName', 'LoginName', 'CPU', 'Reads', 'Writes', 'Duration', 'ClientProcessID', 'SPID', 'StartTime', 'EndTime']
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'EventClass',
|
||||||
|
eventsMapped: ['name']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'ExistingConnection',
|
name: 'TextData',
|
||||||
columns: ['TextData', 'ApplicationName', 'NTUserName', 'LoginName', 'ClientProcessID', 'SPID', 'StartTime']
|
eventsMapped: ['options_text', 'batch_text']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'RPC:Completed',
|
name: 'SPID',
|
||||||
columns: ['ApplicationName', 'NTUserName', 'LoginName', 'CPU', 'Reads', 'Writes', 'Duration', 'ClientProcessID', 'SPID', 'StartTime', 'EndTime', 'BinaryData']
|
eventsMapped: ['session_id']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'SQL:BatchCompleted',
|
name: 'StartTime',
|
||||||
columns: ['TextData', 'ApplicationName', 'NTUserName', 'LoginName', 'CPU', 'Reads', 'Writes', 'Duration', 'ClientProcessID', 'SPID', 'StartTime', 'EndTime', 'BinaryData']
|
eventsMapped: ['timestamp']
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'SQL:BatchStarting',
|
name: 'Tuning View',
|
||||||
columns: ['TextData', 'ApplicationName', 'NTUserName', 'LoginName', 'ClientProcessID', 'SPID', 'StartTime']
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'EventClass',
|
||||||
|
eventsMapped: ['name']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TextData',
|
||||||
|
eventsMapped: ['options_text', 'batch_text']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Duration',
|
||||||
|
eventsMapped: ['duration']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'SPID',
|
||||||
|
eventsMapped: ['session_id']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'DatabaseID',
|
||||||
|
eventsMapped: ['database_id']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'DatabaseName',
|
||||||
|
eventsMapped: ['database_name']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ObjectType',
|
||||||
|
eventsMapped: ['object_type']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'LoginName',
|
||||||
|
eventsMapped: ['server_principal_name']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TSQL_Locks View',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'EventClass',
|
||||||
|
eventsMapped: ['name']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TextData',
|
||||||
|
eventsMapped: ['options_text', 'batch_text']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ApplicationName',
|
||||||
|
eventsMapped: ['client_app_name']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'NTUserName',
|
||||||
|
eventsMapped: ['nt_username']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'LoginName',
|
||||||
|
eventsMapped: ['server_principal_name']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ClientProcessID',
|
||||||
|
eventsMapped: ['client_pid']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'SPID',
|
||||||
|
eventsMapped: ['session_id']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'StartTime',
|
||||||
|
eventsMapped: ['timestamp']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CPU',
|
||||||
|
eventsMapped: ['cpu_time']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Reads',
|
||||||
|
eventsMapped: ['logical_reads']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Writes',
|
||||||
|
eventsMapped: ['writes']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Duration',
|
||||||
|
eventsMapped: ['duration']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TSQL_Duration View',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'EventClass',
|
||||||
|
eventsMapped: ['name']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Duration',
|
||||||
|
eventsMapped: ['duration']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TextData',
|
||||||
|
eventsMapped: ['options_text', 'batch_text']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'SPID',
|
||||||
|
eventsMapped: ['session_id']
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
|
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
|
||||||
const dashboardConfig: IConfigurationNode = {
|
const dashboardConfig: IConfigurationNode = {
|
||||||
id: 'Profiler',
|
id: 'Profiler',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
[PROFILER_SESSION_TEMPLATE_SETTINGS]: profilerSessionTemplateSchema
|
[PROFILER_VIEW_TEMPLATE_SETTINGS]: profilerViewTemplateSchema
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -360,7 +360,10 @@ export class ProfilerColumnEditorDialog extends Modal {
|
|||||||
super.onAccept(e);
|
super.onAccept(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// currently not used, this dialog is a work in progress
|
||||||
|
// tracked in issue #1545 https://github.com/Microsoft/sqlopsstudio/issues/1545
|
||||||
private _updateInput(): void {
|
private _updateInput(): void {
|
||||||
|
/*
|
||||||
this._element.getUnsortedChildren().forEach(e => {
|
this._element.getUnsortedChildren().forEach(e => {
|
||||||
let origEvent = this._input.sessionTemplate.view.events.find(i => i.name === e.id);
|
let origEvent = this._input.sessionTemplate.view.events.find(i => i.name === e.id);
|
||||||
if (e.indeterminate) {
|
if (e.indeterminate) {
|
||||||
@@ -387,9 +390,13 @@ export class ProfilerColumnEditorDialog extends Modal {
|
|||||||
}, []);
|
}, []);
|
||||||
newColumns.unshift('EventClass');
|
newColumns.unshift('EventClass');
|
||||||
this._input.setColumns(newColumns);
|
this._input.setColumns(newColumns);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// currently not used, this dialog is a work in progress
|
||||||
|
// tracked in issue #1545 https://github.com/Microsoft/sqlopsstudio/issues/1545
|
||||||
private _updateList(): void {
|
private _updateList(): void {
|
||||||
|
/*
|
||||||
this._element = new SessionItem(this._input.sessionTemplate.name, this._selectedValue === 0 ? 'event' : 'column');
|
this._element = new SessionItem(this._input.sessionTemplate.name, this._selectedValue === 0 ? 'event' : 'column');
|
||||||
this._input.sessionTemplate.events.forEach(item => {
|
this._input.sessionTemplate.events.forEach(item => {
|
||||||
let event = new EventItem(item.name, this._element);
|
let event = new EventItem(item.name, this._element);
|
||||||
@@ -402,6 +409,7 @@ export class ProfilerColumnEditorDialog extends Modal {
|
|||||||
});
|
});
|
||||||
this._tree.setInput(this._element);
|
this._tree.setInput(this._element);
|
||||||
this._tree.layout(DOM.getTotalHeight(this._treeContainer));
|
this._tree.layout(DOM.getTotalHeight(this._treeContainer));
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
protected layout(height?: number): void {
|
protected layout(height?: number): void {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { ProfilerInput } from './profilerInput';
|
|||||||
import { TabbedPanel } from 'sql/base/browser/ui/panel/panel';
|
import { TabbedPanel } from 'sql/base/browser/ui/panel/panel';
|
||||||
import { Table } from 'sql/base/browser/ui/table/table';
|
import { Table } from 'sql/base/browser/ui/table/table';
|
||||||
import { TableDataView } from 'sql/base/browser/ui/table/tableDataView';
|
import { TableDataView } from 'sql/base/browser/ui/table/tableDataView';
|
||||||
import { IProfilerService, IProfilerSessionTemplate } from 'sql/parts/profiler/service/interfaces';
|
import { IProfilerService, IProfilerViewTemplate } from 'sql/parts/profiler/service/interfaces';
|
||||||
import { Taskbar } from 'sql/base/browser/ui/taskbar/taskbar';
|
import { Taskbar } from 'sql/base/browser/ui/taskbar/taskbar';
|
||||||
import { attachTableStyler } from 'sql/common/theme/styler';
|
import { attachTableStyler } from 'sql/common/theme/styler';
|
||||||
import { IProfilerStateChangedEvent } from './profilerState';
|
import { IProfilerStateChangedEvent } from './profilerState';
|
||||||
@@ -114,8 +114,8 @@ export class ProfilerEditor extends BaseEditor {
|
|||||||
|
|
||||||
private _profilerEditorContextKey: IContextKey<boolean>;
|
private _profilerEditorContextKey: IContextKey<boolean>;
|
||||||
|
|
||||||
private _sessionTemplateSelector: SelectBox;
|
private _viewTemplateSelector: SelectBox;
|
||||||
private _sessionTemplates: Array<IProfilerSessionTemplate>;
|
private _viewTemplates: Array<IProfilerViewTemplate>;
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
private _connectAction: Actions.ProfilerConnect;
|
private _connectAction: Actions.ProfilerConnect;
|
||||||
@@ -125,6 +125,7 @@ export class ProfilerEditor extends BaseEditor {
|
|||||||
private _autoscrollAction: Actions.ProfilerAutoScroll;
|
private _autoscrollAction: Actions.ProfilerAutoScroll;
|
||||||
private _collapsedPanelAction: Actions.ProfilerCollapsablePanelAction;
|
private _collapsedPanelAction: Actions.ProfilerCollapsablePanelAction;
|
||||||
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ITelemetryService telemetryService: ITelemetryService,
|
@ITelemetryService telemetryService: ITelemetryService,
|
||||||
@IWorkbenchThemeService themeService: IWorkbenchThemeService,
|
@IWorkbenchThemeService themeService: IWorkbenchThemeService,
|
||||||
@@ -189,27 +190,27 @@ export class ProfilerEditor extends BaseEditor {
|
|||||||
this._connectAction = this._instantiationService.createInstance(Actions.ProfilerConnect, Actions.ProfilerConnect.ID, Actions.ProfilerConnect.LABEL);
|
this._connectAction = this._instantiationService.createInstance(Actions.ProfilerConnect, Actions.ProfilerConnect.ID, Actions.ProfilerConnect.LABEL);
|
||||||
this._autoscrollAction = this._instantiationService.createInstance(Actions.ProfilerAutoScroll, Actions.ProfilerAutoScroll.ID, Actions.ProfilerAutoScroll.LABEL);
|
this._autoscrollAction = this._instantiationService.createInstance(Actions.ProfilerAutoScroll, Actions.ProfilerAutoScroll.ID, Actions.ProfilerAutoScroll.LABEL);
|
||||||
|
|
||||||
this._sessionTemplates = this._profilerService.getSessionTemplates();
|
this._viewTemplates = this._profilerService.getViewTemplates();
|
||||||
this._sessionTemplateSelector = new SelectBox(this._sessionTemplates.map(i => i.name), 'Standard', this._contextViewService);
|
this._viewTemplateSelector = new SelectBox(this._viewTemplates.map(i => i.name), 'Standard View', this._contextViewService);
|
||||||
this._register(this._sessionTemplateSelector.onDidSelect(e => {
|
this._register(this._viewTemplateSelector.onDidSelect(e => {
|
||||||
if (this.input) {
|
if (this.input) {
|
||||||
this.input.sessionTemplate = this._sessionTemplates.find(i => i.name === e.selected);
|
this.input.viewTemplate = this._viewTemplates.find(i => i.name === e.selected);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
let dropdownContainer = document.createElement('div');
|
let dropdownContainer = document.createElement('div');
|
||||||
dropdownContainer.style.width = '150px';
|
dropdownContainer.style.width = '150px';
|
||||||
this._sessionTemplateSelector.render(dropdownContainer);
|
this._viewTemplateSelector.render(dropdownContainer);
|
||||||
|
|
||||||
this._register(attachSelectBoxStyler(this._sessionTemplateSelector, this.themeService));
|
this._register(attachSelectBoxStyler(this._viewTemplateSelector, this.themeService));
|
||||||
|
|
||||||
this._actionBar.setContent([
|
this._actionBar.setContent([
|
||||||
{ action: this._startAction },
|
{ action: this._startAction },
|
||||||
{ action: this._stopAction },
|
{ action: this._stopAction },
|
||||||
{ element: dropdownContainer },
|
|
||||||
{ element: Taskbar.createTaskbarSeparator() },
|
{ element: Taskbar.createTaskbarSeparator() },
|
||||||
{ action: this._pauseAction },
|
{ action: this._pauseAction },
|
||||||
{ action: this._autoscrollAction },
|
{ action: this._autoscrollAction },
|
||||||
{ action: this._instantiationService.createInstance(Actions.ProfilerClear, Actions.ProfilerClear.ID, Actions.ProfilerClear.LABEL) }
|
{ action: this._instantiationService.createInstance(Actions.ProfilerClear, Actions.ProfilerClear.ID, Actions.ProfilerClear.LABEL) },
|
||||||
|
{ element: dropdownContainer },
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,10 +341,10 @@ export class ProfilerEditor extends BaseEditor {
|
|||||||
return super.setInput(input, options).then(() => {
|
return super.setInput(input, options).then(() => {
|
||||||
this._profilerTableEditor.setInput(input);
|
this._profilerTableEditor.setInput(input);
|
||||||
|
|
||||||
if (input.sessionTemplate) {
|
if (input.viewTemplate) {
|
||||||
this._sessionTemplateSelector.selectWithOptionName(input.sessionTemplate.name);
|
this._viewTemplateSelector.selectWithOptionName(input.viewTemplate.name);
|
||||||
} else {
|
} else {
|
||||||
input.sessionTemplate = this._sessionTemplates.find(i => i.name === 'Standard');
|
input.viewTemplate = this._viewTemplates.find(i => i.name === 'Standard View');
|
||||||
}
|
}
|
||||||
|
|
||||||
this._actionBar.context = input;
|
this._actionBar.context = input;
|
||||||
@@ -401,10 +402,7 @@ export class ProfilerEditor extends BaseEditor {
|
|||||||
|
|
||||||
if (e.isConnected) {
|
if (e.isConnected) {
|
||||||
this._connectAction.connected = this.input.state.isConnected;
|
this._connectAction.connected = this.input.state.isConnected;
|
||||||
if (this.input.state.isConnected) {
|
if (!this.input.state.isConnected) {
|
||||||
this._sessionTemplateSelector.disable();
|
|
||||||
} else {
|
|
||||||
this._sessionTemplateSelector.enable();
|
|
||||||
this._startAction.enabled = this.input.state.isConnected;
|
this._startAction.enabled = this.input.state.isConnected;
|
||||||
this._stopAction.enabled = false;
|
this._stopAction.enabled = false;
|
||||||
this._pauseAction.enabled = false;
|
this._pauseAction.enabled = false;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { TableDataView } from 'sql/base/browser/ui/table/tableDataView';
|
import { TableDataView } from 'sql/base/browser/ui/table/tableDataView';
|
||||||
import { IProfilerSession, IProfilerService, ProfilerSessionID, IProfilerSessionTemplate } from 'sql/parts/profiler/service/interfaces';
|
import { IProfilerSession, IProfilerService, ProfilerSessionID, IProfilerViewTemplate } from 'sql/parts/profiler/service/interfaces';
|
||||||
import { ProfilerState } from './profilerState';
|
import { ProfilerState } from './profilerState';
|
||||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||||
|
|
||||||
@@ -28,7 +28,10 @@ export class ProfilerInput extends EditorInput implements IProfilerSession {
|
|||||||
private _id: ProfilerSessionID;
|
private _id: ProfilerSessionID;
|
||||||
private _state: ProfilerState;
|
private _state: ProfilerState;
|
||||||
private _columns: string[] = [];
|
private _columns: string[] = [];
|
||||||
private _sessionTemplate: IProfilerSessionTemplate;
|
private _viewTemplate: IProfilerViewTemplate;
|
||||||
|
// mapping of event categories to what column they display under
|
||||||
|
// used for coallescing multiple events with different names to the same column
|
||||||
|
private _columnMapping: { [event: string]: string } = {};
|
||||||
|
|
||||||
private _onColumnsChanged = new Emitter<Slick.Column<Slick.SlickData>[]>();
|
private _onColumnsChanged = new Emitter<Slick.Column<Slick.SlickData>[]>();
|
||||||
public onColumnsChanged: Event<Slick.Column<Slick.SlickData>[]> = this._onColumnsChanged.event;
|
public onColumnsChanged: Event<Slick.Column<Slick.SlickData>[]> = this._onColumnsChanged.event;
|
||||||
@@ -63,22 +66,26 @@ export class ProfilerInput extends EditorInput implements IProfilerSession {
|
|||||||
this._data = new TableDataView<Slick.SlickData>(undefined, searchFn);
|
this._data = new TableDataView<Slick.SlickData>(undefined, searchFn);
|
||||||
}
|
}
|
||||||
|
|
||||||
public set sessionTemplate(template: IProfilerSessionTemplate) {
|
public set viewTemplate(template: IProfilerViewTemplate) {
|
||||||
this._sessionTemplate = template;
|
this._data.clear();
|
||||||
let newColumns = this.sessionTemplate.view.events.reduce<Array<string>>((p, e) => {
|
this._viewTemplate = template;
|
||||||
e.columns.forEach(c => {
|
|
||||||
if (!p.includes(c)) {
|
let newColumns = this._viewTemplate.columns.reduce<Array<string>>((p, e) => {
|
||||||
p.push(c);
|
p.push(e.name);
|
||||||
}
|
|
||||||
});
|
|
||||||
return p;
|
return p;
|
||||||
}, []);
|
}, []);
|
||||||
newColumns.unshift('EventClass');
|
|
||||||
this.setColumns(newColumns);
|
let newMapping: { [event: string]: string } = {};
|
||||||
|
this._viewTemplate.columns.forEach(c => {
|
||||||
|
c.eventsMapped.forEach(e => {
|
||||||
|
newMapping[e] = c.name;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.setColumnMapping(newColumns, newMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get sessionTemplate(): IProfilerSessionTemplate {
|
public get viewTemplate(): IProfilerViewTemplate {
|
||||||
return this._sessionTemplate;
|
return this._viewTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTypeId(): string {
|
public getTypeId(): string {
|
||||||
@@ -117,6 +124,12 @@ export class ProfilerInput extends EditorInput implements IProfilerSession {
|
|||||||
this._onColumnsChanged.fire(this.columns);
|
this._onColumnsChanged.fire(this.columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setColumnMapping(columns: Array<string>, mapping: { [event: string]: string }) {
|
||||||
|
this._columns = columns;
|
||||||
|
this._columnMapping = mapping;
|
||||||
|
this._onColumnsChanged.fire(this.columns);
|
||||||
|
}
|
||||||
|
|
||||||
public get id(): ProfilerSessionID {
|
public get id(): ProfilerSessionID {
|
||||||
return this._id;
|
return this._id;
|
||||||
}
|
}
|
||||||
@@ -140,7 +153,7 @@ export class ProfilerInput extends EditorInput implements IProfilerSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public onMoreRows(eventMessage: sqlops.ProfilerSessionEvents) {
|
public onMoreRows(eventMessage: sqlops.ProfilerSessionEvents) {
|
||||||
if (eventMessage.eventsLost){
|
if (eventMessage.eventsLost) {
|
||||||
this._notificationService.warn(nls.localize("profiler.eventsLost", "The XEvent Profiler session for {0} has lost events.", this._connection.serverName));
|
this._notificationService.warn(nls.localize("profiler.eventsLost", "The XEvent Profiler session for {0} has lost events.", this._connection.serverName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,42 +162,13 @@ export class ProfilerInput extends EditorInput implements IProfilerSession {
|
|||||||
let data = {};
|
let data = {};
|
||||||
data['EventClass'] = e.name;
|
data['EventClass'] = e.name;
|
||||||
data['StartTime'] = e.timestamp;
|
data['StartTime'] = e.timestamp;
|
||||||
const columns = [
|
|
||||||
'TextData',
|
|
||||||
'ApplicationName',
|
|
||||||
'NTUserName',
|
|
||||||
'LoginName',
|
|
||||||
'CPU',
|
|
||||||
'Reads',
|
|
||||||
'Writes',
|
|
||||||
'Duration',
|
|
||||||
'ClientProcessID',
|
|
||||||
'SPID',
|
|
||||||
'StartTime',
|
|
||||||
'EndTime',
|
|
||||||
'BinaryData'
|
|
||||||
];
|
|
||||||
|
|
||||||
let columnNameMap: Map<string, string> = new Map<string, string>();
|
|
||||||
columnNameMap['client_app_name'] = 'ApplicationName';
|
|
||||||
columnNameMap['nt_username'] = 'NTUserName';
|
|
||||||
columnNameMap['options_text'] = 'TextData';
|
|
||||||
columnNameMap['server_principal_name'] = 'LoginName';
|
|
||||||
columnNameMap['session_id'] = 'SPID';
|
|
||||||
columnNameMap['batch_text'] = 'TextData';
|
|
||||||
columnNameMap['cpu_time'] = 'CPU';
|
|
||||||
columnNameMap['duration'] = 'Duration';
|
|
||||||
columnNameMap['logical_reads'] = 'Reads';
|
|
||||||
columnNameMap['event_sequence'] = 'EventSequence';
|
|
||||||
columnNameMap['client_pid'] = 'ClientProcessID';
|
|
||||||
columnNameMap['writes'] = 'Writes';
|
|
||||||
|
|
||||||
// Using ' ' instead of '' fixed the error where clicking through events
|
// Using ' ' instead of '' fixed the error where clicking through events
|
||||||
// with empty text fields causes future text panes to be highlighted.
|
// with empty text fields causes future text panes to be highlighted.
|
||||||
// This is a temporary fix, and should be changed before the July release
|
// This is a temporary fix
|
||||||
data['TextData'] = ' ';
|
data['TextData'] = ' ';
|
||||||
for (let key in e.values) {
|
for (let key in e.values) {
|
||||||
let columnName = columnNameMap[key];
|
let columnName = this._columnMapping[key];
|
||||||
if (columnName) {
|
if (columnName) {
|
||||||
let value = e.values[key];
|
let value = e.values[key];
|
||||||
data[columnName] = value;
|
data[columnName] = value;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const IProfilerService = createDecorator<IProfilerService>(PROFILER_SERVI
|
|||||||
|
|
||||||
export type ProfilerSessionID = string;
|
export type ProfilerSessionID = string;
|
||||||
|
|
||||||
export const PROFILER_SESSION_TEMPLATE_SETTINGS = 'profiler.sessionTemplates';
|
export const PROFILER_VIEW_TEMPLATE_SETTINGS = 'profiler.viewTemplates';
|
||||||
export const PROFILER_SETTINGS = 'profiler';
|
export const PROFILER_SETTINGS = 'profiler';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,7 +84,7 @@ export interface IProfilerService {
|
|||||||
* @returns An array of session templates that match the provider passed, if passed, and generic ones (no provider specified),
|
* @returns An array of session templates that match the provider passed, if passed, and generic ones (no provider specified),
|
||||||
* otherwise returns all session templates
|
* otherwise returns all session templates
|
||||||
*/
|
*/
|
||||||
getSessionTemplates(providerId?: string): Array<IProfilerSessionTemplate>;
|
getViewTemplates(providerId?: string): Array<IProfilerViewTemplate>;
|
||||||
/**
|
/**
|
||||||
* Launches the dialog for editing the view columns of a profiler session template for the given input
|
* Launches the dialog for editing the view columns of a profiler session template for the given input
|
||||||
* @param input input object that contains the necessary information which will be modified based on used input
|
* @param input input object that contains the necessary information which will be modified based on used input
|
||||||
@@ -93,25 +93,16 @@ export interface IProfilerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IProfilerSettings {
|
export interface IProfilerSettings {
|
||||||
sessionTemplates: Array<IProfilerSessionTemplate>;
|
viewTemplates: Array<IProfilerViewTemplate>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IEventTemplate {
|
export interface IColumnViewTemplate {
|
||||||
name: string;
|
name: string;
|
||||||
optionalColumns: Array<string>;
|
width: string;
|
||||||
|
eventsMapped: Array<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IEventViewTemplate {
|
export interface IProfilerViewTemplate {
|
||||||
name: string;
|
name: string;
|
||||||
columns: Array<string>;
|
columns: Array<IColumnViewTemplate>;
|
||||||
}
|
|
||||||
|
|
||||||
export interface ISessionViewTemplate {
|
|
||||||
events: Array<IEventViewTemplate>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IProfilerSessionTemplate {
|
|
||||||
name: string;
|
|
||||||
events: Array<IEventTemplate>;
|
|
||||||
view: ISessionViewTemplate;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
import { IConnectionManagementService, IConnectionCompletionOptions, ConnectionType, RunQueryOnConnectionMode } from 'sql/parts/connection/common/connectionManagement';
|
import { IConnectionManagementService, IConnectionCompletionOptions, ConnectionType, RunQueryOnConnectionMode } from 'sql/parts/connection/common/connectionManagement';
|
||||||
import {
|
import {
|
||||||
ProfilerSessionID, IProfilerSession, IProfilerService, IProfilerSessionTemplate,
|
ProfilerSessionID, IProfilerSession, IProfilerService, IProfilerViewTemplate,
|
||||||
PROFILER_SETTINGS, IProfilerSettings
|
PROFILER_SETTINGS, IProfilerSettings
|
||||||
} from './interfaces';
|
} from './interfaces';
|
||||||
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
import { IConnectionProfile } from 'sql/parts/connection/common/interfaces';
|
||||||
@@ -128,13 +128,13 @@ export class ProfilerService implements IProfilerService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getSessionTemplates(provider?: string): Array<IProfilerSessionTemplate> {
|
public getViewTemplates(provider?: string): Array<IProfilerViewTemplate> {
|
||||||
let config = <IProfilerSettings>this._configurationService.getValue(PROFILER_SETTINGS);
|
let config = <IProfilerSettings>this._configurationService.getValue(PROFILER_SETTINGS);
|
||||||
|
|
||||||
if (provider) {
|
if (provider) {
|
||||||
return config.sessionTemplates;
|
return config.viewTemplates;
|
||||||
} else {
|
} else {
|
||||||
return config.sessionTemplates;
|
return config.viewTemplates;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user