PerfCollect를 사용하여 .NET 애플리케이션 추적
이 문서의 적용 대상: ✔️ .NET Core 2.1 SDK 이상 버전
Linux에서 성능 문제가 발생하는 경우 perfcollect
로 추적을 수집하면 성능 문제 발생 시 머신에서 발생한 상황에 대한 자세한 정보를 수집할 수 있습니다.
perfcollect
는 LTTng(Linux Trace Tookit: next generation)를 사용하여 런타임이나 모든 EventSource에서 기록된 이벤트를 수집할 뿐만 아니라 perf를 사용하여 대상 프로세스의 CPU 샘플을 수집하는 bash 스크립트입니다.
머신 준비
perfcollect
로 성능 추적을 수집할 머신을 준비하려면 다음 단계를 수행합니다.
참고 항목
컨테이너 내부에서 캡처하는 경우 컨테이너에 적절한 기능이 있어야 합니다. 최소 필수 기능은 PERFMON
및 SYS_PTRACE
입니다. 최소 집합으로 캡처가 실패하면 컨테이너에 SYS_ADMIN
기능을 추가합니다. PerfCollect를 사용하여 컨테이너 내 애플리케이션 추적에 대한 자세한 내용은 컨테이너에서 진단 수집을 참조하세요.
perfcollect
를 다운로드합니다.curl -OL https://aka.ms/perfcollect
스크립트를 실행 가능하도록 설정합니다.
chmod +x perfcollect
추적 필수 구성 요소인 실제 추적 라이브러리를 설치합니다.
sudo ./perfcollect install
그러면 다음과 같은 필수 구성 요소가 머신에 설치됩니다.
perf
: Linux 성능 이벤트 하위 시스템과 수반되는 사용자 모드 컬렉션/뷰어 애플리케이션입니다.perf
는 Linux 커널 소스의 일부이지만 보통 기본적으로 설치되지는 않습니다.LTTng
: CoreCLR에서 런타임에 내보낸 이벤트 데이터를 캡처하는 데 사용됩니다. 그런 다음, 이 데이터를 사용하여 GC, JIT, 스레드 풀과 같은 다양한 런타임 구성 요소의 동작을 분석합니다.
최신 버전의 .NET Core 및 Linux perf 도구는 프레임워크 코드의 메서드 이름 자동 확인을 지원합니다.
네이티브 런타임 DLL(예: libcoreclr.so)의 메서드 이름을 확인하기 위해 perfcollect
는 데이터를 변환할 때 기호를 확인하지만 이러한 이진에 대한 기호가 있는 경우에만 확인합니다. 자세한 내용은 네이티브 런타임에 대한 기호 가져오기 섹션을 참조하세요.
추적 수집
두 개의 셸을 사용할 수 있습니다. 하나는 추적을 제어하는 데 사용되어 [Trace]라고 하고 하나는 애플리케이션을 실행하는 데 사용되어 [App]이라고 합니다.
[Trace] 컬렉션을 시작합니다.
sudo ./perfcollect collect sampleTrace
예상 출력:
Collection started. Press CTRL+C to stop.
[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_
접두사를 사용해야 합니다.[App] 앱을 실행합니다. 성능 문제를 캡처하기 위해 실행해야 하는 한 앱이 실행되도록 합니다. 조사하려는 성능 문제가 발생하는 기간을 충분히 캡처할 수 있다면 정확한 길이는 짧을 수 있습니다.
dotnet run
[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
를 사용할 수 있습니다.
Linux에서 Windows 머신으로 trace.zip 파일을 복사합니다.
https://aka.ms/perfview에서 PerfView를 다운로드합니다.
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을 사용하여 네이티브 런타임 기호를 가져오려면 다음을 수행합니다.
dotnet-symbol
설치:dotnet tool install -g dotnet-symbol
기호를 다운로드합니다. 설치한 .NET Core 런타임 버전이 2.1.0인 경우 이 작업을 수행하는 명령은 다음과 같습니다.
mkdir mySymbols dotnet symbol --symbols --output mySymbols /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.0/lib*.so
기호를 올바른 위치에 복사합니다.
sudo cp mySymbols/* /usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.0
적절한 디렉터리에 대한 쓰기 권한이 없어 이 작업을 수행할 수 없는 경우
perf buildid-cache
를 사용하여 기호를 추가할 수 있습니다.
그러면 perfcollect
를 실행할 때 네이티브 dll의 기호 이름을 가져와야 합니다.
Docker 컨테이너에서 수집
컨테이너 환경에서 perfcollect
를 사용하는 방법에 대한 자세한 내용은 컨테이너에서 진단 수집을 참조하세요.
수집 옵션에 대한 자세한 정보
진단 요구 사항에 맞게 perfcollect
를 사용하여 다음의 선택적 플래그를 지정할 수 있습니다.
특정 기간에 수집
특정 기간에 추적을 수집하려면 -collectsec
옵션 다음에 추적을 수집할 총 시간(초)을 지정할 수 있습니다.
threadtime 추적 수집
-threadtime
을 perfcollect
와 함께 지정하면 스레드별 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배 이상 오래 걸릴 수 있기 때문에 성능 비용이 높아집니다. 프로덕션 환경에서 추적할 경우에는 이 추적 옵션 사용에 따른 성능 영향을 이해하는 것이 좋습니다.
.NET