Update to XElite (#1287)

* added Xevent.xelite to packages

* WIP on XELite conversion

* added wip changes

* added streaminfo class for preserving streams

* added list for profilerService

* added cancelXelStreamRequest.cs

* added test configuration for profilerservice

* added request handler using startprofilingrequest

* fix start profiling result

* added small connection string

* WIP branch for XElite (not functional)

* added hardcoded string with working stream

* added check for buildconnectionstring

* added back HandleXEvent

* added profilerservice eventsavailable test

* WIP change for profilersessionmonitor

* added more changes to profilersessionmonitor

* changed HandleXEvent

* added more additions to profielrSessionMonitor

* added startmonitoringstream

* added startmonitoringsession

* added startmonitoringstream to IProfilerSessionMonitor

* switch to monitoringStream

* added assignment of connectioninfo

* added conninfo

* added conninfo to iProfilerSessionMonitor.cs

* added isStreaming flag

* added token list

* added XEventSession name.

* removed polling lock

* test adding filters

* removed old profile filter as its incompatible

* added wip cancel feature in removesession

* moved cancellationtoken outside

* added backIsStreaming

* moved isstreaming around

* added  multiple events in list

* added timeout to handleXEvent

* removed timeout

* remove eventList count check

* remove old events filter

* returned eventlist

* remove old events filter

* renamed xelite handle function

* restored sqlclient version

* removed original handlestartprofilingrequest

* added monitoring stream to handlecreatexeventsessionrequest

* removed unnecessary sections from monitor

* Revert "removed unnecessary sections from monitor"

This reverts commit 91cadeebeeedfe99cec2e9c42944ba6716d95a61.

* added xevent actions to profileEvent

* removed polling lock for processStreams

* added filter for oldevents

* removed unused methods

* removed comment

* removed unnecessary class

* removed unnecessary requests

* removed outdated methods

* added work in progress cancellation task

* added profilersessionmonitor changes

* added small changes

* renamed startMonitoringStream

* more changes related to feedback

* made changes to code

* removed more polling code

* fixed tests

* added connectioninfo to testxeventsessions

* changed functions

* added back else

* small formatting fix

* more changes made

* added changes to XEventSession

* update to strings

* added changes to accomodate tests

* more changes

* added profilerservicetest for stopprofiling

* added TestStoppedSessionNotification test

* added session missing details handler

* simplified error message

* restored strings and added changes

* added auto-getter setter for IsStreaming

* added more changes

* removed unnecessary lines from test

* added more debugging messages

* made last changes

* added error message for handlestopprofilingrequest

* added more debug messages

* added back an s

* added verbose
This commit is contained in:
Alex Ma
2021-12-07 14:11:42 -08:00
committed by GitHub
parent faaf062f0f
commit 822a6459ce
15 changed files with 245 additions and 328 deletions

View File

@@ -18,6 +18,7 @@ using Microsoft.SqlServer.Management.Sdk.Sfc;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.XEvent;
using Microsoft.SqlServer.Management.XEventDbScoped;
using Microsoft.SqlServer.XEvent.XELite;
using Microsoft.SqlTools.Hosting.Protocol;
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
using Microsoft.SqlTools.ServiceLayer.Connection;
@@ -120,6 +121,42 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
this.SessionMonitor.AddSessionListener(this);
}
/// <summary>
/// Handle request to start a profiling session
/// </summary>
internal async Task HandleStartProfilingRequest(StartProfilingParams parameters, RequestContext<StartProfilingResult> requestContext)
{
await Task.Run(async () =>
{
try
{
Logger.Write(TraceEventType.Verbose, "HandleStartProfilingRequest started");
ConnectionInfo connInfo;
ConnectionServiceInstance.TryFindConnection(
parameters.OwnerUri,
out connInfo);
if (connInfo != null)
{
// create a new XEvent session and Profiler session
var xeSession = this.XEventSessionFactory.GetXEventSession(parameters.SessionName, connInfo);
monitor.StartMonitoringSession(parameters.OwnerUri, xeSession);
var result = new StartProfilingResult();
await requestContext.SendResult(result);
}
else
{
Logger.Write(TraceEventType.Error, "Connection Info could not be found for " + parameters.OwnerUri);
throw new Exception(SR.ProfilerConnectionNotFound);
}
}
catch (Exception e)
{
Logger.Write(TraceEventType.Error, "HandleStartProfilingRequest failed for uri " + parameters.OwnerUri);
await requestContext.SendError(new Exception (SR.StartProfilingFailed(e.Message), e));
}
});
}
/// <summary>
/// Handle request to start a profiling session
/// </summary>
@@ -129,20 +166,24 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
{
try
{
Logger.Write(TraceEventType.Verbose, "HandleCreateXEventSessionRequest started");
ConnectionInfo connInfo;
ConnectionServiceInstance.TryFindConnection(
parameters.OwnerUri,
out connInfo);
if (connInfo == null)
{
Logger.Write(TraceEventType.Error, "Connection Info could not be found for " + parameters.OwnerUri);
throw new Exception(SR.ProfilerConnectionNotFound);
}
else if (parameters.SessionName == null)
{
Logger.Write(TraceEventType.Error, "Session Name could not be found for " + parameters.OwnerUri);
throw new ArgumentNullException("SessionName");
}
else if (parameters.Template == null)
{
Logger.Write(TraceEventType.Error, "Template could not be found for " + parameters.OwnerUri);
throw new ArgumentNullException("Template");
}
else
@@ -156,10 +197,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
{
xeSession = this.XEventSessionFactory.GetXEventSession(parameters.SessionName, connInfo);
}
catch { }
catch {
Logger.Write(TraceEventType.Verbose, "Session with name '" + parameters.SessionName + "' was not found");
}
if (xeSession == null)
{
Logger.Write(TraceEventType.Verbose, "Creating new XEventSession with SessionName " + parameters.SessionName);
// create a new XEvent session and Profiler session
xeSession = this.XEventSessionFactory.CreateXEventSession(parameters.Template.CreateStatement, parameters.SessionName, connInfo);
}
@@ -175,42 +219,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
}
catch (Exception e)
{
await requestContext.SendError(new Exception(SR.CreateSessionFailed(e.Message)));
}
});
}
/// <summary>
/// Handle request to start a profiling session
/// </summary>
internal async Task HandleStartProfilingRequest(StartProfilingParams parameters, RequestContext<StartProfilingResult> requestContext)
{
await Task.Run(async () =>
{
try
{
ConnectionInfo connInfo;
ConnectionServiceInstance.TryFindConnection(
parameters.OwnerUri,
out connInfo);
if (connInfo != null)
{
// 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
{
throw new Exception(SR.ProfilerConnectionNotFound);
}
}
catch (Exception e)
{
await requestContext.SendError(new Exception(SR.StartSessionFailed(e.Message)));
Logger.Write(TraceEventType.Error, "HandleCreateXEventSessionRequest failed for uri " + parameters.OwnerUri);
await requestContext.SendError(new Exception (SR.CreateSessionFailed(e.Message), e));
}
});
}
@@ -224,6 +234,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
{
try
{
Logger.Write(TraceEventType.Verbose, "HandleStopProfilingRequest started");
ProfilerSession session;
monitor.StopMonitoringSession(parameters.OwnerUri, out session);
@@ -240,11 +251,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
await requestContext.SendResult(new StopProfilingResult { });
break;
}
catch (InvalidOperationException)
catch (InvalidOperationException e)
{
remainingAttempts--;
if (remainingAttempts == 0)
{
Logger.Write(TraceEventType.Error, "Stop profiler session '" + session.XEventSession.Session.Name + "' failed after three retries, last exception was: " + e.Message);
throw;
}
Thread.Sleep(500);
@@ -258,6 +270,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
}
catch (Exception e)
{
Logger.Write(TraceEventType.Error, "HandleStopProfilingRequest failed for uri " + parameters.OwnerUri);
await requestContext.SendError(new Exception(SR.StopSessionFailed(e.Message)));
}
});
@@ -272,12 +285,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
{
try
{
Logger.Write(TraceEventType.Verbose, "HandlePauseProfilingRequest started");
monitor.PauseViewer(parameters.OwnerUri);
await requestContext.SendResult(new PauseProfilingResult { });
}
catch (Exception e)
{
Logger.Write(TraceEventType.Error, "HandlePauseProfilingRequest failed for uri " + parameters.OwnerUri);
await requestContext.SendError(new Exception(SR.PauseSessionFailed(e.Message)));
}
});
@@ -292,6 +307,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
{
try
{
Logger.Write(TraceEventType.Verbose, "HandleGetXEventSessionsRequest started");
var result = new GetXEventSessionsResult();
ConnectionInfo connInfo;
ConnectionServiceInstance.TryFindConnection(
@@ -299,6 +315,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
out connInfo);
if (connInfo == null)
{
Logger.Write(TraceEventType.Error, "Connection Info could not be found for " + parameters.OwnerUri);
await requestContext.SendError(new Exception(SR.ProfilerConnectionNotFound));
}
else
@@ -310,6 +327,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
}
catch (Exception e)
{
Logger.Write(TraceEventType.Error, "HandleGetXEventSessionsRequest failed for uri " + parameters.OwnerUri);
await requestContext.SendError(e);
}
});
@@ -324,11 +342,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
{
try
{
Logger.Write(TraceEventType.Verbose, "HandleDisconnectSessionRequest started");
ProfilerSession session;
monitor.StopMonitoringSession(parameters.OwnerUri, out session);
}
catch (Exception e)
{
Logger.Write(TraceEventType.Error, "HandleDisconnectSessionRequest failed for uri " + parameters.OwnerUri);
await requestContext.SendError(e);
}
});
@@ -374,6 +394,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
return store;
}
/// <summary>
/// Nulls out properties in ConnectionDetails that aren't compatible with XElite.
/// </summary>
private static void RemoveIncompatibleConnectionProperties(ConnectionDetails connDetails){
connDetails.ConnectRetryCount = null;
connDetails.ConnectRetryInterval = null;
connDetails.MultiSubnetFailover = null;
}
/// <summary>
/// Gets an XEvent session with the given name per the IXEventSessionFactory contract
/// Also starts the session if it isn't currently running
@@ -383,6 +412,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
var sqlConnection = ConnectionService.OpenSqlConnection(connInfo);
SqlStoreConnection connection = new SqlStoreConnection(sqlConnection);
BaseXEStore store = CreateXEventStore(connInfo, connection);
RemoveIncompatibleConnectionProperties(connInfo.ConnectionDetails);
Session session = store.Sessions[sessionName];
// start the session if it isn't already running
@@ -399,6 +429,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler
// create xevent session wrapper
return new XEventSession()
{
ConnectionDetails = connInfo.ConnectionDetails,
Session = session
};
}