2009-12-01 49 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