-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,10 +12,19 @@ internal static class SqlClientDiagnosticListenerExtensions | |
public const string DiagnosticListenerName = "SqlClientDiagnosticListener"; | ||
|
||
private const string SqlClientPrefix = "System.Data.SqlClient."; | ||
|
||
public const string SqlBeforeExecuteCommand = SqlClientPrefix + nameof(WriteCommandBefore); | ||
public const string SqlAfterExecuteCommand = SqlClientPrefix + nameof(WriteCommandAfter); | ||
public const string SqlErrorExecuteCommand = SqlClientPrefix + nameof(WriteCommandError); | ||
|
||
public const string SqlBeforeOpenConnection = SqlClientPrefix + nameof(WriteConnectionOpenBefore); | ||
public const string SqlAfterOpenConnection = SqlClientPrefix + nameof(WriteConnectionOpenAfter); | ||
public const string SqlErrorOpenConnection = SqlClientPrefix + nameof(WriteConnectionOpenError); | ||
|
||
public const string SqlBeforeCloseConnection = SqlClientPrefix + nameof(WriteConnectionCloseBefore); | ||
public const string SqlAfterCloseConnection = SqlClientPrefix + nameof(WriteConnectionCloseAfter); | ||
public const string SqlErrorCloseConnection = SqlClientPrefix + nameof(WriteConnectionCloseError); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
trstringer
Author
Owner
|
||
|
||
public static Guid WriteCommandBefore(this DiagnosticListener @this, SqlCommand sqlCommand, [CallerMemberName] string operation = "") | ||
{ | ||
if (@this.IsEnabled(SqlBeforeExecuteCommand)) | ||
|
@@ -28,6 +37,7 @@ public static Guid WriteCommandBefore(this DiagnosticListener @this, SqlCommand | |
{ | ||
OperationId = operationId, | ||
Operation = operation, | ||
ConnectionId = sqlCommand.Connection.ClientConnectionId, | ||
This comment has been minimized.
Sorry, something went wrong. |
||
Command = sqlCommand | ||
}); | ||
|
||
|
@@ -47,6 +57,7 @@ public static void WriteCommandAfter(this DiagnosticListener @this, Guid operati | |
{ | ||
OperationId = operationId, | ||
Operation = operation, | ||
ConnectionId = sqlCommand.Connection.ClientConnectionId, | ||
Command = sqlCommand, | ||
Statistics = sqlCommand.Statistics?.GetDictionary(), | ||
Timestamp = Stopwatch.GetTimestamp() | ||
|
@@ -64,11 +75,130 @@ public static void WriteCommandError(this DiagnosticListener @this, Guid operati | |
{ | ||
OperationId = operationId, | ||
Operation = operation, | ||
ConnectionId = sqlCommand.Connection.ClientConnectionId, | ||
Command = sqlCommand, | ||
Exception = ex, | ||
Timestamp = Stopwatch.GetTimestamp() | ||
}); | ||
} | ||
} | ||
|
||
public static Guid WriteConnectionOpenBefore(this DiagnosticListener @this, SqlConnection sqlConnection, [CallerMemberName] string operation = "") | ||
{ | ||
if (@this.IsEnabled(SqlBeforeOpenConnection)) | ||
{ | ||
Guid operationId = Guid.NewGuid(); | ||
|
||
@this.Write( | ||
SqlBeforeOpenConnection, | ||
new | ||
{ | ||
OperationId = operationId, | ||
Operation = operation, | ||
Connection = sqlConnection, | ||
Timestamp = Stopwatch.GetTimestamp() | ||
}); | ||
|
||
return operationId; | ||
} | ||
else | ||
return Guid.Empty; | ||
} | ||
|
||
public static void WriteConnectionOpenAfter(this DiagnosticListener @this, Guid operationId, SqlConnection sqlConnection, [CallerMemberName] string operation = "") | ||
{ | ||
if (@this.IsEnabled(SqlAfterOpenConnection)) | ||
{ | ||
@this.Write( | ||
SqlAfterOpenConnection, | ||
new | ||
{ | ||
OperationId = operationId, | ||
Operation = operation, | ||
ConnectionId = sqlConnection.ClientConnectionId, | ||
Connection = sqlConnection, | ||
Statistics = sqlConnection.Statistics?.GetDictionary(), | ||
Timestamp = Stopwatch.GetTimestamp() | ||
}); | ||
} | ||
} | ||
|
||
public static void WriteConnectionOpenError(this DiagnosticListener @this, Guid operationId, SqlConnection sqlConnection, Exception ex, [CallerMemberName] string operation = "") | ||
{ | ||
if (@this.IsEnabled(SqlErrorOpenConnection)) | ||
{ | ||
@this.Write( | ||
SqlErrorOpenConnection, | ||
new | ||
{ | ||
OperationId = operationId, | ||
Operation = operation, | ||
ConnectionId = sqlConnection.ClientConnectionId, | ||
Connection = sqlConnection, | ||
Exception = ex, | ||
Timestamp = Stopwatch.GetTimestamp() | ||
}); | ||
} | ||
} | ||
|
||
public static Guid WriteConnectionCloseBefore(this DiagnosticListener @this, SqlConnection sqlConnection, [CallerMemberName] string operation = "") | ||
{ | ||
if (@this.IsEnabled(SqlBeforeCloseConnection)) | ||
{ | ||
Guid operationId = Guid.NewGuid(); | ||
|
||
@this.Write( | ||
SqlBeforeCloseConnection, | ||
new | ||
{ | ||
OperationId = operationId, | ||
Operation = operation, | ||
ConnectionId = sqlConnection.ClientConnectionId, | ||
Connection = sqlConnection, | ||
Statistics = sqlConnection.Statistics?.GetDictionary(), | ||
Timestamp = Stopwatch.GetTimestamp() | ||
}); | ||
|
||
return operationId; | ||
} | ||
else | ||
return Guid.Empty; | ||
} | ||
|
||
public static void WriteConnectionCloseAfter(this DiagnosticListener @this, Guid operationId, Guid clientConnectionId, SqlConnection sqlConnection, [CallerMemberName] string operation = "") | ||
{ | ||
if (@this.IsEnabled(SqlAfterCloseConnection)) | ||
{ | ||
@this.Write( | ||
SqlAfterCloseConnection, | ||
new | ||
{ | ||
OperationId = operationId, | ||
Operation = operation, | ||
ConnectionId = clientConnectionId, | ||
Connection = sqlConnection, | ||
Statistics = sqlConnection.Statistics?.GetDictionary(), | ||
This comment has been minimized.
Sorry, something went wrong.
trstringer
Author
Owner
|
||
Timestamp = Stopwatch.GetTimestamp() | ||
}); | ||
} | ||
} | ||
|
||
public static void WriteConnectionCloseError(this DiagnosticListener @this, Guid operationId, Guid clientConnectionId, SqlConnection sqlConnection, Exception ex, [CallerMemberName] string operation = "") | ||
{ | ||
if (@this.IsEnabled(SqlErrorCloseConnection)) | ||
{ | ||
@this.Write( | ||
SqlErrorCloseConnection, | ||
new | ||
{ | ||
OperationId = operationId, | ||
Operation = operation, | ||
ConnectionId = clientConnectionId, | ||
Connection = sqlConnection, | ||
Exception = ex, | ||
Timestamp = Stopwatch.GetTimestamp() | ||
}); | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -462,8 +462,28 @@ private void CloseInnerConnection() | |
|
||
override public void Close() | ||
{ | ||
ConnectionState previousState = State; | ||
Guid operationId; | ||
Guid clientConnectionId; | ||
|
||
// during the call to Dispose() there is a redundant call to | ||
// Close(). because of this, the second time Close() is invoked the | ||
// connection is already in a closed state. this doesn't seem to be a | ||
// problem except for logging, as we'll get duplicate Before/After/Error | ||
// log entries | ||
if (previousState == ConnectionState.Open) | ||
{ | ||
operationId = s_diagnosticListener.WriteConnectionCloseBefore(this); | ||
// we want to cache the ClientConnectionId for After/Error logging, as when the connection | ||
// is closed then we will lose this identifier | ||
// | ||
// note: caching this is only for diagnostics logging purposes | ||
clientConnectionId = ClientConnectionId; | ||
} | ||
|
||
SqlStatistics statistics = null; | ||
|
||
Exception e = null; | ||
try | ||
{ | ||
statistics = SqlStatistics.StartTimer(Statistics); | ||
|
@@ -491,9 +511,28 @@ override public void Close() | |
ADP.TimerCurrent(out _statistics._closeTimestamp); | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
e = ex; | ||
throw; | ||
} | ||
finally | ||
{ | ||
SqlStatistics.StopTimer(statistics); | ||
This comment has been minimized.
Sorry, something went wrong.
avanderhoorn
|
||
|
||
// we only want to log this even if the previous state of the | ||
This comment has been minimized.
Sorry, something went wrong. |
||
// connection is open, as that's the valid use-case | ||
if (previousState == ConnectionState.Open) | ||
{ | ||
if (e != null) | ||
{ | ||
s_diagnosticListener.WriteConnectionCloseError(operationId, clientConnectionId, this, e); | ||
} | ||
else | ||
{ | ||
s_diagnosticListener.WriteConnectionCloseAfter(operationId, clientConnectionId, this); | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
@@ -524,9 +563,13 @@ private void DisposeMe(bool disposing) | |
|
||
override public void Open() | ||
{ | ||
Guid operationId = s_diagnosticListener.WriteConnectionOpenBefore(this); | ||
|
||
PrepareStatisticsForNewConnection(); | ||
|
||
SqlStatistics statistics = null; | ||
|
||
Exception e = null; | ||
try | ||
{ | ||
statistics = SqlStatistics.StartTimer(Statistics); | ||
|
@@ -536,9 +579,23 @@ override public void Open() | |
throw ADP.InternalError(ADP.InternalErrorCode.SynchronousConnectReturnedPending); | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
e = ex; | ||
throw; | ||
} | ||
finally | ||
{ | ||
SqlStatistics.StopTimer(statistics); | ||
|
||
if (e != null) | ||
{ | ||
s_diagnosticListener.WriteConnectionOpenError(operationId, this, e); | ||
} | ||
else | ||
{ | ||
s_diagnosticListener.WriteConnectionOpenAfter(operationId, this); | ||
} | ||
} | ||
} | ||
This comment has been minimized.
Sorry, something went wrong.
avanderhoorn
|
||
|
||
|
Wasn't there some discussion before of using an attribute for the caller name? Did that end up not working this scenario?