Skip to content

Commit 237dc95

Browse files
committed
- Setting XEvent session duration for Azure SQL and SQL Server 2025+.
1 parent c6792c5 commit 237dc95

File tree

1 file changed

+74
-42
lines changed

1 file changed

+74
-42
lines changed

src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs

Lines changed: 74 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,15 +1257,40 @@ protected virtual void OnMatchingEventWritten(EventWrittenEventArgs eventData)
12571257

12581258
public readonly ref struct XEventScope : IDisposable
12591259
{
1260-
private const int MaxXEventsLatencyS = 5;
1260+
# region Private Fields
12611261

1262+
// Maximum dispatch latency for XEvents, in seconds.
1263+
private const int MaxDispatchLatencySeconds = 5;
1264+
1265+
// The connection to use for all operations.
12621266
private readonly SqlConnection _connection;
1263-
private readonly ushort _durationInMinutes;
1267+
1268+
// True if connected to an Azure SQL instance.
12641269
private readonly bool _isAzureSql;
1270+
1271+
// True if connected to a non-Azure SQL Server version 17 or higher.
12651272
private readonly bool _isVersion17OrHigher;
12661273

1274+
// Duration for the XEvent session, in minutes.
1275+
private readonly ushort _durationInMinutes;
1276+
1277+
# endregion
1278+
1279+
# region Properties
1280+
1281+
// The name of the XEvent session, derived from the session name
1282+
// provided at construction time, with a unique suffix appended.
12671283
public string SessionName { get; }
12681284

1285+
#endregion
1286+
1287+
#region Construction
1288+
1289+
// Construct with the specified parameters.
1290+
//
1291+
// This will use the connection to query the server properties and
1292+
// setup and start the XEvent session.
1293+
//
12691294
public XEventScope(
12701295
string sessionName,
12711296
// The connection must already be open.
@@ -1284,13 +1309,56 @@ public XEventScope(
12841309
// SQL Azure only supports database-scoped XEvent sessions
12851310
_isAzureSql = GetSqlServerProperty(connection, ServerProperty.EngineEdition) == "5";
12861311
_isVersion17OrHigher = int.Parse(GetSqlServerProperty(connection, ServerProperty.ProductMajorVersion)) >= 17;
1312+
1313+
// Setup and start the XEvent session.
1314+
string sessionLocation = _isAzureSql ? "DATABASE" : "SERVER";
12871315

1288-
SetupXEvent(eventSpecification, targetSpecification);
1316+
// Both Azure SQL and SQL Server 2025 (v17.x) and higher support
1317+
// setting a maximum duration for the XEvent session.
1318+
string duration =
1319+
_isAzureSql || _isVersion17OrHigher
1320+
? $"MAX_DURATION={_durationInMinutes} MINUTES,"
1321+
: string.Empty;
1322+
1323+
string xEventCreateAndStartCommandText =
1324+
$@"CREATE EVENT SESSION [{SessionName}] ON {sessionLocation}
1325+
{eventSpecification}
1326+
{targetSpecification}
1327+
WITH (
1328+
{duration}
1329+
MAX_MEMORY=16 MB,
1330+
EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,
1331+
MAX_DISPATCH_LATENCY={MaxDispatchLatencySeconds} SECONDS,
1332+
MAX_EVENT_SIZE=0 KB,
1333+
MEMORY_PARTITION_MODE=NONE,
1334+
TRACK_CAUSALITY=ON,
1335+
STARTUP_STATE=OFF)
1336+
1337+
ALTER EVENT SESSION [{SessionName}] ON {sessionLocation} STATE = START ";
1338+
1339+
using SqlCommand createXEventSession = new SqlCommand(xEventCreateAndStartCommandText, _connection);
1340+
createXEventSession.ExecuteNonQuery();
12891341
}
12901342

1343+
// Disposal stops and drops the XEvent session.
12911344
public void Dispose()
1292-
=> DropXEvent();
1345+
{
1346+
string dropXEventSessionCommand = _isAzureSql
1347+
? $"IF EXISTS (select * from sys.dm_xe_database_sessions where name ='{SessionName}')" +
1348+
$" DROP EVENT SESSION [{SessionName}] ON DATABASE"
1349+
: $"IF EXISTS (select * from sys.dm_xe_sessions where name ='{SessionName}')" +
1350+
$" DROP EVENT SESSION [{SessionName}] ON SERVER";
1351+
1352+
using SqlCommand command = new SqlCommand(dropXEventSessionCommand, _connection);
1353+
command.ExecuteNonQuery();
1354+
}
1355+
1356+
#endregion
12931357

1358+
#region Public Methods
1359+
1360+
// Query the XEvent session for its collected events, returning them
1361+
// as an XML document.
12941362
public System.Xml.XmlDocument GetEvents()
12951363
{
12961364
string xEventQuery = _isAzureSql
@@ -1307,7 +1375,7 @@ INNER JOIN sys.dm_xe_sessions AS xe
13071375

13081376
using SqlCommand command = new SqlCommand(xEventQuery, _connection);
13091377

1310-
Thread.Sleep(MaxXEventsLatencyS * 1000);
1378+
Thread.Sleep(MaxDispatchLatencySeconds * 1000);
13111379

13121380
string? targetData = command.ExecuteScalar() as string;
13131381
Assert.NotNull(targetData);
@@ -1318,43 +1386,7 @@ INNER JOIN sys.dm_xe_sessions AS xe
13181386
return xmlDocument;
13191387
}
13201388

1321-
private void SetupXEvent(string eventSpecification, string targetSpecification)
1322-
{
1323-
string sessionLocation = _isAzureSql ? "DATABASE" : "SERVER";
1324-
1325-
// TODO: Does Azure SQL support setting duration as well?
1326-
string duration = _isVersion17OrHigher ? $"MAX_DURATION={_durationInMinutes} MINUTES," : string.Empty;
1327-
1328-
string xEventCreateAndStartCommandText = $@"CREATE EVENT SESSION [{SessionName}] ON {sessionLocation}
1329-
{eventSpecification}
1330-
{targetSpecification}
1331-
WITH (
1332-
{duration}
1333-
MAX_MEMORY=16 MB,
1334-
EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,
1335-
MAX_DISPATCH_LATENCY={MaxXEventsLatencyS} SECONDS,
1336-
MAX_EVENT_SIZE=0 KB,
1337-
MEMORY_PARTITION_MODE=NONE,
1338-
TRACK_CAUSALITY=ON,
1339-
STARTUP_STATE=OFF)
1340-
1341-
ALTER EVENT SESSION [{SessionName}] ON {sessionLocation} STATE = START ";
1342-
1343-
using SqlCommand createXEventSession = new SqlCommand(xEventCreateAndStartCommandText, _connection);
1344-
createXEventSession.ExecuteNonQuery();
1345-
}
1346-
1347-
private void DropXEvent()
1348-
{
1349-
string dropXEventSessionCommand = _isAzureSql
1350-
? $"IF EXISTS (select * from sys.dm_xe_database_sessions where name ='{SessionName}')" +
1351-
$" DROP EVENT SESSION [{SessionName}] ON DATABASE"
1352-
: $"IF EXISTS (select * from sys.dm_xe_sessions where name ='{SessionName}')" +
1353-
$" DROP EVENT SESSION [{SessionName}] ON SERVER";
1354-
1355-
using SqlCommand command = new SqlCommand(dropXEventSessionCommand, _connection);
1356-
command.ExecuteNonQuery();
1357-
}
1389+
#endregion
13581390
}
13591391

13601392
/// <summary>

0 commit comments

Comments
 (0)