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 보다 오래 실행되더라도 스택 추적을 자동으로 생성하지 않습니다.