New Relic의 .NET 에이전트는 에이전트 버전 6.0 부터 비동기 프레임워크 계측을 자동으로 포함합니다. .NET 4.5에 도입된 표준 async-await
패턴을 사용하면 호출된 메서드에서 수행 중인 작업이 아직 진행 중인 경우에도 비동기 메서드에 대한 호출이 반환될 수 있습니다. .NET 에이전트는 진행 중인 이 비동기 작업을 관찰하고 타이밍을 기록하기 전에 완료될 때까지 기다립니다.
비동기 계측을 지원하는 기능
비동기 지원이 추가되어 .NET 에이전트에서 추가 기능을 사용할 수 있습니다. 그러나 이 개선 사항의 일부로 에이전트가 이전에 제공한 일부 기능을 현재 사용할 수 없습니다. 명시된 경우를 제외하고 에이전트는 .NET 에이전트에 대해 지원되는 다른 프레임워크 에 대해 비동기 메서드를 계측하지 않습니다.
에이전트는 다음 HttpClient
비동기 메서드를 계측합니다.
SendAsync
GetAsync
PostAsync
PutAsync
DeleteAsync
GetStringAsync
GetStreamAsync
GetByteArrayAsync
에이전트는 다음 RestClient
비동기 메서드를 계측합니다.
ExecuteTaskAsync
ExecuteGetTaskAsync
ExecutePostTaskAsync
에이전트는 다음 SqlCommand
비동기 메서드를 계측합니다.
ExecuteReaderAsync
ExecuteNonQueryAsync
ExecuteScalarAsync
ExecuteXmlReaderAsync
에이전트는 다음 SqlDataReader
비동기 메서드를 계측합니다.
NextResultAsync
ReadAsync
에이전트는 다음 NpgsqlCommand
비동기 메서드(Postgres)를 계측합니다.
ExecuteReaderAsync
ExecuteNonQueryAsync
ExecuteScalarAsync
.NET 에이전트는 고유한 비동기 메서드의 사용자 지정 계측 을 지원합니다.
알려진 제한 사항
다음은 .NET 에이전트를 사용한 비동기 계측에 대한 알려진 제한 사항에 대한 요약입니다.
응답 시간은 async
- await
사용 장면에서 소요된 총 시간보다 짧을 것으로 예상됩니다. 웹 엔드포인트에 대한 다음 코드 예제를 고려하십시오.
async Task<string> WebEndpointExample() { await DoSomethingForSomeSecondsAsync(5); //kick off a 5-second-work to be done. return "Complete";}
[Trace][MethodImpl(MethodImplOptions.NoInlining)]private static async Task DoSomethingForSomeSecondsAsync(int seconds){ await Task.Delay(TimeSpan.FromSeconds(seconds));}
이 코드 예에서 WebEndpointExample
이 완료되는 데 약 5초가 걸리므로 WebEndpointExample
엔드포인트에 대한 요청을 나타내는 트랜잭션의 응답 시간은 약 5초가 됩니다.
에이전트는 또한 트랜잭션을 구성하는 각 개별 세그먼트의 "사용 중" 시간(계장된 메서드가 실제로 실행되는 시간)을 캡처합니다. WebEndpointExample
및 DoSomethingForSomeSecondsAsync
입니다. 이상적으로는 두 세그먼트의 총 실행 시간이 응답 시간(약 5초)과 같습니다.
DoSomethingForSomeSecondsAsync
의 실행 시간이 5초임을 쉽게 알 수 있습니다. 그러나 WebEndpointExample
의 실행 시간은 0초에 가까워야 합니다. (어떤 작업도 수행하지 않습니다. await
DoSomethingForSomeSecondsAsync
이(가) 완료됩니다.)
그러나 에이전트는 여전히 실행 시간을 약 5초로 측정합니다. 이는 메서드가 다른 메서드에 대해 await
할 때 에이전트가 차단된 시간(CPU 시간 아님)을 감지할 수 없기 때문입니다. 따라서 총 시간은 응답 시간(약 5초)보다 긴 10초로 보고됩니다.
동시에 에이전트는 async
메서드에 대한 호출이 항상 호출자를 전체 시간 동안 차단한다고 가정할 수 없습니다. 다음 예는 이것을 보여줍니다:
async Task<string> WebEndpointExample(){ var task = DoSomethingForSomeSecondsAsync(5); //kick off a 5-second-work to be done.
//Do something less than 5 seconds here.
await task; return "Complete";}
[Trace][MethodImpl(MethodImplOptions.NoInlining)]private static async Task DoSomethingForSomeSecondsAsync(int seconds){ await Task.Delay(TimeSpan.FromSeconds(seconds));}
이 예에서 응답 시간은 여전히 약 5초이지만 WebEndpointExample
의 실제 실행 시간은 더 이상 약 0이 아닙니다.
레거시 ASP 파이프라인이 있는 경우 .NET 에이전트는 비동기 메서드를 계측하지 않습니다. Microsoft는 비동기 메서드가 도입되기 훨씬 전에 레거시 ASP 파이프라인을 교체했기 때문에 이 문제는 일반적으로 .NET Framework 4.0 이하에서 만든 다음 .NET Framework 4.5 이상으로 마이그레이션한 응용 프로그램에만 영향을 미칩니다.
이 문제가 애플리케이션에 영향을 미치는지 확인하고 문제가 발생하는 경우 이를 해결하는 방법 은 문제 해결 절차 를 검토하십시오 .
.NET 에이전트는 Task
또는 Task<T>
이외의 반환 유형이 있는 비동기 메서드의 계측을 지원하지 않습니다. 에이전트는 async void
메서드를 지원하지 않습니다.
자세한 내용은 비동기 반환 유형 에 대한 Microsoft 설명서를 참조하세요.
.NET 에이전트는 WCF 애플리케이션 을 제외하고 begin*
및 end*
스타일을 사용하는 .NET 메서드를 계측하지 않습니다. 이 예외를 제외하고 애플리케이션이 이러한 유형의 메서드를 호출하는 경우 에이전트는 해당 메서드에 대한 세그먼트를 생성하지 않습니다. 그러나 나머지 거래 및 세그먼트는 올바르게 생성됩니다.
.NET 에이전트는 애플리케이션에서 수동으로 생성한 스레드 내에서 범위가 지정된 메트릭 또는 세그먼트를 캡처하지 않습니다.
애플리케이션이 계측된 비동기 메서드를 호출하는 경우 { Task.Result()
Task
관련 메서드 대신 await
를 사용하여 결과를 기다립니다. 그렇지 않으면 계측이 제대로 작동하지 않을 수 있습니다.
일반적으로 비동기 메서드를 호출할 때는 Task.Result()
사용하지 마세요. 교착 상태가 발생할 수 있습니다.
계측된 비동기 메서드에서 반환된 프라미스에 고유한 ContinueWith({})
블록을 추가하면 계측에서 보고하는 타이밍 측정에 영향을 미칠 수 있습니다. 예를 들어, 시간에는 ContinueWith
이 실행되는 데 걸리는 시간이 포함될 수 있습니다.
트랜잭션 추적의 세그먼트는 transaction_tracer.stack_trace_threshold
보다 오래 실행되더라도 스택 추적을 자동으로 생성하지 않습니다.