2009-12-01 17 views
15

私は、サーバーがページを生成するのにかかった時間を追跡する方法を探しています。私はこれを追跡するためにトレースを使用することができますが、私はページごとにこれを表示する方法が必要です。ページの生成時間 - ASP.Net MVC

そのASP.Net MVC 2

答えて

14

のようにマスターページにそれを置きます EDIT:完全な実装を追加イオン

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章 - パフォーマンス、モニタリングページの生成時間。

EDIT:(@Pinoコメント) ここでは、私のプロジェクトのための例です:? alt text http://www.diarioplus.com/files/pictures/example_performance.JPG

+0

ありがとうございます - これは私のページを壊す要素の後に出力されたようです:(提案? – LiamB

+0

これは応答の一部として追加(追加)され、HTML終了タグの後にはない可能性があります – JOBG

+0

私の投稿を編集しますサンプルimgを使って、私はすでにプロジェクトを実行してテストしていますが、なぜダーリンがHTMLの後に言ったのかわからないのですが、おそらく彼は別の実装を参照したでしょうか? – JOBG

4

これは、この情報をどこに含めるかによって異なります。あなたは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>タグの後、レンダリング時間が表示されますHTTPハンドラを書くことができ総ページレンダリング時間。

+0

は、これは私のページ:(提案を壊す要素の後に出力するようだ – LiamB

+0

はい、それは私が私に言いました –

+0

このアプローチはJsonとFileの結果、または単にhtmlで動作するのでしょうか? –

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; 
    } 
} 

のようにそれを実装することができ、それがアウトにデバッグ中のテキストを吐きます。

EDIT:あなたはページ上に印刷したい場合は、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 
} 

にこのスニペットを追加することができます今、あなたはViewDataをに保存されてExecutionTimeがあると私は通常..ページにアクセスすることができます:デリン提案がASP.NEtアプリケーションでそれを行うための標準的な方法で、私はちょうどそれが非HTMLレスポンスに干渉しないようならば追加を示唆しているうん、この

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

すべてのコントローラやアクションメソッドを飾ることはちょっと難しいことです(かなり大きいプロジェクト) - とにかく私たちはこのような大きな変更を加えることなく、この作業サイトを幅広くすることができますか? – LiamB

+3

私のプロジェクトでは、すべてのコントローラがBaseControllerから継承しています。だから、私はちょうど実行されているすべてのアクションメソッドを「装飾する」basecontrollerを装飾するだけです。 –

+2

これはかなり良いアプローチです。これは、実際にはコントローラのライフタイムを追跡するものであり、要求ライフタイムの合計ではないことに言及するだけの価値があります。 – JOBG

関連する問題