İlkay İlknur

ASP.NET Core MVC ve Web API Uygulamalarında Mini Profiler Kullanımı

Ağustos 05, 2020

Bu yazıda uygulamalarımızda profiling yapmak için kullanabileceğimiz araçlardan biri olan Mini Profiler'dan bahsedeceğiz. Mini Profiler kullanarak hızlı ve basit bir şekilde uygulamalarımızda hangi noktalarda ne kadar zaman harcandığını görmemiz mümkün. Böylece development esnasında performans sorunu yaşadığımız noktaları tespit edip buna göre aksiyon almamız oldukça kolaylaşmakta. Mini profiler Stackoverflow ekibi tarafından geliştirilmekte olup ve aynı zamanda uygulamalarında da aktif olarak kullanılmakta. İncelemek isteyenler için Github linkini buraya bırakıyorum.

Şimdi gelin Mini profilerı uygulamalarımıza nasıl entegre ediyoruz kısmıyla başlayalım. ASP.NET Core uygulamalarından Mini profilerı kullanmak için aşağıdaki nuget paketini yüklememiz gerekiyor.

Install-Package MiniProfiler.AspNetCore.Mvc

Paketi yükledikten sonra Startup.cs içerisinde mini profiler konfigürasyonunu yapıp ve middleware'ini aşağıdaki gibi eklememiz gerekiyor.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMiniProfiler();
}
 
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseMiniProfiler();
}

Sonrasında Mini profiler tag helperlarını aşağıdaki gibi _ViewImports.cshtml dosyasına eklememiz gerekiyor.

@using StackExchange.Profiling
@addTagHelper *, MiniProfiler.AspNetCore.Mvc

Son olarak ise Layout.cshtml dosyasına mini profiler view'ını ekliyoruz.

<mini-profiler/>

Bu şekilde default olarak konfigürasyon yapıp uygulamayı çalıştırdığınızda sayfanın sol üst köşesinden mini profiler view'ını görebilirsiniz.

Bu view'a tıkladığımızda ise daha detaylı görünüme geçebiliyoruz.

Sağ alttaki show trivial linkine tıkladığımızda ise hangi action filterlarda, hangi viewlarda vs.. ne kadar vakit harcandığını görmemiz mümkün.

Entity Framework Core Entegrasyonu

Mini profilerın en güzel özelliklerinden biri de entity framework core entegrasyonu olması ve bu entegrasyon sayesinde tüm database sorguları, connection hareketleri vs.. gibi işlemleri kolayca görebilmemiz. Bu entegrasyonu aktifleştirmek için öncelikle entegrasyon paketini yüklememiz gerekiyor.

Install-Package MiniProfiler.EntityFrameworkCore

Sonrasında Startup.cs'e gidip ufak bir ekleme yapiyoruz.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMiniProfiler()
            .AddEntityFramework();
}

Uygulamayı yeniden başlattığımızda DB tarafında ne kadar vakit harcanıyor, hangi sql sorguları çalışıyor hepsini görebiliyoruz.

Daha Detaylı Profiling

Yukarıdaki ekran görüntülerine baktığınızda mini profilerın default olarak her actionı bir bütün olarak gösterdiğini ve altındaki işlemleri ayrıca göremediğimizi farketmişsinizdir. Örneğin bir action içerisinde 2-3 farklı yere requestte bulunuyorsak bu operasyonları ayrı ayrı takip etmemiz default kullanımda mümkün değil. Bunun için kendimiz ayrıca profiling adımları tanımlamamız gerekiyor.

Profiling adımlarını tanımlamak için MiniProfiler.Current içerisindeki Step metodunu kullanabiliriz. Step metodunu çağırırken o adıma vereceğimiz adı yazmamız yeterli.

public IActionResult Index()
{
    using (MiniProfiler.Current.Step("UserCheck"))
    {
        using (MiniProfiler.Current.Step("User Role Check"))
        {
 
        }
    }
 
}

Sonrasında uygulamayı çalıştırdığımızda tanımladığımız adımların ayrı ayrı gözüktüğünü göreceğiz.

Bazı profiling adımlarının belirtilen sürenin üzerinde sürdüğü durumlarda profiling raporunda ayrı bir step olarak gözükmesini de isteyebiliriz. Bunun için de StepIf metodunu kullanabiliriz. Örneğin UserRoleCheck adımı 100ms'den uzun sürdüğü durumlarda gözükmesini istersek şu şekilde bir tanımlama yapabiliriz.

using (MiniProfiler.Current.Step("UserCheck"))
{
    using (MiniProfiler.Current.StepIf("User Role Check", 100))
    {
                    
    }
}

Mini profiler kullanırken uygulama dışında bağlandığımız servislerin profilingini yapmak için Custom Timing yapısını kullanabiliriz. Custom Timing yapısı aslında Entity Framework entegrasyonundaki yapının benzerini bizim kurmamıza imkan veriyor. Yani bir kategori belirleyip o kategori altında çalışan sorguları veya requestleri profiling raporunda görebiliyoruz.

CustomTiming metodunun örnek kullanımı ise şu şekilde.

using (MiniProfiler.Current.CustomTiming("http""http://www.ilkayilknur.com""GET"))
{
}

Burada ilk parametre kategorinin adı, ikinci parametre çalışan komutun kendisi, üçüncü parametre ise executionType. Bu şekilde bir custom timing tanımladıktan sonra profiling raporunda şu şekilde görebiliyoruz.

View İçerisinde Profiling

Kod tarafında profiling yapabilmek için kullanmamız gereken bileşenleri inceledik. View tarafında da ekstra adımlar eklemek istediğimizde profile tag helperını kullanabiliriz.

<profile name="UserMenuGeneration">
 
</profile>

Web API İçerisinde Mini Profiler Kullanımı

Web API'lar içerisinde herhangi bir UI olmadığı için API'ların profile edilmesinde bir başka mini profiler özelliğini kullanacağız. Mini profilerı default olarak konfigüre ettiğinizde iki endpointin dışarı açıldığını göreceksiniz.

Bunlar,

  • /mini-profiler-resources/results-index : Son profiling sessionların listesi
  • /mini-profiler-resources/results : Son profiling sessionın detayları

Bu endpointleri kullanarak Web API'larda da profiling yapmamız mümkün. Bu endpointler aynı zamanda MVC uygulamalarında da bulunmakta.

Endpointlerin base kısmını(mini-profiler-resources) değiştirmek isterseniz konfigürasyon sırasında RouteBasePath'i kullanabilirsiniz.

services.AddMiniProfiler(options=>
{
    options.RouteBasePath = "profiles";              
});

Mini Profiler Özelleştirme

Şimdiye kadar çoğunlukla mini profilerı default ayarlarıyla kullanmayı inceledik. Ancak mini profilerın pek çok özelleştirme ayarı mevcut. Bu ayarlara MiniProfilerOptions içerisinden ulaşabiliriz. Ben en çok dikkatimi çeken özelliklerden bahsedeceğim.

  • ShouldProfile: Mini profiler default olarak gelen tüm requestleri profile eder. Bu özelliği değiştirmek istediğimizde veya production ortamlarında gerektiğinde sadece belirli bölümlerin profile edilmesini istediğimizde bu propertyi kullanabiliriz.

  • ResultsAuthorize, ResultsAuthorizeAsync, ResultsListAuthorize,ResultsListAuthorizeAsync : Yukarıda bahsettiğim iki adrese kimlerin erişebileceğini belirleyebileceğiniz yerler. Özellikle production ortamlarında herkesin profiling sessionlarına erişmesini istemeyeceksinizdir.

  • EnableMvcFilterProfiling, EnableMvcViewProfiling : Filter ve Viewların ayrı adımlar olarak profiling raporlarında gösterilip gösterilmeyeceğini belirleyen property. Default değeri true.

Profiling Sessionların Saklanması

Mini profilerın bir diğer kuvvetli yönü de pek çok provider desteğiyle profiling verilerinin saklanmasına yardımcı olması. Mini profiler providerlarıyla aşağıdaki yerlerde profiling verilerini saklayabiliyoruz.

  • SqlServer
  • Redis
  • Sqlite
  • MySQL
  • MongoDB
  • RavenDB
  • PostgreSQL
  • SqlServerCE

Hangi ortamda saklamak istedigimiz konusunda seçimi yaptıktan sonra ilgili provider paketini yükleyip ilerleyebiliriz. Örneğin SqlServerda verileri saklamak istersek öncelikle MiniProfiler.Providers.SqlServer nuget paketini projemize ekliyoruz. Sonrasında ise options içerisindeki Storage propertysine ilgili tanımlamayı yapıyoruz.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMiniProfiler(options =>
    {
        options.Storage = new SqlServerStorage("ConnectionString");              
    });
    services.AddControllers();
}

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