다음을 통해 공유


PerfCollect를 사용하여 .NET 애플리케이션 추적

이 문서의 적용 대상: ✔️ .NET Core 2.1 SDK 이상 버전

Linux에서 성능 문제가 발생하는 경우 perfcollect로 추적을 수집하면 성능 문제 발생 시 머신에서 발생한 상황에 대한 자세한 정보를 수집할 수 있습니다.

perfcollectLTTng(Linux Trace Tookit: next generation)를 사용하여 런타임이나 모든 EventSource에서 기록된 이벤트를 수집할 뿐만 아니라 perf를 사용하여 대상 프로세스의 CPU 샘플을 수집하는 bash 스크립트입니다.

머신 준비

perfcollect로 성능 추적을 수집할 머신을 준비하려면 다음 단계를 수행합니다.

참고 항목

컨테이너 내부에서 캡처하는 경우 컨테이너에 적절한 기능이 있어야 합니다. 최소 필수 기능은 PERFMONSYS_PTRACE입니다. 최소 집합으로 캡처가 실패하면 컨테이너에 SYS_ADMIN 기능을 추가합니다. PerfCollect를 사용하여 컨테이너 내 애플리케이션 추적에 대한 자세한 내용은 컨테이너에서 진단 수집을 참조하세요.

  1. perfcollect를 다운로드합니다.

    curl -OL https://aka.ms/perfcollect
    
  2. 스크립트를 실행 가능하도록 설정합니다.

    chmod +x perfcollect
    
  3. 추적 필수 구성 요소인 실제 추적 라이브러리를 설치합니다.

    sudo ./perfcollect install
    

    그러면 다음과 같은 필수 구성 요소가 머신에 설치됩니다.

    1. perf: Linux 성능 이벤트 하위 시스템과 수반되는 사용자 모드 컬렉션/뷰어 애플리케이션입니다. perf는 Linux 커널 소스의 일부이지만 보통 기본적으로 설치되지는 않습니다.

    2. LTTng: CoreCLR에서 런타임에 내보낸 이벤트 데이터를 캡처하는 데 사용됩니다. 그런 다음, 이 데이터를 사용하여 GC, JIT, 스레드 풀과 같은 다양한 런타임 구성 요소의 동작을 분석합니다.

최신 버전의 .NET Core 및 Linux perf 도구는 프레임워크 코드의 메서드 이름 자동 확인을 지원합니다.

네이티브 런타임 DLL(예: libcoreclr.so)의 메서드 이름을 확인하기 위해 perfcollect는 데이터를 변환할 때 기호를 확인하지만 이러한 이진에 대한 기호가 있는 경우에만 확인합니다. 자세한 내용은 네이티브 런타임에 대한 기호 가져오기 섹션을 참조하세요.

추적 수집

  1. 두 개의 셸을 사용할 수 있습니다. 하나는 추적을 제어하는 데 사용되어 [Trace]라고 하고 하나는 애플리케이션을 실행하는 데 사용되어 [App]이라고 합니다.

  2. [Trace] 컬렉션을 시작합니다.

    sudo ./perfcollect collect sampleTrace
    

    예상 출력:

    Collection started.  Press CTRL+C to stop.
    
  3. [App] 다음 환경 변수를 사용하여 애플리케이션 셸을 설정합니다. 따라서 CoreCLR의 구성 추적을 사용할 수 있습니다.

    export DOTNET_PerfMapEnabled=1
    export DOTNET_EnableEventLog=1
    

    참고 항목

    .NET 7로 앱을 실행하는 경우 이전 환경 변수 외에 DOTNET_EnableWriteXorExecute=0도 설정해야 합니다. 예시:

    export DOTNET_EnableWriteXorExecute=0
    

    참고 항목

    .NET 6은 .NET 런타임 동작을 구성하는 환경 변수에 대해 COMPlus_ 대신 접두사 DOTNET_을 표준화합니다. 그러나 COMPlus_ 접두사도 계속 작동합니다. 이전 버전의 .NET 런타임을 사용하는 경우에도 환경 변수에 COMPlus_ 접두사를 사용해야 합니다.

  4. [App] 앱을 실행합니다. 성능 문제를 캡처하기 위해 실행해야 하는 한 앱이 실행되도록 합니다. 조사하려는 성능 문제가 발생하는 기간을 충분히 캡처할 수 있다면 정확한 길이는 짧을 수 있습니다.

    dotnet run
    
  5. [Trace] 컬렉션을 중지합니다. Ctrl+C를 누릅니다.

    ^C
    ...STOPPED.
    
    Starting post-processing. This may take some time.
    
    Generating native image symbol files
    ...SKIPPED
    Saving native symbols
    ...FINISHED
    Exporting perf.data file
    ...FINISHED
    Compressing trace files
    ...FINISHED
    Cleaning up artifacts
    ...FINISHED
    
    Trace saved to sampleTrace.trace.zip
    

    이제 압축된 추적 파일이 현재 작업 디렉터리에 저장됩니다.

추적 보기

수집된 추적을 볼 수 있는 여러 가지 옵션이 있습니다. 추적은 Windows에서 PerfView를 사용하여 가장 잘 볼 수 있지만 PerfCollect 자체나 TraceCompass를 사용하여 Linux에서 직접 볼 수 있습니다.

PerfCollect를 사용하여 추적 파일 보기

PerfCollect 자체를 사용하여 수집한 추적을 볼 수 있습니다. 이렇게 하려면 다음 명령을 사용합니다.

./perfcollect view sampleTrace.trace.zip

기본적으로 perf를 사용하여 애플리케이션의 CPU 추적을 표시합니다.

LTTng를 통해 수집된 이벤트를 확인하려면 -viewer lttng 플래그를 전달하여 개별 이벤트를 확인하면 됩니다.

./perfcollect view sampleTrace.trace.zip -viewer lttng

그러면 babeltrace 뷰어를 사용하여 이벤트 페이로드를 출력합니다.

# [01:02:18.189217659] (+0.020132603) ubuntu-xenial DotNETRuntime:ExceptionThrown_V1: { cpu_id = 0 }, { ExceptionType = "System.Exception", ExceptionMessage = "An exception happened", ExceptionEIP = 139875671834775, ExceptionHRESULT = 2148734208, ExceptionFlags = 16, ClrInstanceID = 0 }
# [01:02:18.189250227] (+0.020165171) ubuntu-xenial DotNETRuntime:ExceptionCatchStart: { cpu_id = 0 }, { EntryEIP = 139873639728404, MethodID = 139873626968120, MethodName = "void [helloworld] helloworld.Program::Main(string[])", ClrInstanceID = 0 }

PerfView를 사용하여 추적 파일 열기

CPU 샘플과 이벤트의 집계 뷰를 보려면 Windows 머신에서 PerfView를 사용할 수 있습니다.

  1. Linux에서 Windows 머신으로 trace.zip 파일을 복사합니다.

  2. https://aka.ms/perfview에서 PerfView를 다운로드합니다.

  3. PerfView.exe 실행

    PerfView.exe <path to trace.zip file>
    

PerfView는 추적 파일에 포함된 데이터에 따라 지원되는 보기 목록을 표시합니다.

  • CPU를 조사하려면 CPU 스택을 선택합니다.

  • 자세한 GC 정보를 보려면 GCStats를 선택합니다.

  • 프로세스/모듈/메서드별 JIT 정보를 보려면 JITStats를 선택합니다.

  • 필요한 정보에 대한 보기가 없는 경우 원시 이벤트 보기에서 이벤트를 검색해 볼 수 있습니다. 이벤트를 선택합니다.

PerfView에서 보기를 해석하는 방법에 대한 자세한 내용은 보기 자체의 도움말 링크를 참조하거나 PerfView의 주 창에서 도움말->사용자 가이드를 선택합니다.

참고 항목

System.Diagnostics.Tracing.EventSource API를 통해 작성된 이벤트(프레임워크의 이벤트 포함)는 해당 공급자 이름 아래에 표시되지 않습니다. 대신, Microsoft-Windows-DotNETRuntime 공급자 아래에 EventSourceEvent 이벤트로 작성되고 해당 페이로드는 JSON 직렬화됩니다.

참고 항목

메서드 이름과 호출 스택에서 [unknown] /memfd:doublemapper 프레임을 관찰하는 경우 perfcollect로 추적하는 앱을 실행하기 전에 DOTNET_EnableWriteXorExecute=0을 설정합니다.

TraceCompass를 사용하여 추적 파일 열기

Eclipse TraceCompass는 추적을 보는 데 사용할 수 있는 또 다른 옵션입니다. TraceCompass는 Linux 머신에서도 작동하므로 추적을 Windows 머신으로 이동할 필요가 없습니다. TraceCompass를 사용하여 추적 파일을 열려면 파일의 압축을 풀어야 합니다.

unzip myTrace.trace.zip

perfcollect는 수집된 LTTng 추적을 CTF 파일 형식으로 lttngTrace의 하위 디렉터리에 저장합니다. 특히 CTF 파일은 lttngTrace/auto-20201025-101230\ust\uid\1000\64-bit\ 같은 디렉터리에 배치됩니다.

TraceCompass에서 File -> Open Trace를 선택하고 metadata 파일을 선택하여 CTF 추적 파일을 엽니다.

자세한 내용은 TraceCompass 설명서를 참조하세요.

네이티브 런타임에 대한 기호 가져오기

대체로 개발자는 직접 작성한 코드에 관심이 있으며, 이러한 코드는 기본적으로 perfcollect에서 확인됩니다. 경우에 따라 .NET DLL 내부의 진행 상황(마지막 섹션에서 다루는 내용)을 확인하는 것이 유용하지만, 경우에 따라서는 네이티브 런타임 DLL(일반적으로 libcoreclr.so)의 진행 상황이 흥미롭습니다. perfcollect는 데이터를 변환할 때 이러한 기호를 확인하지만 이러한 네이티브 DLL에 대한 기호가 있고 대상 라이브러리 옆에 있을 때만 확인합니다.

dotnet-symbol이라는 전역 명령이 있어 이 작업을 수행합니다. dotnet-symbol을 사용하여 네이티브 런타임 기호를 가져오려면 다음을 수행합니다.

  1. dotnet-symbol 설치:

    dotnet tool install -g dotnet-symbol
    
  2. 기호를 다운로드합니다. 설치한 .NET Core 런타임 버전이 2.1.0인 경우 이 작업을 수행하는 명령은 다음과 같습니다.

    mkdir mySymbols
    dotnet symbol --symbols --output mySymbols  /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.0/lib*.so
    
  3. 기호를 올바른 위치에 복사합니다.

    sudo cp mySymbols/* /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.0
    

    적절한 디렉터리에 대한 쓰기 권한이 없어 이 작업을 수행할 수 없는 경우 perf buildid-cache를 사용하여 기호를 추가할 수 있습니다.

그러면 perfcollect를 실행할 때 네이티브 dll의 기호 이름을 가져와야 합니다.

Docker 컨테이너에서 수집

컨테이너 환경에서 perfcollect를 사용하는 방법에 대한 자세한 내용은 컨테이너에서 진단 수집을 참조하세요.

수집 옵션에 대한 자세한 정보

진단 요구 사항에 맞게 perfcollect를 사용하여 다음의 선택적 플래그를 지정할 수 있습니다.

특정 기간에 수집

특정 기간에 추적을 수집하려면 -collectsec 옵션 다음에 추적을 수집할 총 시간(초)을 지정할 수 있습니다.

threadtime 추적 수집

-threadtimeperfcollect와 함께 지정하면 스레드별 CPU 사용량 현황 데이터를 수집할 수 있습니다. 이렇게 하면 모든 스레드에서 CPU 시간을 소비한 위치를 분석할 수 있습니다.

관리되는 메모리 및 가비지 수집기 성능에 대한 추적 수집

다음 옵션을 사용하면 런타임에서 GC 이벤트를 지정하여 수집할 수 있습니다.

  • perfcollect collect -gccollectonly

최소한의 GC 수집 이벤트 세트만 수집합니다. 가장 낮은 표시 수준의 GC 이벤트 수집 프로필이므로 대상 앱의 성능에 미치는 영향이 가장 적습니다. 이 명령은 PerfView의 PerfView.exe /GCCollectOnly collect 명령과 유사합니다.

  • perfcollect collect -gconly

JIT, 로더, 예외 이벤트를 사용하여 더 높은 표시 수준의 GC 수집 이벤트를 수집합니다. 표시 수준이 더 높은 이벤트(예: 할당 정보 및 GC 조인 정보)가 필요하므로 -gccollectonly 옵션보다 대상 앱의 성능에 미치는 영향이 큽니다. 이 명령은 PerfView의 PerfView.exe /GCOnly collect 명령과 유사합니다.

  • perfcollect collect -gcwithheap

힙 존속 및 이동도 추적하는 가장 높은 표시 수준의 GC 수집 이벤트를 수집합니다. 따라서 GC 동작을 심층 분석할 수 있지만 각 GC가 2배 이상 오래 걸릴 수 있기 때문에 성능 비용이 높아집니다. 프로덕션 환경에서 추적할 경우에는 이 추적 옵션 사용에 따른 성능 영향을 이해하는 것이 좋습니다.