Un modo estremamente rapido e preciso per monitorare i tempi di generazione di pagine ASP.NET (o ASP.NET MVC) consiste nell'implementare un HttpModule in grado di intercettare gli eventi di inizio e fine richiesta, chiamati rispettivamente PreRequestHandlerExecute e PostRequestHandlerExecute. Il primo viene invocato immediatamente prima dell'avvio dell'esecuzione della pagina, mentre l'esecuzione del secondo scatta al termine dell'elaborazione della pagina stessa.
public class PageMonitorModule : IHttpModule { private const string TIMER_NAME = "_PAGE_GENERATION_TIMER"; public void Init(HttpApplication context) { context.PreRequestHandlerExecute += delegate(object sender, EventArgs e) { HttpContext requestContext = ((HttpApplication) sender).Context; Stopwatch timer = new Stopwatch(); requestContext.Items[TIMER_NAME] = timer; timer.Start(); }; context.PostRequestHandlerExecute += delegate(object sender, EventArgs e) { HttpContext requestContext = ((HttpApplication)sender).Context; if (requestContext.Items[TIMER_NAME] != null) { Stopwatch timer = (Stopwatch) requestContext.Items[TIMER_NAME]; timer.Stop(); if (requestContext.Response.ContentType == "text/html") { double seconds = PerformCalc(timer); ShowElapsedTime(requestContext, seconds); } } }; } public void Dispose() { } }
In corrispondenza di questi due eventi è necessario implementare la logica necessaria per il calcolo del tempo di generazione della pagina. Per questo fine abbiamo utilizzato la classe Stopwatch, appartenente al namespace System.Diagnostics, che ci consente di calcolare in modo preciso e semplice questo valore.
Tutto ciò che dobbiamo fare, infatti, è istanziare un timer durante l'evento PreRequestHandlerExecute, avendo cura di memorizzarlo all'interno della collection HttpContext.Items, affinchè possiamo recuperarlo nel successivo evento di PostRequestHandlerExecute. In corrispondenza di quest'ultimo, infine, possiamo finalmente fermarlo e avviare il calcolo:
public double PerformCalc(StopWatch timer) { return (double) timer.ElapsedTicks / Stopwatch.Frequency; }
Il valore così ottenuto potrà essere scritto in un file di log per una successiva consultazione, o visualizzato a video, come nel nostro caso:
public void ShowElapsedTime(HttpContext requestContext, double seconds) { string result = string.Format( "Page generation time: {0:F6} sec. ({1:F0} req./sec.)", seconds, 1 / seconds); requestContext.Response.Write(string.Format("<div id=\"pageTimer\">{0}</div>", result)); }
Ricordiamo che gli HttpModule vanno registrati nel web.config, tramite l'impostazione seguente:
<httpModules> <add name="PageMonitorModule" type="PageMonitorModule.PageMonitorModule, PageMonitorModule" /> </httpModules>
Nel caso di un sito in esecuzione su IIS7 in Integrated Pipeline, la medesima stringa dovrà essere inserita all'interno della sezione system.webserver/modules.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Sviluppare un'interfaccia utente in React con Tailwind CSS e Preline UI
Usare il versioning con i controller di ASP.NET Core Web API
Come EF 8 ha ottimizzato le query che usano il metodo Contains
Gestire liste di tipi semplici con Entity Framework Core
Potenziare Azure AI Search con la ricerca vettoriale
Implementare il throttling in ASP.NET Core
Utilizzare domini personalizzati gestiti automaticamente con Azure Container Apps
Semplificare il deployment di siti statici con Azure Static Web App
Applicare il versioning ai nostri endpoint ASP.NET Core Minimal API
Effettuare il deploy di immagini solo da container registry approvati in Kubernetes
Load test di ASP.NET Core con k6
Usare un KeyedService di default in ASP.NET Core 8
I più letti di oggi
- Utilizzare WebAssembly con .NET, ovunque
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- Ottimizzare le performance delle collection con le classi FrozenSet e FrozenDictionary
- Utilizzare il trigger SQL con le Azure Function
- Disabilitare automaticamente un workflow di GitHub (parte 2)
- Ottimizzazione dei block template in Angular 17
- Paginare i risultati con QuickGrid in Blazor