.Net Core MVC Bir Projede Actionların Çalışma Süresini Razor Ve Google Chart İle Raporlama

Selamlar Arkadaşlar,

Bu makalede yine herkesin ihtiyacı olabilecek bir konuyu tartışacağız. MVC bir web uygulamasında hangi sayfanın ortlama olarak ne kadar sürede geldiğini, ve ilgili sayfanın seçilmesi durumunda, detayına gidilerek son 10 kaydınını kronolojik olarak ekrana basıldığı uygulamayı hep beraber kodlayacağız. Bu raporlama için, Razor View Engine ve Google Chart kullanılarak animasyonlu bir hale getirilecektir.  Bu yapı istenirse çalışma süresi, örneğin 2sn’den fazla olan Actionların yöneticiye mail atılarak bildirildiği, yani projenin monitör edilerek sorunlu yerlerin bildirildiği bir yapı olarak da kullanılabilir.

Gelin önce aşağıda görüldüğü gibi “ActionTotalTime” adında .Net Core Mvc bir proje oluşturalım.

dotnet new mvc -o ActionTotalTime

Bu projede farklı dummy birçok sayfamız olacak.

Amaç, farklı sayfaların                                açılış performancelarını gözlemlemektir. Bunun için her sayfaya ait Actionlar içerisine random olarak oluşturulucak bekleme süreli aşağıdaki gibi konulmuştur.

Bazı örnek amaçlı dummy sayfalara giden actionlar aşağıdaki gibidir:

HomeController.cs: Görüldüğü gibi tüm actionlarda ==>”System.Threading.Thread.Sleep(GenerateWaitTime() * 1000)” random maximum 5sn ye kadar bekleten threadler kullanılmıştır.

Şimdi sıra geldi, DB’de tutulacak Data Model’e. Aşağıda Actionların çalışma zamanı ile ilgili tutlacak data model(Action Performance) tanımlanmıştır.

ActionPerformance.cs: 

Bu projede DB işlemleri için EntityFrameWork DBContext kullanılmıştır.

ActionContext.cs: İlgili modelin DB karşılığı burada tanımlanmıştır.

Ölçüm:

Şimdi sıra geldi Actionların çalışma zamanını ölçmeye. Bu işlem için bu projede Action Filter kullanılmıştır.

  • TimerFilter” olarak tanımlayacağımız action filter, Action’a ilk girildiği andaki zamanı [“Controller_Action”] isminden key oluşturarak,  “HttpContext” altında tutmaktadır. Actiona ilk girildiği zaman “OnActionExecuting()” methodu çağrılmaktadır.
  • İlgili Action’dan çıkıldığı zaman, bir başka değiş ile sonlanması sırasında  “OnActionExecuted()” metodu çağrılmaktadır. Burada “HttpContext”‘den action’a ilk girilen zaman çekilir.(startTime) Şu anki zaman (endTime) ile zaman farkı alınarak, Action için harcanan toplam zaman bulunur (“TimeSpan“).
  • Action için harcanan toplam zamanı saniye cinsinden, action ve controller’ın ismi, işlemin yapıldığı zaman ve saat_dakika_saniye cinsinden geçen zamanın açıklaması “ActionPerformance” tabosuna kaydedilir.

TimerFilter.cs:

Not: Şimdi sırada Raporlama ekranı var. Ama öncesinde aklınıza şöyle bir soru gelebilir. Bazı ekranlar için DB’ye kayıt atmak istemezsek, örneğin Raporlama ekranı için log tutmak istemezsek ne yapmalıyız? Bunun için farklı bir çok yol var. Örneğin bir black list yapıp, bunu ya config’de ya da DB’de tutup, ilgili sayfa bu listede var ise log tutulmayabilir. Ama bundan daha şık yollar da var. O da, bir attribute yapıp, bununla işaretli olan  Actionları kayıt altına almamak yani loglamamaktır. Kısaca Custom bir Attribute yazacağız ve bunu loglanmasını istemediğimiz Actionların üstüne koyacağız.

IgnoreAction.cs: Bu Attribute sadece loglanmıyacak Actionları, flaglemek için kullanılmıştır.

Şimdi gelin TimerFilter class’ını aşağıdaki gibi güncelleyelim.

TimerFilter.cs(Full): 

  • HasIgnoreAction()” : Mehod üzerindeki tüm “CustomAttribute”‘ler gezilerek  tipi “IgnoreAction” olan var mı diye bakılarak, “true” veya “false” olarak bir sonuç geri dönülür.
  • “OnActionExecuting()” Methodunda HasIgnoreAction() methodundaki sonuca göre “context.HttpContext.Items[“HasIgnoreAction”]” değer atılır.
  • “OnActionExecuted()” : Methodunda “if ((bool)context.HttpContext.Items[“HasIgnoreAction”]==false)” bakılır. Eğere ilgili Attribute yok ise Loglama işlemine devam edilir.

Report :

ReportModel.cs: Raporlama sayfası için kullanılacak data model aşağıdaki gibidir.

Report(): İlgili Controller’a ait Actionların “TotalSeconds” yani sayfanın açılış süresine göre bir Rapor datası çekilmiştir.

  • İlgili action, Custom Attribute olan ” [IgnoreAction]” ile işaretlenmiştir. Bu neden ile çalışma süresi loglanmıyacaktır.
  • Aşağıda görüldüğü gibi Raporlama amaçlı ilgili  “Controller/Action“‘a göre bir guruplama yapılmış ve “TotalSeconds” alanının Ortalaması alınmıştır.
  • Çekilen tüm data “ForEach()” ile dönülerek, View tarafında da beklenen “List<ReportModel>” tipindeki “viewModel“‘e ilgili datalar atılmıştır.
  • Report.cshtml View’a, doldurulan “viewModel” ile dönülür.

Report.cshtml: Raporlama amaçlı Razor View engine ile birlikte “Google Chart” kullanılmıştır. Google Chart en çok kullanılan toolardan biri olsa da offline kullanılmaya izin vermemesi büyük bir dezavantaj.

  • Sayfa model olarak “List<ReportModel>” beklemektedir.
  • Sayfa içerisinde kullanılacak scriptler, externel Url ile tanımlanmıştır. Araştırdığı kadarı ile Google Chart offline kullanılmaya izin vermiyor. “google.load()” methodu offline malesef işe yaramıyor.
  • @foreach (var item in Model)” ile tüm kayıt dönülerek ekrana basılmıştır.
  • <text>[‘@item.Name’, @item.TotalSeconds,’@color’],</text>” : Action ismi ve ortalama işlem süresi herbir kayıt için basılır.
  • var color = String.Format(“#{0:X6}”, random.Next(0x1000000))” : Her seferinde ilgili bar rengi, Random olarak ekrana basılır.
  • ” var options = { animation:{ startup:true, duration: 1000, easing: ‘out’,”: Animasyon işlemleri burada yapılır. Amaç barların animatif olarak 1sn süresince gelmesidir. “startup:true”‘nun konulması önemlidir. Yoksa animasyon çalışmayacaktır.
  • curveType“: Burada X ve Y kordinatlarındaki başlık, sitil ve max-min değerleri ayarlanmaktadır.
  • google.visualization.events.addListener(chartPerformance, ‘select’, selectAction)” : İlgili charter’ın “select” event’i dinlenir ve herhangi bir bar’ın tıklanması durumunda “selectAction()” methodu çağrılır.
  • selectAction()“: İlgili methodda ==>
    • “var selectedBar = chartPerformance.getSelection()[0]” : Seçilen bar’ın datası alınır.
    • window.location.href=”/Home/Detail/”+selectedAction.replace(/\//g,’_’)” : Controller ve Action’ın parametre olarak gönderilerek, Detay sayfasına yönlenilir.

Detail(): Bu method’da da görüldüğü gibi “[IgnoreAction]” custom Attribute’ü ile işaretlenmiştir. Amaç bu Action için de performans kaydının tutulmamasıdır.

  • ViewBag.Action’a gelen “Controller/Action” şeklinde Detayı gösterilen sayfa tanımlanır.
  • ActionPerformance tablosundan ilgili Action ve Controller’a göre son 10 kayıt çekilir.
  • Çekilen her bir kayıt gezilerek “List<DetailModel> viewModel”‘e doldurularak Detay sayfasına gidilir.

Detail.cshtml: Seçilen Action’ı ait son 10 kayıt Google Chart’da “List<DetailModel>” ile yukarıdaki gibi animatif olarak gösterilir.

Son olarak uygulamanın “1923” portundan çalışması için Program.cs’deki “CreateWebHostBuilder()” aşağıdaki gibi düzenlenir.

Program.cs:

Geldik bir makalenin daha sonuna. Bu makalede Custom Filterlar kullanılarak, minimum Code ile Maximum iş ilkesine bağlı kalınarak, bir mvc projede istenen Actionların total çalışma zamanı ölçülmüş ve bir Sql DB’ye yazılmıştır. Ölçülmek istenmeyen Actionlar, Custom bir Attribute([IgnoreAction]) ile işaretlenmiş ve  ilgili Action Filter’da(TimerFilter) işleme tabi tutulmamışlardır. Ölçüm yapılan tüm Actionlar, bir Raporlama ekranında Google Chart ile hareketli grafikler halinde gösterilmiştir. Ayrıca yine istenen Action’ın detayına tıklanılması sureti ile, Detail sayfasında son 10 kaydı olacak şekilde gösterilmiştir.

İstenir ise bu sistem, belli bir Rule yapısı çalıştırılarak, örneğin çalışma süresi 3sn den fazla Actionlar tespit edilerek, Admin’e mail veya Sms atan bir monitoring sisteme çevirilebilir.

Yeni bir makalede görüşmek üzere hepinize hoşçakalın.

Source Code : https://github.com/borakasmer/MonitorActionExecutionTime

Herkes Görsün:

Bunlar da hoşunuza gidebilir...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir