SqlClient의 이벤트 카운터
적용 대상: .NET Framework .NET Core .NET Standard
Important
이벤트 카운터는 .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가지가 있습니다.
속성 | 표시 이름 | 설명 |
---|---|---|
active-hard-connections | 현재 서버에 대해 설정된 실제 활성 연결 | 데이터베이스 서버에 현재 열려 있는 연결 수입니다. |
hard-connects | 서버에 대한 실제 연결 비율 | 데이터베이스 서버에 대해 열려 있는 초당 연결 수입니다. |
hard-disconnects | 서버의 실제 연결 끊김 속도 | 데이터베이스 서버에 대해 이루어지는 초당 연결 끊김 수입니다. |
active-soft-connects | 연결 풀에서 검색된 실제 연결 | 연결 풀에서 사용 중인 이미 열린 연결 수입니다. |
soft-connects | 연결 풀에서 검색된 연결 비율 | 연결 풀에서 사용 중인 초당 연결 수입니다. |
soft-disconnects | 연결 풀으로 반환된 연결 비율 | 연결 풀에 반환 중인 초당 연결 수입니다. |
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를 사용하는 두 가지 기본 방법은 in-proc 또는 out-of-proc입니다. 자세한 내용은 EventCounter 사용을 참조하세요.
out-of-proc 사용
Windows에서 PerfView 및 Xperf를 사용하여 이벤트 카운터 데이터를 수집할 수 있습니다. 자세한 내용은 SqlClient에서 이벤트 추적 사용을 참조하세요. 플랫폼 간 .NET 도구인 dotnet-counters 및 dotnet-trace를 사용하여 이벤트 카운터 데이터를 모니터링하고 수집할 수 있습니다.
Out-of-proc 예
다음 명령은 1초마다 한 번씩 SqlClient 이벤트 카운터 값을 실행하고 수집합니다. EventCounterIntervalSec=1
을 더 높은 값으로 바꾸면 카운터 데이터의 세분성이 떨어지는 대신 더 작은 추적을 수집할 수 있습니다.
PerfView /onlyProviders=*Microsoft.Data.SqlClient.EventSource:EventCounterIntervalSec=1 run "<application-Path>"
다음 명령은 1초마다 한 번씩 SqlClient 이벤트 카운터 값을 수집합니다.
dotnet-trace collect --process-id <pid> --providers Microsoft.Data.SqlClient.EventSource:0:1:EventCounterIntervalSec=1
다음 명령은 3초마다 한 번씩 SqlClient 이벤트 카운터 값을 모니터링합니다.
dotnet-counters monitor Microsoft.Data.SqlClient.EventSource -p <process-id> --refresh-interval 3
다음 명령은 1초마다 한 번씩 선택한 SqlClient 이벤트 카운터 값을 모니터링합니다.
dotnet-counters monitor Microsoft.Data.SqlClient.EventSource[hard-connects,hard-disconnects] -p <process-id>
In-proc에서 사용
EventListener API를 통해 카운터 값을 사용할 수 있습니다. EventListener
는 애플리케이션의 EventSource 인스턴스에 의해 기록된 이벤트를 사용하는 in-process 방법입니다. 자세한 내용은 EventListener를 참조하세요.
In-proc 예
다음 샘플 코드는 EventCounterIntervalSec=1
을 사용하여 Microsoft.Data.SqlClient.EventSource
이벤트를 캡처합니다. 각 이벤트 카운터 업데이트에 카운터 이름과 해당 Mean
값을 씁니다.
참고 항목
이 이벤트를 사용하는 경우 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
...