İlkay İlknur

.NET Uygulamalarında Kullanabileceğimiz Diagnostics Araçları

January 17, 2021

Bu yazıda .NET uygulamalarımızı monitör ederken, memory ve performans problemeleriyle karşılaştığımızda kullanabileceğimiz diagnostics araçlarını inceleyeceğiz. Daha öncesinde yine bu kapsamda dotnet-counters isimli aracı blogda yazmıştım. Dilerseniz o yazıyı da okuyabilirsiniz.

dotnet-trace

dotnet-trace CLI toolu ile çalışan .NET uygulamaların tracelerini toplayabiliyoruz. Bu tool cross-platform olarak çalışabildiği için ve EventPipe'ları kullandığı için native profilera ihtiyaç duyulmuyor.

Yüklemek için dotnet tool install --global dotnet-trace

Toolu yükledikten sonra ilk yapmamız gereken şey tracelerini toplayacağımız .NET processini bulmak. Bunun için dotnet-trace ps komutunu kullanabiliriz.

PS C:\Users\ilkay\source\repos\WebApplication27\WebApplication27\bin\Release\net5.0> dotnet trace ps
      6076 dotnet     C:\Program Files\dotnet\dotnet.exe
     27928 dotnet     C:\Program Files\dotnet\dotnet.exe

Process IDsini bulduktan sonra basitçe dotnet-trace collect -p <pID> komutunu çalıştırarak traceleri toplayabiliriz.

No profile or providers specified, defaulting to trace profile 'cpu-sampling'

Provider Name                           Keywords            Level               Enabled By
Microsoft-DotNETCore-SampleProfiler     0x0000F00000000000  Informational(4)    --profile
Microsoft-Windows-DotNETRuntime         0x00000014C14FCCBD  Informational(4)    --profile

Process        : C:\Program Files\dotnet\dotnet.exe
Output File    : C:\Users\ilkay\source\repos\WebApplication27\WebApplication27\bin\Release\net5.0\trace.nettrace

[00:00:00:04]   Recording trace 161.435  (KB)
Stopping the trace. This may take up to minutes depending on the application being traced.

Bu komutu çalıştırdıktan sonra traceler siz dur diyene kadar toplanacak ve dosyaya yazılacak. Bu nedenle bir noktada trace toplama işlemini sonlandırmak için Enter veya Ctrl+Cye basmanız gerekiyor.

dotnet-trace komutu default olarak cpu-sampling profile ile çalışmakta. Eğer GC profiling yapmak isterseniz size uygun olan profile'ı dotnet-trace list-profiles komutuyla bulup komutu çalıştırırken parametre geçebilirsiniz. dotnet-trace komutu default olarak .nettrace uzantılı dosyalar üretmekte. Bu dosyaları Visual Studio veya PerfView gibi araçlarla açıp analiz edebilirsiniz. Linux tarafındaki traceleri Windows'a aktarıp incelemek tabi ki bir opsiyon. Buna alternatif olarak komutu çağırırken --format speedscope belirtirseniz çıktı olarak üretilen trace dosyasını SpeedScope üzerinden inceleyebilirsiniz. Varolan trace dosyalarını da başka formata çevirmek isterseniz yine dotnet-trace convert komutunu kullanmak mümkün.

.NET 5.0 ile beraber uygulamaların ayağa kalmasıyla beraber trace toplamak mümkün olmakta. Bu da bize uygulamaların startup zamanlarının monitör edebilmemize ve sorunları bulmamıza olanak sağlamakta. Bunun için dotnet-trace collect -- <command> şeklinde komutu çalıştırabiliriz. Bu komutu çalıştırdığımızda belirttiğimiz komut çalıştırılıp sonrasında traceler toplanmaya başlanır. Trace toplamayı durdurduğumuzda uygulama da kapatılır.

dotnet-trace collect -- WebApplication27.exe

dotnet-trace collect -- dotnet .\WebApplication27.dll

dotnet-trace toolu ile ilgili daha detaylı bilgi almak için buraya bakabilirsiniz.

dotnet-dump

dotnet-dump CLI toolu bizim cross-platform olarak managed dump almamızı ve analiz etmemizi sağlayan bir tool.

Yüklemek için

dotnet tool install --global dotnet-dump

dotnet-dump toolunu kullanmak için dotnet-trace toolunda olduğu gibi dumpını alacağımız processin IDsini veya adını bulmamız gerekiyor. Sonrasında komutu çağırırken -p veya -n ile ilgili parametreyi geçebiliriz.

Dump almak için dotnet-dump tooluna collect komutunu geçerek ilgili parametreleri de belirtmemiz gerekiyor.

Örneğin, process IDsi ile dump almak istersek.

dotnet-dump collect -p 10956

Aynı zamanda dump alırken --type parametresinde hangi tipte(Mini, Heap, Full) bir dump almak istediğimizi de belirtebiliriz. Eğer belirtmezsek full dump alınmakta.

dotnet-dump collect -p 10956 --type Mini

Dump aldıktan sonra alınan dumpı analiz etmek için de analyze komutunu çalıştırıp SOS komutlarıyla analiz edebiliriz.

dotnet-dump analyze <DumpDosyasi>

Analyze komutunu çağırdıktan sonra tool bizden analiz için kullanabileceğimiz komutları bekliyor. Kullanabileceğimiz komutlara help yazarak da ulaşmamız mümkün.

PS C:\Users\ilkay\source\repos\WebApplication27\WebApplication27\bin\Release\net5.0> dotnet-dump analyze .\dump_20210117_173351.dmp
Loading core dump: .\dump_20210117_173351.dmp ...
Ready to process analysis commands. Type 'help' to list available commands or 'help [command]' to get detailed help on a command.
Type 'quit' or 'exit' to exit the session.
> verifyheap
No heap corruption detected.
> threadpool
CPU utilization: 2 %%
Worker Thread: Total: 1 Running: 0 Idle: 1 MaxLimit: 32767 MinLimit: 12
Work Request in Queue: 0
--------------------------------------
Number of Timers: 1
--------------------------------------
Completion Port Thread:Total: 2 Free: 2 MaxFree: 24 CurrentLimit: 2 MaxLimit: 1000 MinLimit: 12

dotnet-dump ile aldığımız dumpların bir kısıtı da örneğin Linux tarafında aldığımız dumpları Windows tarafında inceleyemememiz. Bu durumun tam tersi de geçerli. Bu da bizi bir sonra inceleyeceğimiz komuta götürecek.

dotnet-dump toolu ile ilgili daha detaylı bilgi için burayı inceleyebilirsiniz.

dotnet-gcdump

dotnet-gcdump CLI toolu ile çalışan uygulamaların gcdumplarını alabiliyoruz. Bu tool ile gcdump alınırken Gen2 GC tetikleniyor ve EventPipe üzerinde gelen eventler kullanılıyor. Bu nedenle dotnet-dump komutundaki limitlemeler burada yok ve daha lightweight bir çözüm. Cross-platform şeklinde inceleme yapabiliyoruz. Tool çalışması sırasında Gen2 GC tetiklediği için uygulamada Gen2'un fazla büyük olduğu senaryolarda uygulamada duraksamaların olması beklenen bir davranış. Bu nedenle performans kritik applerde bu komutun çalıştırılması problemler oluşturabilir.

Yüklemek için

dotnet tool install --global dotnet-gcdump

Dump almak için

dotnet-gcdump collect -p <pID>

Bu tooldan aldığımız gcdumpları Visual Studio veya PerfView kullanarak analiz edebiliriz.

visual-studio-gc-dump-analyze

Bu yazıda basitçe uygulamalarımızı monitör ederken veya çeşitli sorunlarla karşılaştığımızda kullabileceğimiz toollardan bahsetmeye çalıştım. Tabi ki biz bu yazıda basitçe komutlardan ve ne işe yaradıklarından bahsettik. Production ortamlarında bu komutları ve araçları bilmenin yanı sıra bu araçların ürettiği çıktıları da analiz etmek oldukça önemli. İlerleyen yazılarda bu konulardan da bahsetmeyi planlıyorum.

Bir sonraki yazıda görüşmek üzere,

Kaynaklar