SqlClient のイベント カウンター
適用対象: .NET Framework .NET Core .NET Standard
重要
イベント カウンターは、 .NET Core 3.1 以降または .NET Standard 2.1 以降がターゲットのときに使用できます。 この機能は、Microsoft.Data.SqlClient
バージョン 3.0.0 以降で使用できます。
Microsoft.Data.SqlClient のイベント カウンターを使用すると、アプリケーションの状態とそこで使用されている接続リソースを監視できます。 イベント カウンターは、.NET CLI global tools
と perfView
によって監視したり、System.Diagnostics.Tracing 名前空間の EventListener クラスを使用してプログラムでアクセスしたりできます。
使用可能なイベント カウンター
次の表で説明されているように、現在、Microsoft.Data.SqlClient では 16 個の異なるイベント カウンターを使用できます。
名前 | Display name | 説明 |
---|---|---|
active-hard-connections | サーバーに対する現在の実際のアクティブな接続 | データベース サーバーに対して現在開かれている接続の数。 |
hard-connects | サーバーに対する実際の接続速度 | データベース サーバーに対して開かれている 1 秒あたりの接続の数。 |
hard-disconnects | サーバーからの実際の切断速度 | データベース サーバーに対して行われる 1 秒あたりの切断の数。 |
active-soft-connects | 接続プールから取得されたアクティブな接続 | 接続プールから消費される既に開かれている接続の数。 |
soft-connects | 接続プールから取得された接続の速度 | 接続プールから消費される 1 秒あたりの接続の数。 |
soft-disconnects | 接続プールに返される接続の速度 | 接続プールに返される 1 秒あたりの接続の数。 |
number-of-non-pooled-connections | 接続プーリングを使用しない接続の数 | プールされていないアクティブな接続の数。 |
number-of-pooled-connections | 接続プールによって管理されている接続の数 | 接続プール インフラストラクチャによって管理されているアクティブな接続の数。 |
number-of-active-connection-pool-groups | アクティブな一意の接続文字列の数 | アクティブな一意の接続プール グループの数。 このカウンターは、AppDomain に見つかった一意の接続文字列数によって制御されます。 |
number-of-inactive-connection-pool-groups | 切断待ちの一意な接続文字列の数 | 排除対象としてマークされた一意の接続プール グループの数。 このカウンターは、AppDomain に見つかった一意の接続文字列数によって制御されます。 |
number-of-active-connection-pools | アクティブな接続プールの数 | 接続プールの合計数。 |
number-of-inactive-connection-pools | 非アクティブな接続プールの数 | 最近のアクティビティが存在せず、破棄待ち状態となっている非アクティブな接続プールの数。 |
number-of-active-connections | アクティブな接続の数 | 現在使用中のアクティブな接続の数。 |
number-of-free-connections | 接続プール内の準備完了接続の数 | 接続プール内の開いている利用可能な接続の数。 |
number-of-stasis-connections | 現在準備完了待ち状態の接続の数 | 現在アクションの完了待ち状態で、アプリケーションで使用できない接続の数。 |
number-of-reclaimed-connections | GC から回収された接続の数 | アプリケーションによって Close または Dispose が呼び出されなかったガベージ コレクションによって回収された接続の数。 注 明示的に終了または破棄しないと、パフォーマンスに悪影響を及ぼします。 |
イベント カウンター値の取得
EventCounters を使用する場合、インプロセスとアウトプロセスという 2 つの主な方法があります。 詳細については、「EventCounters を使用する」を参照してください。
アウトプロセスで使用する
Windows では、PerfView と Xperf を使用して、イベント カウンター データを収集できます。 詳細については、「SqlClient でのイベントのトレースの有効化」を参照してください。 dotnet-counters と dotnet-trace を使用できます。これらは、イベント カウンター データを監視して収集するためのクロスプラットフォームの .NET ツールです。
アウトプロセスの例
次のコマンドを実行すると、SqlClient イベント カウンターの値が 1 秒に 1 回収集されます。 EventCounterIntervalSec=1
を大きい値に置き換えると、カウンター データの細分性が低下し、収集されるトレースが小さくなります。
PerfView /onlyProviders=*Microsoft.Data.SqlClient.EventSource:EventCounterIntervalSec=1 run "<application-Path>"
次のコマンドを使用すると、SqlClient イベント カウンターの値が 1 秒に 1 回収集されます。
dotnet-trace collect --process-id <pid> --providers Microsoft.Data.SqlClient.EventSource:0:1:EventCounterIntervalSec=1
次のコマンドを使用すると、SqlClient イベント カウンターの値が 3 秒ごとに 1 回監視されます。
dotnet-counters monitor Microsoft.Data.SqlClient.EventSource -p <process-id> --refresh-interval 3
次のコマンドを使用すると、選択した SqlClient イベント カウンターの値が 1 秒ごとに 1 回監視されます。
dotnet-counters monitor Microsoft.Data.SqlClient.EventSource[hard-connects,hard-disconnects] -p <process-id>
インプロセスで使用する
カウンター値は、、EventListener API で使用できます。 EventListener
は、アプリケーション内の EventSource のインスタンスによって書き込まれたイベントを使用するインプロセスの方法です。 詳細については、EventListener に関する記事を参照してください。
インプロセスの例
次のサンプル コードでは、EventCounterIntervalSec=1
を使用して Microsoft.Data.SqlClient.EventSource
イベントをキャプチャします。 イベント カウンターの更新ごとに、カウンター名とその Mean
値が書き込まれます。
Note
このイベントを有効にする場合は、EventCounterIntervalSec
プロパティ値を指定する必要があります。
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Linq;
// This listener class will listen for events from the SqlClientEventSource class.
// SqlClientEventSource is an implementation of the EventSource class which gives
// it the ability to create events.
public class EventCounterListener : EventListener
{
protected override void OnEventSourceCreated(EventSource eventSource)
{
// Only enable events from SqlClientEventSource.
if (eventSource.Name.Equals("Microsoft.Data.SqlClient.EventSource"))
{
var options = new Dictionary<string, string>();
// define time interval 1 second
// without defining this parameter event counters will not enabled
options.Add("EventCounterIntervalSec", "1");
// enable for the None keyword
EnableEvents(eventSource, EventLevel.Informational, EventKeywords.None, options);
}
}
// This callback runs whenever an event is written by SqlClientEventSource.
// Event data is accessed through the EventWrittenEventArgs parameter.
protected override void OnEventWritten(EventWrittenEventArgs eventData)
{
if (eventData.Payload.FirstOrDefault(p => p is IDictionary<string, object> x && x.ContainsKey("Name")) is IDictionary<string, object> counters)
{
if (counters.TryGetValue("DisplayName", out object name) && name is string cntName
&& counters.TryGetValue("Mean", out object value) && value is double cntValue)
{
// print event counter's name and mean value
Console.WriteLine($"{cntName}\t\t{cntValue}");
}
}
}
}
class Program
{
static void Main(string[] args)
{
// Create a new event listener
using (var listener = new EventCounterListener())
{
string connectionString = "Data Source=localhost; Integrated Security=true";
for (int i = 0; i < 50; i++)
{
// Open a connection
SqlConnection cnn = new SqlConnection(connectionString);
cnn.Open();
// wait for sampling interval happens
System.Threading.Thread.Sleep(500);
}
}
}
}
Actual active connections currently made to servers 0
Active connections retrieved from the connection pool 26
Number of connections not using connection pooling 0
Number of connections managed by the connection pool 26
Number of active unique connection strings 1
Number of unique connection strings waiting for pruning 0
Number of active connection pools 1
Number of inactive connection pools 0
Number of active connections 26
Number of ready connections in the connection pool 0
Number of connections currently waiting to be ready 0
...