mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-14 01:25:40 -05:00
Add ability to create sessions from templates, and list existing sessions (#671)
* Initial changes to connect to existing sessions * Creating new profiler sessions * Some session template changes * Fixing errors * Cleaning up comments, string constants, and formatting * Removing commented code
This commit is contained in:
committed by
GitHub
parent
e8360ef68e
commit
4b9807f0cf
@@ -4559,9 +4559,9 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
return Keys.GetString(Keys.EditDataIncorrectTable, tableName);
|
||||
}
|
||||
|
||||
public static string StopSessionFailed(String error)
|
||||
public static string CreateSessionFailed(String error)
|
||||
{
|
||||
return Keys.GetString(Keys.StopSessionFailed, error);
|
||||
return Keys.GetString(Keys.CreateSessionFailed, error);
|
||||
}
|
||||
|
||||
public static string StartSessionFailed(String error)
|
||||
@@ -4569,6 +4569,21 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
return Keys.GetString(Keys.StartSessionFailed, error);
|
||||
}
|
||||
|
||||
public static string PauseSessionFailed(String error)
|
||||
{
|
||||
return Keys.GetString(Keys.PauseSessionFailed, error);
|
||||
}
|
||||
|
||||
public static string StopSessionFailed(String error)
|
||||
{
|
||||
return Keys.GetString(Keys.StopSessionFailed, error);
|
||||
}
|
||||
|
||||
public static string SessionAlreadyExists(String sessionName)
|
||||
{
|
||||
return Keys.GetString(Keys.SessionAlreadyExists, sessionName);
|
||||
}
|
||||
|
||||
public static string EnableAlertsTitle(String serverName)
|
||||
{
|
||||
return Keys.GetString(Keys.EnableAlertsTitle, serverName);
|
||||
@@ -6176,15 +6191,24 @@ namespace Microsoft.SqlTools.ServiceLayer
|
||||
public const string AzureSystemDbProfilingError = "AzureSystemDbProfilingError";
|
||||
|
||||
|
||||
public const string StopSessionFailed = "StopSessionFailed";
|
||||
public const string CreateSessionFailed = "CreateSessionFailed";
|
||||
|
||||
|
||||
public const string StartSessionFailed = "StartSessionFailed";
|
||||
|
||||
|
||||
public const string PauseSessionFailed = "PauseSessionFailed";
|
||||
|
||||
|
||||
public const string StopSessionFailed = "StopSessionFailed";
|
||||
|
||||
|
||||
public const string SessionNotFound = "SessionNotFound";
|
||||
|
||||
|
||||
public const string SessionAlreadyExists = "SessionAlreadyExists";
|
||||
|
||||
|
||||
public const string EnableAlertsTitle = "EnableAlertsTitle";
|
||||
|
||||
|
||||
|
||||
@@ -2027,20 +2027,35 @@
|
||||
<value>Cannot profile Azure system databases</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="StopSessionFailed" xml:space="preserve">
|
||||
<value>Failed to stop session: {0}</value>
|
||||
<data name="CreateSessionFailed" xml:space="preserve">
|
||||
<value>Failed to create session: {0}</value>
|
||||
<comment>.
|
||||
Parameters: 0 - error (String) </comment>
|
||||
</data>
|
||||
<data name="StartSessionFailed" xml:space="preserve">
|
||||
<value>Failed to start session: {0}</value>
|
||||
<comment>.
|
||||
Parameters: 0 - error (String) </comment>
|
||||
</data>
|
||||
<data name="PauseSessionFailed" xml:space="preserve">
|
||||
<value>Failed to pause session: {0}</value>
|
||||
<comment>.
|
||||
Parameters: 0 - error (String) </comment>
|
||||
</data>
|
||||
<data name="StopSessionFailed" xml:space="preserve">
|
||||
<value>Failed to stop session: {0}</value>
|
||||
<comment>.
|
||||
Parameters: 0 - error (String) </comment>
|
||||
</data>
|
||||
<data name="SessionNotFound" xml:space="preserve">
|
||||
<value>Cannot find requested XEvent session</value>
|
||||
<comment></comment>
|
||||
</data>
|
||||
<data name="SessionAlreadyExists" xml:space="preserve">
|
||||
<value>An XEvent session named {0} already exists</value>
|
||||
<comment>.
|
||||
Parameters: 0 - sessionName (String) </comment>
|
||||
</data>
|
||||
<data name="EnableAlertsTitle" xml:space="preserve">
|
||||
<value>Enable Alerts - {0}</value>
|
||||
<comment>.
|
||||
|
||||
@@ -888,9 +888,12 @@ InvalidPathError = Cannot access the specified path on the server: {0}
|
||||
# Profiler
|
||||
ProfilerConnectionNotFound = Connection not found
|
||||
AzureSystemDbProfilingError = Cannot profile Azure system databases
|
||||
StopSessionFailed(String error) = Failed to stop session: {0}
|
||||
CreateSessionFailed(String error) = Failed to create session: {0}
|
||||
StartSessionFailed(String error) = Failed to start session: {0}
|
||||
PauseSessionFailed(String error) = Failed to pause session: {0}
|
||||
StopSessionFailed(String error) = Failed to stop session: {0}
|
||||
SessionNotFound = Cannot find requested XEvent session
|
||||
SessionAlreadyExists(String sessionName) = An XEvent session named {0} already exists
|
||||
|
||||
#############################################################################
|
||||
# SQL Agent
|
||||
|
||||
@@ -3112,6 +3112,24 @@
|
||||
<note>.
|
||||
Parameters: 0 - error (String) </note>
|
||||
</trans-unit>
|
||||
<trans-unit id="CreateSessionFailed">
|
||||
<source>Failed to create session: {0}</source>
|
||||
<target state="new">Failed to create session: {0}</target>
|
||||
<note>.
|
||||
Parameters: 0 - error (String) </note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PauseSessionFailed">
|
||||
<source>Failed to pause session: {0}</source>
|
||||
<target state="new">Failed to pause session: {0}</target>
|
||||
<note>.
|
||||
Parameters: 0 - error (String) </note>
|
||||
</trans-unit>
|
||||
<trans-unit id="SessionAlreadyExists">
|
||||
<source>An XEvent session named {0} already exists</source>
|
||||
<target state="new">An XEvent session named {0} already exists</target>
|
||||
<note>.
|
||||
Parameters: 0 - sessionName (String) </note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Profiler.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Start Profiling request parameters
|
||||
/// </summary>
|
||||
public class CreateXEventSessionParams : GeneralRequestDetails
|
||||
{
|
||||
public string OwnerUri { get; set; }
|
||||
|
||||
public string SessionName { get; set; }
|
||||
|
||||
public ProfilerSessionTemplate Template { get; set; }
|
||||
}
|
||||
|
||||
public class CreateXEventSessionResult{}
|
||||
|
||||
/// <summary>
|
||||
/// Start Profile request type
|
||||
/// </summary>
|
||||
public class CreateXEventSessionRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Request definition
|
||||
/// </summary>
|
||||
public static readonly
|
||||
RequestType<CreateXEventSessionParams, CreateXEventSessionResult> Type =
|
||||
RequestType<CreateXEventSessionParams, CreateXEventSessionResult>.Create("profiler/createsession");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Profiler.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Start Profiling request parameters
|
||||
/// </summary>
|
||||
public class GetXEventSessionsParams : GeneralRequestDetails
|
||||
{
|
||||
public string OwnerUri { get; set; }
|
||||
}
|
||||
|
||||
public class GetXEventSessionsResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Session ID that was started
|
||||
/// </summary>
|
||||
public List<string> Sessions { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start Profile request type
|
||||
/// </summary>
|
||||
public class GetXEventSessionsRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Request definition
|
||||
/// </summary>
|
||||
public static readonly
|
||||
RequestType<GetXEventSessionsParams, GetXEventSessionsResult> Type =
|
||||
RequestType<GetXEventSessionsParams, GetXEventSessionsResult>.Create("profiler/getsessions");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Profiler.Contracts
|
||||
{
|
||||
public class ProfilerSessionCreatedParams
|
||||
{
|
||||
public string OwnerUri { get; set; }
|
||||
|
||||
public string SessionName { get; set; }
|
||||
|
||||
public string TemplateName { get; set; }
|
||||
}
|
||||
|
||||
public class ProfilerSessionCreatedNotification
|
||||
{
|
||||
public static readonly
|
||||
EventType<ProfilerSessionCreatedParams> Type =
|
||||
EventType<ProfilerSessionCreatedParams>.Create("profiler/sessioncreated");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Profiler.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// Class that contains data for a single profile event
|
||||
/// </summary>
|
||||
public class ProfilerSessionTemplate
|
||||
{
|
||||
/// <summary>
|
||||
/// Initialize a new ProfilerEvent with required parameters
|
||||
/// </summary>
|
||||
public ProfilerSessionTemplate(string name, string defaultView, string createStatement)
|
||||
{
|
||||
this.Name = name;
|
||||
this.DefaultView = defaultView;
|
||||
this.CreateStatement = createStatement;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Profiler event name
|
||||
/// </summary>
|
||||
public string Name { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Profiler event timestamp
|
||||
/// </summary>
|
||||
public string DefaultView { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Profiler event timestamp
|
||||
/// </summary>
|
||||
public string CreateStatement { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Equals method
|
||||
/// </summary>
|
||||
public bool Equals(ProfilerSessionTemplate t)
|
||||
{
|
||||
// if parameter is null return false:
|
||||
if ((object)t == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.Name == t.Name
|
||||
&& this.DefaultView == t.DefaultView
|
||||
&& this.CreateStatement == t.CreateStatement;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,30 +16,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler.Contracts
|
||||
{
|
||||
public string OwnerUri { get; set; }
|
||||
|
||||
public string TemplateName
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetOptionValue<string>("templateName");
|
||||
}
|
||||
set
|
||||
{
|
||||
SetOptionValue("templateName", value);
|
||||
}
|
||||
}
|
||||
public string SessionName { get; set; }
|
||||
}
|
||||
|
||||
public class StartProfilingResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Session ID that was started
|
||||
/// </summary>
|
||||
public string SessionId { get; set; }
|
||||
|
||||
public bool Succeeded { get; set; }
|
||||
|
||||
public string ErrorMessage { get; set; }
|
||||
}
|
||||
public class StartProfilingResult{}
|
||||
|
||||
/// <summary>
|
||||
/// Start Profile request type
|
||||
|
||||
@@ -16,8 +16,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
|
||||
public interface IXEventSessionFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or creates an XEvent session with the given template
|
||||
/// Gets an XEvent session with the given name
|
||||
/// </summary>
|
||||
IXEventSession GetOrCreateXEventSession(string template, ConnectionInfo connInfo);
|
||||
IXEventSession GetXEventSession(string sessionName, ConnectionInfo connInfo);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an XEvent session with the given create statement and name
|
||||
/// </summary>
|
||||
IXEventSession CreateXEventSession(string createStatement, string sessionName, ConnectionInfo connInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,13 +110,57 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
|
||||
public void InitializeService(ServiceHost serviceHost)
|
||||
{
|
||||
this.ServiceHost = serviceHost;
|
||||
this.ServiceHost.SetRequestHandler(CreateXEventSessionRequest.Type, HandleCreateXEventSessionRequest);
|
||||
this.ServiceHost.SetRequestHandler(StartProfilingRequest.Type, HandleStartProfilingRequest);
|
||||
this.ServiceHost.SetRequestHandler(StopProfilingRequest.Type, HandleStopProfilingRequest);
|
||||
this.ServiceHost.SetRequestHandler(PauseProfilingRequest.Type, HandlePauseProfilingRequest);
|
||||
this.ServiceHost.SetRequestHandler(GetXEventSessionsRequest.Type, HandleGetXEventSessionsRequest);
|
||||
|
||||
this.SessionMonitor.AddSessionListener(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle request to start a profiling session
|
||||
/// </summary>
|
||||
internal async Task HandleCreateXEventSessionRequest(CreateXEventSessionParams parameters, RequestContext<CreateXEventSessionResult> requestContext)
|
||||
{
|
||||
try
|
||||
{
|
||||
ConnectionInfo connInfo;
|
||||
ConnectionServiceInstance.TryFindConnection(
|
||||
parameters.OwnerUri,
|
||||
out connInfo);
|
||||
if (connInfo == null)
|
||||
{
|
||||
throw new Exception(SR.ProfilerConnectionNotFound);
|
||||
}
|
||||
else if (parameters.SessionName == null)
|
||||
{
|
||||
throw new ArgumentNullException("SessionName");
|
||||
}
|
||||
else if (parameters.Template == null)
|
||||
{
|
||||
throw new ArgumentNullException("Template");
|
||||
}
|
||||
else
|
||||
{
|
||||
// create a new XEvent session and Profiler session
|
||||
var xeSession = this.XEventSessionFactory.CreateXEventSession(parameters.Template.CreateStatement, parameters.SessionName, connInfo);
|
||||
// start monitoring the profiler session
|
||||
monitor.StartMonitoringSession(parameters.OwnerUri, xeSession);
|
||||
|
||||
var result = new CreateXEventSessionResult();
|
||||
await requestContext.SendResult(result);
|
||||
|
||||
SessionCreatedNotification(parameters.OwnerUri, parameters.SessionName, parameters.Template.Name);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await requestContext.SendError(new Exception(SR.CreateSessionFailed(e.Message)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle request to start a profiling session
|
||||
/// </summary>
|
||||
@@ -124,25 +168,24 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = new StartProfilingResult();
|
||||
ConnectionInfo connInfo;
|
||||
ConnectionServiceInstance.TryFindConnection(
|
||||
parameters.OwnerUri,
|
||||
out connInfo);
|
||||
|
||||
if (connInfo != null)
|
||||
{
|
||||
int xEventSessionId = StartSession(parameters.OwnerUri, parameters.TemplateName, connInfo);
|
||||
result.SessionId = xEventSessionId.ToString();
|
||||
result.Succeeded = true;
|
||||
// create a new XEvent session and Profiler session
|
||||
var xeSession = this.XEventSessionFactory.GetXEventSession(parameters.SessionName, connInfo);
|
||||
// start monitoring the profiler session
|
||||
monitor.StartMonitoringSession(parameters.OwnerUri, xeSession);
|
||||
|
||||
var result = new StartProfilingResult();
|
||||
await requestContext.SendResult(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Succeeded = false;
|
||||
result.ErrorMessage = SR.ProfilerConnectionNotFound;
|
||||
throw new Exception(SR.ProfilerConnectionNotFound);
|
||||
}
|
||||
|
||||
await requestContext.SendResult(result);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -160,13 +203,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
|
||||
ProfilerSession session;
|
||||
monitor.StopMonitoringSession(parameters.OwnerUri, out session);
|
||||
|
||||
if (session == null)
|
||||
if (session != null)
|
||||
{
|
||||
session.XEventSession.Stop();
|
||||
await requestContext.SendResult(new StopProfilingResult{});
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(SR.SessionNotFound);
|
||||
}
|
||||
|
||||
session.XEventSession.Stop();
|
||||
await requestContext.SendResult(new StopProfilingResult{});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -187,26 +232,58 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await requestContext.SendError(e);
|
||||
await requestContext.SendError(new Exception(SR.PauseSessionFailed(e.Message)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a new profiler session or connects to an existing session
|
||||
/// for the provided connection and template info
|
||||
/// Handle request to pause a profiling session
|
||||
/// </summary>
|
||||
internal async Task HandleGetXEventSessionsRequest(GetXEventSessionsParams parameters, RequestContext<GetXEventSessionsResult> requestContext)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = new GetXEventSessionsResult();
|
||||
ConnectionInfo connInfo;
|
||||
ConnectionServiceInstance.TryFindConnection(
|
||||
parameters.OwnerUri,
|
||||
out connInfo);
|
||||
if (connInfo == null)
|
||||
{
|
||||
await requestContext.SendError(new Exception(SR.ProfilerConnectionNotFound));
|
||||
}
|
||||
else
|
||||
{
|
||||
List<string> sessions = GetXEventSessionList(parameters.OwnerUri, connInfo);
|
||||
result.Sessions = sessions;
|
||||
await requestContext.SendResult(result);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await requestContext.SendError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of all running XEvent Sessions
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The XEvent Session Id that was started
|
||||
/// A list of the names of all running XEvent sessions
|
||||
/// </returns>
|
||||
internal int StartSession(string ownerUri, string template, ConnectionInfo connInfo)
|
||||
internal List<string> GetXEventSessionList(string ownerUri, ConnectionInfo connInfo)
|
||||
{
|
||||
// create a new XEvent session and Profiler session
|
||||
var xeSession = this.XEventSessionFactory.GetOrCreateXEventSession(template, connInfo);
|
||||
var sqlConnection = ConnectionService.OpenSqlConnection(connInfo);
|
||||
SqlStoreConnection connection = new SqlStoreConnection(sqlConnection);
|
||||
BaseXEStore store = CreateXEventStore(connInfo, connection);
|
||||
|
||||
// start monitoring the profiler session
|
||||
monitor.StartMonitoringSession(ownerUri, xeSession);
|
||||
// get session names from the session list
|
||||
List<string> results = store.Sessions.Aggregate(new List<string>(), (result, next) => {
|
||||
result.Add(next.Name);
|
||||
return result;
|
||||
} );
|
||||
|
||||
return xeSession.Id;
|
||||
return results;
|
||||
}
|
||||
|
||||
private static BaseXEStore CreateXEventStore(ConnectionInfo connInfo, SqlStoreConnection connection)
|
||||
@@ -228,13 +305,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or creates an XEvent session with the given template per the IXEventSessionFactory contract
|
||||
/// Gets an XEvent session with the given name per the IXEventSessionFactory contract
|
||||
/// Also starts the session if it isn't currently running
|
||||
/// </summary>
|
||||
public IXEventSession GetOrCreateXEventSession(string template, ConnectionInfo connInfo)
|
||||
public IXEventSession GetXEventSession(string sessionName, ConnectionInfo connInfo)
|
||||
{
|
||||
string sessionName = "Profiler";
|
||||
|
||||
var sqlConnection = ConnectionService.OpenSqlConnection(connInfo);
|
||||
SqlStoreConnection connection = new SqlStoreConnection(sqlConnection);
|
||||
BaseXEStore store = CreateXEventStore(connInfo, connection);
|
||||
@@ -243,7 +318,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
|
||||
// start the session if it isn't already running
|
||||
if (session == null)
|
||||
{
|
||||
session = CreateSession(connInfo, connection, sessionName);
|
||||
throw new Exception(SR.SessionNotFound);
|
||||
}
|
||||
|
||||
if (session != null && !session.IsRunning)
|
||||
@@ -258,60 +333,39 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
|
||||
};
|
||||
}
|
||||
|
||||
private static Session CreateSession(ConnectionInfo connInfo, SqlStoreConnection connection, string sessionName)
|
||||
{
|
||||
string createSessionSql =
|
||||
@"
|
||||
CREATE EVENT SESSION [Profiler] ON SERVER
|
||||
ADD EVENT sqlserver.attention(
|
||||
ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.database_id,sqlserver.nt_username,sqlserver.query_hash,sqlserver.server_principal_name,sqlserver.session_id)
|
||||
WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0)))),
|
||||
ADD EVENT sqlserver.existing_connection(SET collect_options_text=(1)
|
||||
ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.nt_username,sqlserver.server_principal_name,sqlserver.session_id)),
|
||||
ADD EVENT sqlserver.login(SET collect_options_text=(1)
|
||||
ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.nt_username,sqlserver.server_principal_name,sqlserver.session_id)),
|
||||
ADD EVENT sqlserver.logout(
|
||||
ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.nt_username,sqlserver.server_principal_name,sqlserver.session_id)),
|
||||
ADD EVENT sqlserver.rpc_completed(
|
||||
ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.database_id,sqlserver.nt_username,sqlserver.query_hash,sqlserver.server_principal_name,sqlserver.session_id)
|
||||
WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0)))),
|
||||
ADD EVENT sqlserver.sql_batch_completed(
|
||||
ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.database_id,sqlserver.nt_username,sqlserver.query_hash,sqlserver.server_principal_name,sqlserver.session_id)
|
||||
WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0)))),
|
||||
ADD EVENT sqlserver.sql_batch_starting(
|
||||
ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.database_id,sqlserver.nt_username,sqlserver.query_hash,sqlserver.server_principal_name,sqlserver.session_id)
|
||||
WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0))))
|
||||
ADD TARGET package0.ring_buffer(SET max_events_limit=(1000),max_memory=(51200))
|
||||
WITH (MAX_MEMORY=8192 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=5 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=PER_CPU,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)";
|
||||
|
||||
string createAzureSessionSql =
|
||||
@"
|
||||
CREATE EVENT SESSION [Profiler] ON DATABASE
|
||||
ADD EVENT sqlserver.attention(
|
||||
ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.database_id,sqlserver.username,sqlserver.query_hash,sqlserver.session_id)
|
||||
WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0)))),
|
||||
ADD EVENT sqlserver.existing_connection(SET collect_options_text=(1)
|
||||
ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.username,sqlserver.session_id)),
|
||||
ADD EVENT sqlserver.login(SET collect_options_text=(1)
|
||||
ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.username,sqlserver.session_id)),
|
||||
ADD EVENT sqlserver.logout(
|
||||
ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.username,sqlserver.session_id)),
|
||||
ADD EVENT sqlserver.rpc_completed(
|
||||
ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.database_id,sqlserver.username,sqlserver.query_hash,sqlserver.session_id)
|
||||
WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0)))),
|
||||
ADD EVENT sqlserver.sql_batch_completed(
|
||||
ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.database_id,sqlserver.username,sqlserver.query_hash,sqlserver.session_id)
|
||||
WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0)))),
|
||||
ADD EVENT sqlserver.sql_batch_starting(
|
||||
ACTION(package0.event_sequence,sqlserver.client_app_name,sqlserver.client_pid,sqlserver.database_id,sqlserver.username,sqlserver.query_hash,sqlserver.session_id)
|
||||
WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0))))
|
||||
ADD TARGET package0.ring_buffer(SET max_events_limit=(1000),max_memory=(51200))
|
||||
WITH (MAX_MEMORY=8192 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=5 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=PER_CPU,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)";
|
||||
|
||||
string createStatement = connInfo.IsCloud ? createAzureSessionSql : createSessionSql;
|
||||
connection.ServerConnection.ExecuteNonQuery(createStatement);
|
||||
/// <summary>
|
||||
/// Creates and starts an XEvent session with the given name and create statement per the IXEventSessionFactory contract
|
||||
/// </summary>
|
||||
public IXEventSession CreateXEventSession(string createStatement, string sessionName, ConnectionInfo connInfo)
|
||||
{
|
||||
var sqlConnection = ConnectionService.OpenSqlConnection(connInfo);
|
||||
SqlStoreConnection connection = new SqlStoreConnection(sqlConnection);
|
||||
BaseXEStore store = CreateXEventStore(connInfo, connection);
|
||||
return store.Sessions[sessionName];
|
||||
Session session = store.Sessions[sessionName];
|
||||
|
||||
// session shouldn't already exist
|
||||
if (session != null)
|
||||
{
|
||||
throw new Exception(SR.SessionAlreadyExists(sessionName));
|
||||
}
|
||||
|
||||
var statement = createStatement.Replace("{sessionName}",sessionName);
|
||||
connection.ServerConnection.ExecuteNonQuery(statement);
|
||||
store.Refresh();
|
||||
session = store.Sessions[sessionName];
|
||||
if (session == null){
|
||||
throw new Exception(SR.SessionNotFound);
|
||||
}
|
||||
if (!session.IsRunning)
|
||||
{
|
||||
session.Start();
|
||||
}
|
||||
|
||||
// create xevent session wrapper
|
||||
return new XEventSession()
|
||||
{
|
||||
Session = store.Sessions[sessionName]
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -345,6 +399,22 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback when a new session is created
|
||||
/// </summary>
|
||||
public void SessionCreatedNotification(string viewerId, string sessionName, string templateName)
|
||||
{
|
||||
// pass the profiler events on to the client
|
||||
this.ServiceHost.SendEvent(
|
||||
ProfilerSessionCreatedNotification.Type,
|
||||
new ProfilerSessionCreatedParams()
|
||||
{
|
||||
OwnerUri = viewerId,
|
||||
SessionName = sessionName,
|
||||
TemplateName = templateName
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the Profiler Service
|
||||
/// </summary>
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Profiler
|
||||
// start a new session
|
||||
var startParams = new StartProfilingParams();
|
||||
startParams.OwnerUri = connectionResult.ConnectionInfo.OwnerUri;
|
||||
startParams.TemplateName = "Standard";
|
||||
startParams.SessionName = "Standard";
|
||||
|
||||
string sessionId = null;
|
||||
var startContext = new Mock<RequestContext<StartProfilingResult>>();
|
||||
@@ -47,7 +47,6 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Profiler
|
||||
.Returns<StartProfilingResult>((result) =>
|
||||
{
|
||||
// capture the session id for sending the stop message
|
||||
sessionId = result.SessionId;
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
|
||||
@@ -82,7 +81,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Profiler
|
||||
{
|
||||
var liveConnection = LiveConnectionHelper.InitLiveConnectionInfo("master");
|
||||
ProfilerService profilerService = new ProfilerService();
|
||||
IXEventSession xeSession = profilerService.GetOrCreateXEventSession("Profiler", liveConnection.ConnectionInfo);
|
||||
IXEventSession xeSession = profilerService.GetXEventSession("Profiler", liveConnection.ConnectionInfo);
|
||||
Assert.NotNull(xeSession);
|
||||
Assert.NotNull(xeSession.GetTargetXml());
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Profiler
|
||||
.Returns<StartProfilingResult>((result) =>
|
||||
{
|
||||
// capture the session id for sending the stop message
|
||||
sessionId = result.SessionId;
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
|
||||
@@ -60,7 +59,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Profiler
|
||||
|
||||
var requestParams = new StartProfilingParams();
|
||||
requestParams.OwnerUri = testUri;
|
||||
requestParams.TemplateName = "Standard";
|
||||
requestParams.SessionName = "Standard";
|
||||
|
||||
// start profiling session
|
||||
await profilerService.HandleStartProfilingRequest(requestParams, requestContext.Object);
|
||||
|
||||
@@ -400,7 +400,21 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Profiler
|
||||
public class TestXEventSessionFactory : IXEventSessionFactory
|
||||
{
|
||||
private int sessionNum = 1;
|
||||
public IXEventSession GetOrCreateXEventSession(string template, ConnectionInfo connInfo)
|
||||
public IXEventSession GetXEventSession(string sessionName, ConnectionInfo connInfo)
|
||||
{
|
||||
if(sessionNum == 1)
|
||||
{
|
||||
sessionNum = 2;
|
||||
return new TestXEventSession1();
|
||||
}
|
||||
else
|
||||
{
|
||||
sessionNum = 1;
|
||||
return new TestXEventSession2();
|
||||
}
|
||||
}
|
||||
|
||||
public IXEventSession CreateXEventSession(string createStatement, string sessionName, ConnectionInfo connInfo)
|
||||
{
|
||||
if(sessionNum == 1)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user