2009-12-01 72 views
15

我正在尋找一種方法來跟蹤服務器生成一個頁面需要多長時間。我知道我可以使用跟蹤來跟蹤這個,但我需要一種方法來顯示每頁。頁面生成時間 - ASP.Net MVC

它的ASP.Net MVC 2

回答

14

沒錯的Derin建議是標準的方式做到這一點在ASP.NEt應用程序,我只想建議增加一個,如果因此它不會與非HTML響應的干擾:編輯:添加完整的實現離子

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 */ } 
} 

,你還可以添加一些樣式,...

記住註冊的HttpModules里科WebConfig你的模塊:

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

對於一個完整的參考這個檢查Pro ASP.NET MVC框架作者:Steven Sanderson - 第15章 - 性能,監控頁面生成時間。

編輯:我在說 alt text http://www.diarioplus.com/files/pictures/example_performance.JPG

+0

謝謝 - 效果很好,除了這似乎輸出後,打破我的網頁:(建議? – LiamB 2009-12-01 15:46:17

+0

元素作爲響應的一部分添加(追加),它可能不是HTML結束標記後 – JOBG 2009-12-01 15:58:50

+0

我編輯我的帖子有一個樣本img,我已經有一個項目正在運行並測試它,我不知道爲什麼Darin在HTML之後說過它.. ?,也許他提到了另一個實現。 – JOBG 2009-12-01 16:10:04

4

這取決於你想包含這些信息的地方。例如,你可以寫一個HTTP處理程序將顯示</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() 
    { 
    } 
} 

如果你想顯示在HTML頁面的中間位置渲染時間那麼這個渲染時間將不佔總頁面渲染時間。

+0

這似乎輸出,打破我的頁面元素之後:(建議 – LiamB 2009-12-01 15:45:46

+0

是的,這是我的:(評論@Pino) 這裏是我的項目的例子嗎?後,你可以把它放在一個評論,如果你不想破壞你的驗證。 – 2009-12-01 16:45:49

+0

請問使用JSON和文件的結果,或只是HTML? – 2009-12-01 17:21:35

15

您可以實現它像一個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; 
    } 
} 

裝飾每個控制器或動作方法與它瞧,它吐奏在調試中的文本。

編輯:如果您想打印的頁面上,可以將這個片段添加到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 
} 

現在你有executiontime保存在ViewData的,並且可以在頁面訪問它。我平時把它放在母版這樣

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

裝飾每個控制器或動作方法這種方法工作是一個有點痛苦,因爲我們的有很多的(相當大的項目) - 無論如何,我們可以使這項工作網站廣泛不做大的變化 – LiamB 2009-12-01 15:50:33

+3

在我projeect我的所有控制器從BaseController繼承。所以我只裝飾basecontroller,它反過來「裝飾」所有正在執行的動作方法。 – 2009-12-01 15:53:43

+2

它很不錯的方法,它只是值得一提的,這實際上跟蹤控制器的續航時間,而不是總要求續航時間。 – JOBG 2009-12-01 16:50:46