System.Data.SqlClient のイベントトレースについては BID (Built-In Diagnostics) トレースで実装されていたため、BID トレースの設定を有効化する必要があったかと思います。
BID トレースについては次のドキュメントで解説が行われています。
- HowTo: BID トレース – データアクセス アプリケーションのトレースを採取する
- Data Access Tracing in SQL Server 2008
- Data Access Tracing (Legacy)
最新の SQL Server のデータプロバイダーである、Microsoft.Data.SqlClient では、イベントトレースの取得方法が BID から、EventSoure からのイベントの取得に変わっているようです。
有効化の方法については、SqlClient でのイベントのトレースの有効化 で記載されていますが、C# であれば、ドキュメントに記載されている方法でトレースを取得することができます。
PowerShell (7.0.2) で Microsoft.Data.SqlClient 2.0 を使用する の Windows PowerShell についての記述を追加していて、PowerShell で Microsoft.Data.SqlClient を実行した場合にもトレースが取得できるのかが気になったので試してみました。
今回、コネクションプールの調査でイベントトレースを使用していたのですが、System.Data と Microsoft.Data のイベントトレースの出力の違いについては、次のソースを確認してみても良いのではないでしょうか。
- SqlClient/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/ProviderBase/DbConnectionPool.cs
- referencesource/System.Data/System/Data/ProviderBase/DbConnectionPool.cs
PowerShell で Microsoft.Data.SqlClient のトレースを取得する
PowerShell は 5.0 以降でクラスをサポートしていますので、SqlClient でのイベントのトレースの有効化 の C# のコードを参考にしながら PowerShell でスクリプトを作成してみます。
using namespace System.Diagnostics.Tracing; $ErrorActionPreference = "Stop" class SqlClientListener : EventListener { [void]OnEventSourceCreated([EventSource]$eventSource){ if($eventSource.Name -eq "Microsoft.Data.SqlClient.EventSource"){ $this.EnableEvents($eventSource, [EventLevel]::Verbose, [EventKeywords](32+64)) } } [void]OnEventWritten([EventWrittenEventArgs]$eventData){ Write-Host ("{0} : {1}" -f (Get-Date), $eventData.Payload[0]) } } Add-type -Path "C:\SqlClient\microsoft.identity.client.4.21.1.nupkg\lib\net461\Microsoft.Identity.Client.dll" Add-Type -Path "C:\SqlClient\microsoft.data.sqlclient.2.1.2.nupkg\runtimes\win\lib\net46\Microsoft.Data.SqlClient.dll" $listner = New-Object SqlClientListener try{ $conString = "xxxxxxxxxxxxxxxxx" $con = New-Object Microsoft.Data.SqlClient.SqlConnection($conString) Write-Host "===== Open Connection #1 =========" $con.Open() $cmd = $con.CreateCommand() $cmd.CommandText = "SELECT @@servername" $cmd.ExecuteScalar() Write-Host "===== Close Connection #1 =========" $con.Close() }catch{ Write-Host $_.Exception.Message }finally{ $con.Dispose() $listner.Dispose() }
$conString については、適切な接続文字列を指定し、Add-Type で読み込んでいる DLL については、適切な場所にダウンロードしたものを使用します。
今回は、コネクションプールの情報を取得するようにしていますので、EventKeywords については、PoolerTrace / PoolerScope を有効にしています。
スクリプトを実行すると、初回実行時には次のような出力を取得することができます。
コネクションプールを使用した場合、初回の接続時には、プール内に利用可能な接続がありませんので、接続を作成し、クローズしたタイミングで、プールに接続を Push していることが確認できますね。
2 回目の実行で、コネクションプール内に利用可能な接続がプールされている場合は、次のような実行結果となります。
初回実行時と異なり、「Creating new Connection」を実行せずに「Popped from general pool」で、プール内から接続を取得していることが確認できます。
イベントトレースを使用すると、コネクションプール内の接続が、SQL Server から切断されている場合に、どのようにな動作になっているのかを確認することもできます。(プールから切断されている接続を削除して再度作成するという動作が行われていることがトレースから確認できます)
ADO.NET のコネクションプール (接続プール) については、SQL Server の接続プール (ADO.NET) で解説が行われていますが、イベントトレースの情報とコネクションプールの情報を組み合わせると、プールの動作を理解する一助になるのではないでしょうか。