MiniProfiler — ASP.NET Core
Merhaba arkadaşlar,
Bu yazımda MiniProfiler’ı ASP.NET Core uygulamalarınızda nasıl kullanabileceğinizi anlatacağım. Daha önce hiç duymayanlar için kısaca özetlemek gerekirse, MiniProfiler Stack Overflow ekibinin uygulamalarının çalışma zamanlarını ayrıntılı olarak incelemeleri için geliştirdikleri pakettir.
Konular
- MiniProfiler nedir ve neler yapabilir?
- MiniProfiler’ı ASP.NET Core uygulamasına ekleme.
- Entity Framework Core verilerini takip etmek.
- Custom Timings ve Timing Sections.
- API üzerinde MiniProfiler
- Ekstra
MiniProfiler nedir ve neler yapabilir?
MiniProfiler projenizdeki performans ölçmede size yardımcı olabilecek lightweight bir kütüphanedir. Kurulumu gayet basit ve hızlıdır. 🚀
Simple. Fast. Pragmatic. Useful!
Developerlar doğal olarak hızlı uygulamalar geliştirmek ister, ancak uygulamanın yavaş çalıştığı bölümleri bazen analiz edemeyiz ve istediğimiz performans review’leri yapamayız. MiniProfiler bize kodun çalışma hızı hakkında ayrıntılı ve hızlı şekilde temiz okunaklı bir rapor oluşturur. Bizlerde bu yapılan ölçümler doğrultusunda kodu optimize ederiz…
Measure -> Optimize -> Measure -> Optimize -> Measure
MiniProfiler sayfanın açılma süresinde yapılan işlemlerin sonucu, sayfanın sol alt (ben sol altta seviyorum) bölümüne bir kutucuk içinde gösterir. Her kutucuk bir http request’i temsil etmektedir.
Kutucuklara tıkladığımızda, request ile ilgili detaylar aşağıdaki şekilde gösterilmektedir. Eğer kutucuğun üstünde 🖱️ faremizi (imleç) tutarsak, http request’in nereye atıldığını görebiliriz.
Result table detaylı olarak hangi sorguların ne kadar sürdüğünü bizlere göstermektedir. Parentezlerin içerisinde kaç kere çağrı yapıldığı belirtilmektedir.
MiniProfiler bize atılan sql sorguları da dahil olmak üzere bir çok detay vermektedir. Performans problemi gördüğümüz sorguları kolayca yakalayıp, execution planını inceleyip optimize edebiliriz.
MiniProfiler’ı ASP.NET Core uygulamasına eklemek
Nuget aracılığıyla MiniProfiler.AspNetCore.Mvc
paketini kuruyoruz.
Install-Package MiniProfiler.AspNetCore.Mvc -Version 4.1.0
Sonrasında Startup.cs classımız’a giriyoruz. ConfigureServices()
metodumuzda AddMiniProfiler()
metodunu çağırıyoruz.
public void ConfigureServices(IServiceCollection services)
{
// ... configurations// AddMiniProfiler metodu bir çok configuration parametresi almaktadır.services.AddMiniProfiler(options =>{
// MiniProfiler'ın sağ altta görünmesi için options.PopupRenderPosition = RenderPosition.BottomLeft; options.PopupShowTimeWithChildren = true; });
}
Sonrasında Configure()
metoduna UseMiniProfiler()
satırını ekliyoruz.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ... codes app.UseMiniProfiler();
}
Sıra geldi MiniProfileri tag helper’i sayfalarımıza eklemeye. Öncelikle _ViewImport.cshtml
‘mize tag helper’ımızı aşağıdaki gibi ekliyoruz.
@using StackExchange.Profiling@addTagHelper *, MiniProfiler.AspNetCore.Mvc
_Layout.cshtml sayfamızın sonuna (footer’ın atına) <mini-profiler />
tagini ekliyoruz. Aşağıdaki ekran görüntüsündeki gibi artık profiling’e hazırız. Ekran görüntüsünde Home/Index sayfası açılırken yapılan request’ler ve time duration’ları görüyoruz. (Makale ile birlikte boş bir proje yarattım.) Makaleyi yazarken aynı zamanda güncelliyor da olacağım. Final kodları için tık GitHub!
Entity Framework Core verilerini takip etmek
Bence bu özellik MiniProfiler’ın en önemli özelliği ve eklenmesi en basit özellik.
Bu özellikle birlikte request time’da yer alan tüm entity framework çağrılarını plain sql text ile görebiliyoruz. Gerçekten harika. Bu özellik sayesinde query’lerimizi optimize etmek gerçekten çok kolaylaşıyor.
Nuget aracılığıyla MiniProfiler.EntityFramworkCore
paketini kuruyoruz.
Install-Package MiniProfiler.EntityFrameworkCore -Version 4.1.0
ConfigureServices()
de eklemiş olduğumuz AddMiniProfiler
metodunun sonuna AddEntityFramework()
metodunu ekliyoruz! Done… ✔
public void ConfigureServices(IServiceCollection services)
{
// ... configurations services.AddMiniProfiler(options =>{
// MiniProfiler'ın sağ altta görünmesi için options.PopupRenderPosition = RenderPosition.BottomLeft; options.PopupShowTimeWithChildren = true; }).AddEntityFramework(); // Here~!
}
Yukarıdaki adreste benim bu makalede kullandığım kaynak kodlar mevcut burada, Index açılırken bazı ef core sorguları yazacağım ve MiniProfiler verisini paylaşacağım.
public async Task <IActionResult> Index(){ var result = await _context.Students.Include(x => x.StudentCourses).ThenInclude(x => x.Course).Include(x => x.Address).AsNoTracking().Where(x => x.StudentCourses.Any(y => y.CourseId > 50) && x.Name.StartsWith("a") && x.Address.City.EndsWith("a")).OrderByDescending(x => x.Name).ToListAsync(); return View(result);}
Yukaridaki sorgu sonucunda MiniProfilerin bize söylediği aşağıdadır.
Yukarıda gördüğümüz gibi total duration 627.9 ms. Hangi aşamalarda ne kadar zaman harcandığı görünmekte, ayrıca entity framework core sorgusunun plain halide dialog sayfasında görünmektedir!
Custom Timings ve Timing Sections
Timing Segments
using (MiniProfiler.Current.Step("name string"))
Yukarıdaki satır ile çalışma planındaki kodları segmentlere bölüp analiz yapmanızı kolaylaştırabilirsiniz. Aşağıdaki ekran görüntüsündeki timing segmentler için MiniProfiler.Current.Step() kodu yazılmıştır. HomeControllerımızda yazılan kodu detaylı görebilirsiniz.
Custom Timings
Custom Timing için detail içerisinde görünen duration, with children, from start, sql gibi elemanlardır. Bu elemanlara yenisi eklemek için custom timing kullanılır. Ben http request’lerin yapıldığı http client üzerinden yapacağım. Yukarıdakı elemanları http ekleyerek duration ve detayları yazdıracağım. Bunun için http request’lerin yapıldığı base get metodunu aşağıdaki komutu ekliyorum.
using (MiniProfiler.Current.CustomTiming(
“http”, string.Empty, “Get”))
Kodun tamamı aşağıdaki gibidir. Bu classta http requestlerimizin yapildigini varsayabilirsiniz.
public static string Call(string text){ using (MiniProfiler.Current.CustomTiming(
“http”, string.Empty, “Get”))
{ var delay = new Random().Next(100, 400); Thread.Sleep(delay); return text; }}
Home controllerımızda çağırdıktan sonra sonuç aşağıdaki ekran görüntüsündeki gibidir. Görüldüğü üzere http (ms) eklenmiştir.
API üzerinde MiniProfiler
MiniProfiler sadece MVC uygulamarında değil, api uygulamarında da çalışmaktadır. Tek yapmamız gereken
public void ConfigureServices(IServiceCollection services)
{
// ... configurations // unutulmamalıdır.
services.AddMemoryCache(); // AddMiniProfiler metodu bir çok
//configuration parametresi almaktadır. services.AddMiniProfiler(options => {
options.RouteBasePath = "/profiler"; }).AddEntityFramework();
}
NOT : MiniProfiler da olan bir bugtan dolayı services.AddMemoryCache();
services.AddMiniProfiler()
satırından önce eklemeyi unutmamalıyız.
Configure()
metodunda UseMiniProfiler()
diyoruz.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ... codes app.UseMiniProfiler();
}
Artık kullanıma hazır! Tüm requestlere /profiler/result-index
adresinden erişilebiliriz.
Request’lere tıklayarak detaylı profiling sonucuna erişebliriz.
Extra
MiniProfilerın bir çok konfigurasyon ayarı bulunmakta. Başlıca sevdiğim özellikeri aşağıdaki satırlarda belirtiyor olacağım.
Belli kişilerin MiniProfilerı görmesini sağlayan konfigurasyon;
// (Optional) To control authorization, you can use the Func<HttpRequest, bool> options:
// (default is everyone can access profilers)
options.ResultsAuthorize = request => MyGetUserFunction(request).CanSeeMiniProfiler;
options.ResultsListAuthorize = request => MyGetUserFunction(request).CanSeeMiniProfiler;
Profile edilen dataları loglamak içindeMiniProfiler.Providers.SqlServer
paketini ekleyip, tabloları yaratıp aşağıdaki satır ile db bağlantısı ayarlanmaktadır.
options.Storage = new SqlServerStorage(Configuration.GetConnectionString(“AybMiniProfilerConnection”));
Tüm konfigurasyonlar aşağıdaki linke tıklayabilirsiniz.
MiniProfiler’ı ben test ortamlarımıza kurup kullanıyorum. Ancak Stack Overflow production ortamlarında da kullanmaktadır. Linkte MiniProfilerı kullanımı anlattıkları bölüm;
Bu yazıya başlamadan önce bulduğum harika bir sunumun linkini de buraya paylaşıyorum, yine Nick Craver tarafından :) 👏🏻
Kaynak kodlar;
Referans:
Umarım faydalı bir yazı olmuştur. Biz ekip olarak MiniProfiler’dan çok memnun kaldık. Adeta kodları optimize etmek bir oyuna döndü bizim için :)
Ayrıca yeni projelerimizde complex sorgular için MiniProfiler deneyimlerimizden sonra Dapper ile devam etme kararı aldık.