2009-12-01 8 views
15

Je cherche un moyen de savoir combien de temps il a fallu pour qu'une page soit générée par le serveur. Je sais que je peux utiliser Trace pour suivre cela, mais j'ai besoin d'un moyen de l'afficher par page.Temps de génération de page - ASP.Net MVC

Son ASP.Net MVC 2

Répondre

14

Yep Suggestion Derin est le moyen standard pour le faire dans une application ASP.NEt, je voudrais simplement suggérer d'ajouter un s'il ne gêne pas les réponses non HTML: EDIT: implémentation complète ajoutée ion

public class PerformanceMonitorModule : IHttpModule 
{ 

    public void Init(HttpApplication context) 
    { 
     context.PreRequestHandlerExecute += delegate(object sender, EventArgs e) 
     { 
      //Set Page Timer Star 
      HttpContext requestContext = ((HttpApplication)sender).Context; 
      Stopwatch timer = new Stopwatch(); 
      requestContext.Items["Timer"] = timer; 
      timer.Start(); 
      }; 
     context.PostRequestHandlerExecute += delegate(object sender, EventArgs e) 
     { 

      HttpContext httpContext = ((HttpApplication)sender).Context; 
      HttpResponse response = httpContext.Response; 
      Stopwatch timer = (Stopwatch)httpContext.Items["Timer"]; 
      timer.Stop(); 

      // Don't interfere with non-HTML responses 
      if (response.ContentType == "text/html") 
      { 
       double seconds = (double)timer.ElapsedTicks/Stopwatch.Frequency; 
       string result_time = string.Format("{0:F4} sec ", seconds); 
       RenderQueriesToResponse(response,result_time); 
      } 
     }; 
    } 
    void RenderQueriesToResponse(HttpResponse response, string result_time) 
    { 
     response.Write("<div style=\"margin: 5px; background-color: #FFFF00\""); 
     response.Write(string.Format("<b>Page Generated in "+ result_time)); 
     response.Write("</div>"); 
    } 
    public void Dispose() { /* Not needed */ } 
} 

vous pouvez également ajouter un peu de style à elle ...

Et rappelez-vous d'enregistrer votre module à l'intérieur WebConfig httpModules Section:

<add name="Name" type="namespace, dll"/> 

Pour une référence complète au sujet de cette vérification, la Pro ASP.NET MVC Framework par Steven Sanderson - Chapitre 15 - Performances, surveillance des temps de génération de pages.

EDIT: (commentaire @Pino) ​​ Voici l'exemple pour mon projet: alt text http://www.diarioplus.com/files/pictures/example_performance.JPG

+0

Merci - fonctionne bien sauf cela semble sortir après l'élément qui casse ma page :(suggestions? – LiamB

+0

Ceci est ajouté (append) dans le cadre de la réponse, il peut ne pas être après la balise de fermeture HTML – JOBG

+0

Je modifie mon message avec un img d'exemple, j'ai déjà un projet en cours d'exécution et le tester, je ne sais pas pourquoi Darin a dit son après le HTML ..?, peut-être il se référait à une autre mise en œuvre – JOBG

4

Cela dépendra de l'endroit où vous souhaitez inclure ces informations. Par exemple, vous pouvez écrire un gestionnaire http qui affichera le temps de rendu après la balise </html>:

public class RenderTimeModule : IHttpModule 
{ 
    public void Init(HttpApplication context) 
    { 
     context.BeginRequest += (sender, e) => 
     { 
      var watch = new Stopwatch(); 
      var app = (HttpApplication)sender; 
      app.Context.Items["Stopwatch"] = watch; 
      watch.Start(); 
     }; 

     context.EndRequest += (sender, e) => 
     { 
      var app = (HttpApplication)sender; 
      var watch = (Stopwatch)app.Context.Items["Stopwatch"]; 
      watch.Stop(); 
      var ts = watch.Elapsed; 
      string elapsedTime = String.Format("{0} ms", ts.TotalMilliseconds); 
      app.Context.Response.Write(elapsedTime); 
     }; 
    } 

    public void Dispose() 
    { 
    } 
} 

Si vous souhaitez afficher le temps de rendu quelque part au milieu de la page html alors ce temps de rendu ne sera pas compte de la temps total de rendu de la page.

+0

Cela semble sortie après l'élément qui casse ma page :(suggestions – LiamB

+0

Oui, c'est ce que je disais dans mon Vous pouvez le mettre dans un commentaire si vous ne voulez pas casser votre validation –

+0

Est-ce que cette approche fonctionnera avec JSON et les résultats de fichier ou juste html? –

15

Vous pouvez la mettre en œuvre comme un ActionFilterAttribute

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] 
public class LoggingAttribute : ActionFilterAttribute 
{ 
    private readonly Stopwatch _sw; 

    public LoggingAttribute() 
    { 
     _sw = new Stopwatch(); 
    } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     _sw.Start(); 
     Debug.WriteLine("Beginning executing: " + GetControllerAndActionName(filterContext.ActionDescriptor)); 
    } 

    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     _sw.Stop(); 
     var ms = _sw.ElapsedMilliseconds; 

     Debug.WriteLine("Finishing executing: " + GetControllerAndActionName(filterContext.ActionDescriptor)); 
     Debug.WriteLine("Time elapsed: "+ TimeSpan.FromMilliseconds(ms).TotalSeconds); 
    } 

    private string GetControllerAndActionName(ActionDescriptor actionDescriptor) 
    { 
     return actionDescriptor.ControllerDescriptor.ControllerName + " - " + actionDescriptor.ActionName; 
    } 
} 

Décore chaque contrôleur ou action avec méthode et le tour est joué, il a craché outs le texte de débogage.

EDIT: Si vous voulez imprimer sur la page que vous pouvez ajouter cet extrait à la méthode OnActionExecuted

if(filterContext.Result is ViewResult) { //Make sure the request is a ViewResult, ie. a page 
    ((ViewResult) filterContext.Result).ViewData["ExecutionTime"] = ms; //Set the viewdata dictionary 
} 

Maintenant, vous avez le EXECUTIONTIME enregistré dans ViewData et peut y accéder à la page .. Je habituellement mettre dans le masterpage comme celui-ci

<!-- The page took <%= ViewData["ExecutionTime"] %> ms to execute --> 
+0

Décorer chaque contrôleur ou action-méthode est un peu une douleur comme nous avoir beaucoup (Assez grand projet) - de toute façon nous pouvons faire ce site de travail large sans faire un si grand changement? – LiamB

+3

Dans mon projeect tous mes contrôleurs hérite d'un BaseController . Je décore donc le basecontroller, qui à son tour "décore" toutes les actions-méthodes en cours d'exécution. –

+2

Son approche assez bonne, il vaut la peine de mentionner que cela fait un suivi de la durée de vie du contrôleur, et non la durée de vie totale de la demande. – JOBG

Questions connexes