惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

M
MIT News - Artificial intelligence
雷峰网
雷峰网
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
阮一峰的网络日志
阮一峰的网络日志
月光博客
月光博客
博客园 - Franky
腾讯CDC
T
Tailwind CSS Blog
Recent Announcements
Recent Announcements
V
V2EX
N
Netflix TechBlog - Medium
量子位
Jina AI
Jina AI
Y
Y Combinator Blog
The GitHub Blog
The GitHub Blog
G
Google Developers Blog
爱范儿
爱范儿
博客园 - 叶小钗
D
Docker
MongoDB | Blog
MongoDB | Blog
D
DataBreaches.Net
T
The Blog of Author Tim Ferriss

博客园 - JustRun

Webpack中publicPath设置 忘记Mysql的root密码怎么办? Visual Studio 2015上安装Entity Framework Power Tools Ubuntu下安装中文输入法 Ubuntu如何选择更新源 Orchard中如何配置远端发布 .Net缓存管理框架CacheManager 全新的membership框架Asp.net Identity(2)——绕不过的Claims 全新的membership框架Asp.net Identity(1)——.Net membership的历史 泛型使用中,解决类型转换问题 .Net中使用SendGrid Web Api发送邮件(附源码) 下一代Asp.net开发规范OWIN(3)—— Middleware 下一代Asp.net开发规范OWIN(2)—— Katana介绍以及使用 下一代Asp.net开发规范OWIN(1)—— OWIN产生的背景以及简单介绍 对象映射工具AutoMapper介绍 AngularJs中,如何在render完成之后,执行Js脚本 .Net Collection的一些理解——记录一次向实习生的答疑 代替Reflection(反射)的一些方法 使用PhoneGap开启移动开发之旅
使用Filter跟踪Asp.net MVC页面加载时间
JustRun · 2014-10-16 · via 博客园 - JustRun

2014-10-16 08:08  JustRun  阅读(3384)  评论()    收藏  举报

最近,客户一直反馈系统使用慢,有时候能够指出具体是哪个页面,有时候又只是笼统地反馈慢。这种问题就像是幽灵一样,非常不好处理。因为导致这种问题的因素非常之多,而且在开发工程中,很难模拟出实际运行是的环境。理论上,对于所有的页面做压力测试是个解决方案,但是这种方式的成本太高,又没有办法很快地定位和解决客户的问题。

最后,考虑通过创建Filter来在访问Action之前记录一个时间,在页面Render完成之后,再记录一下时间。通过比较这2个时间的差值来跟踪每个页面的加载性能。如果对于MVC中的Filter还不太熟悉,可以看这里Asp.net MVC使用Filter解除Session, Cookie等依赖,文章有对于Filter的介绍和使用。

言归正传,直接上代码。通过继承ActionFilterAttribute, 分别重写OnActionExecutingOnResultExecuted方法。

public class TrackPageLoadPerformanceAttribute : ActionFilterAttribute
   {

      //这里使用log4net来打印出结果
       private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

      //创建字典来记录开始时间,key是访问的线程Id.
       private readonly Dictionary<int, DateTime> _start = new Dictionary<int, DateTime>();

      //创建字典来记录当前访问的页面Url.
       private readonly Dictionary<int, string > _url = new Dictionary<int, string>();

       public override void OnActionExecuting(ActionExecutingContext filterContext)
       {
           //过滤掉ChildAction, 因为ChildAction实际上不是一个单独的页面
           if(filterContext.IsChildAction) return;

           var currentThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;

           try
           {
               _start.Add(currentThreadId, DateTime.Now);
               _url.Add(currentThreadId, filterContext.HttpContext.Request.Url == null
                   ? string.Empty
                   : filterContext.HttpContext.Request.Url.AbsoluteUri);
           }
           catch (Exception ex)
           {
               Log.Error(ex.ToString());
           }
       }

       public override void OnResultExecuted(ResultExecutedContext filterContext)
       {
           var currentThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
           if (!_start.ContainsKey(currentThreadId)) return;

           try
           {

                //计算出当前页面访问耗时
               var costSeconds = (DateTime.Now - _start[currentThreadId]).TotalSeconds;
               if (costSeconds > 2)//如果耗时超过2秒,就是用log4net打印出,具体是哪个页面访问超过了2秒,具体使用了多长时间。
               {
                   Log.Info(string.Format("Access the action more than 2 seconds. cost seconds {1}.  URL: {0}", _url[currentThreadId], costSeconds));
               }
           }
           catch (Exception ex)
           {
               Log.Error(ex.ToString());
           }
           finally
           {
               _start.Remove(currentThreadId);
               _url.Remove(currentThreadId);
           }
       }
   }

最后,将该Filter注册成Global Filter,这样,就能监控系统中所有页面的加载时间了.

image

如果你也遇到和我类似的性能问题,不妨试试,加上这个Filter, online系统中哪个页面慢,就能够一目了然了。
关于Asp.net MVC性能监控,还有这篇文章可能能帮到你。使用MiniProfiler给Asp.net MVC和Entity Framework号脉(附源码)

如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的推荐按钮。
如果,您希望更容易地发现我的新博客,不妨点击一下右下角的关注 Justrun
因为,我的写作热情也离不开您的肯定支持。

感谢您的阅读,这里还有你可能感兴趣的文章推荐博客文章