博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MiniProfiler,一个.NET简单但有效的微型分析器
阅读量:4034 次
发布时间:2019-05-24

本文共 6033 字,大约阅读时间需要 20 分钟。

背景

MVC MiniProfiler是Stack Overflow团队设计的一款对ASP.NET MVC的性能分析的小程序。可以对一个页面本身,及该页面通过直接引用、Ajax、Iframe形式访问的其它页面进行监控,监控内容包括数据库内容,并可以显示数据库访问的SQL(支持EF、EF CodeFirst等 )。并且以很友好的方式展现在页面上。

该Profiler的一个特别有用的功能是它与数据库框架的集成。除了.NET原生的 DbConnection类,profiler还内置了对实体框架(Entity Framework)以及LINQ to SQL的支持。任何执行的Step都会包括当时查询的次数和所花费的时间。为了检测常见的错误,如N+1反模式,profiler将检测仅有参数值存在差 异的多个查询。

MiniProfiler是以Apache License V2.0协议发布的,你可以在NuGet找到。配置及使用可以看这里:http://code.google.com/p/mvc-mini-profiler

概述

在WebApi中,对其性能进行分析监测是很有必要的。而悲剧的是,MVC项目中可以使用的MiniProfiler或Glimpse等,这些都不支持WebApi项目,而且WebApi项目通常也没有界面,不能进行性能分析的交互。在这篇文章中,我们就来一步步实现为WebApi项目集成Miniprofiler。集成后,我们可以监控EF执行效率,执行语句,页面执行时间等,这些结果将以很友好的方式显示在界面上。

问题

本质上,集成Miniprofiler可以分解为三个问题:

  1. 怎样监测一个WebApi项目的性能。

  2. 将性能分析监测信息从后端发送到UI。

  3. 在UI显示分析监测结果。

实现方式

首先安装Miniprofiler,MiniProfiler.EF6

在Global.asax  加入

using BQoolCommon.Helpers.Model;using Elmah;using ResearchManager.Web.App_Start;using System;using System.Configuration;using System.Web;using System.Web.Mvc;using System.Web.Routing;using StackExchange.Profiling;using StackExchange.Profiling.Mvc;using StackExchange.Profiling.EntityFramework6;using System.Web.Optimization;using NLog;using ResearchManager.Models.ValidateAttribute;namespace ResearchManager.Web{    public class MvcApplication : HttpApplication    {        protected void Application_Start()        {            AreaRegistration.RegisterAllAreas();            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);            RouteConfig.RegisterRoutes(RouteTable.Routes);            BundleConfig.RegisterBundles(BundleTable.Bundles);            //Remove Header X-AspNetMvc-Version            MvcHandler.DisableMvcResponseHeader = true;            AutofacConfig.Bootstrapper();            //在 Controller 之前對 Model 做處理(字串 Trim)            ModelBinders.Binders.DefaultBinder = new BQoolModelBinder();            //註冊自訂的 Validation (複寫預設的錯誤訊息)            CustomerValidation.RegisterCustomerValidation();            DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(CustomizedRequired), typeof(RequiredAttributeAdapter));            DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(CustomizedStringLength), typeof(StringLengthAttributeAdapter));            #region 测试            //if (bool.Parse(ConfigurationManager.AppSettings["MiniProfiler"] ?? "false"))            //{            MiniProfiler.Configure(new MiniProfilerOptions            {                RouteBasePath = "~/profiler",                PopupRenderPosition = RenderPosition.Right,  // defaults to left                PopupMaxTracesToShow = 10,                   // defaults to 15                ResultsAuthorize = request => request.IsLocal,                ResultsListAuthorize = request =>              {                  return true; // all requests are legit in this example              },                // Stack trace settings                StackMaxLength = 256, // default is 120 characters                TrackConnectionOpenClose = true            }                .ExcludeType("SessionFactory")  // Ignore any class with the name of SessionFactory)               .ExcludeAssembly("NHibernate")  // Ignore any assembly named NHibernate               .ExcludeMethod("Flush")         // Ignore any method with the name of Flush               .AddViewProfiling()              // Add MVC view profiling (you want this)                             );            MiniProfilerEF6.Initialize();            //}            #endregion 测试        }        protected void Application_BeginRequest(Object source, EventArgs e)        {            BundleTable.EnableOptimizations = false;            #region 测试            MiniProfiler.StartNew();            #endregion 测试        }        protected void Application_EndRequest()        {            #region 测试            //MiniProfiler.Current?.Stop(); // Be sure to stop the profiler!            #endregion 测试        }        #region Elmah        private static readonly string _exceptionMsg = "A potentially dangerous Request.Path value was detected from the client";        protected void Application_Error(object sender, EventArgs e)        {            Exception ex = Server.GetLastError();            Logger nlogger = LogManager.GetCurrentClassLogger();            nlogger.Error(ex);            if (BQoolCommon.Helpers.Setting.CommonSetting.IsProd())            {                if (e is ExceptionFilterEventArgs exceptionFilter)                {                    if (exceptionFilter.Exception is HttpException httpException && httpException.Message.StartsWith(_exceptionMsg))                    {                        Response.Redirect("/");                    }                }                Response.Clear();                Server.ClearError();                Response.StatusCode = 404;            }        }        ///         /// 排除 Elmah 404 寄信通知        ///         public void ErrorMail_Filtering(object sender, ExceptionFilterEventArgs e)        {            if (e.Exception is HttpException httpException && (httpException.GetHttpCode() == 404 || httpException.Message.StartsWith(_exceptionMsg)))            {                e.Dismiss();            }        }        ///         /// 自定 Elmah 發信主旨        ///         private void ErrorMail_Mailing(object sender, Elmah.ErrorMailEventArgs e)        {            string machineName = "none server";            try            {                if (Request != null)                {                    machineName = Request.ServerVariables["HTTP_HOST"];                }            }            catch            {            }            // 取得 Elamh ErrorMail 的主旨            // "$MachineName$ at $ErrorTime$ : {0}"            string elmahSubject = e.Mail.Subject;            //替換 ErrorMail 的主旨內容            string emailSubject = string.Format("ResearchManager.Web Error => {0}",                elmahSubject                    .Replace("$MachineName$", machineName)            );            e.Mail.Subject = emailSubject;        }        #endregion Elmah    }}

运行效果

运行项目,http://localhost//profiler/results-index  即可看到监测结果

转载地址:http://azudi.baihongyu.com/

你可能感兴趣的文章
Variable property attributes or Modifiers in iOS
查看>>
NSNotificationCenter 用法总结
查看>>
C primer plus 基础总结(一)
查看>>
剑指offer算法题分析与整理(一)
查看>>
剑指offer算法题分析与整理(三)
查看>>
Ubuntu 13.10使用fcitx输入法
查看>>
pidgin-lwqq 安装
查看>>
mint/ubuntu安装搜狗输入法
查看>>
C++动态申请数组和参数传递问题
查看>>
opencv学习——在MFC中读取和显示图像
查看>>
retext出现Could not parse file contents, check if you have the necessary module installed解决方案
查看>>
pyQt不同窗体间的值传递(一)——对话框关闭时返回值给主窗口
查看>>
linux mint下使用外部SMTP(如网易yeah.net)发邮件
查看>>
北京联通华为光猫HG8346R破解改桥接
查看>>
python使用win32*模块模拟人工操作——城通网盘下载器(一)
查看>>
python append 与浅拷贝
查看>>
Matlab与CUDA C的混合编程配置出现的问题及解决方案
查看>>
python自动化工具之pywinauto(零)
查看>>
python一句话之利用文件对话框获取文件路径
查看>>
PaperDownloader——文献命名6起来
查看>>