軟件產品經常會出現這樣的狀況:產品性能因某些沒法預料的瓶頸而受到干擾,致使程序的處理效率下降,性能得不到充分的發揮。如何快速有效地找到軟件產品的性能瓶頸,則是咱們感興趣的內容之一。web
在本文中,我將解釋我如何清理和替換重複、 混亂遍及許多方法在應用程序中的代碼使用ASP.NET Web API 的篩選器來完成ASP.NET Web API 接口執行時間監控。咱們的項目中有以下的需求:個人工做相關的項目 (使用 ASP.NET Web API 框架) 要求記錄下服務接口的調用執行時間以及請求延遲、 故障率每秒的請求總數,以幫助運營團隊。 api
Web API 篩選器是你放到Action上的自定義屬性方法 (或Controller) 添加經常使用功能。 Web API 篩選使您得以添加預處理和後處理的行爲,本文的代碼來自於How to intercept all the ASP.NET WebApi controller action methods calls with Ninject interception for logging? 和 Log duration of an ASP Web API action 。框架
下面是詳細代碼:ide
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Web;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;性能
namespace ContactManager.Filters
{
public class TimingActionFilter : ActionFilterAttribute
{
private const string Key = "__action_duration__";spa
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (SkipLogging(actionContext))
{
return;
}
var stopWatch = new Stopwatch();
actionContext.Request.Properties[Key] = stopWatch;
stopWatch.Start();
}pwa
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (!actionExecutedContext.Request.Properties.ContainsKey(Key))
{
return;
}orm
var stopWatch = actionExecutedContext.Request.Properties[Key] as Stopwatch;
if (stopWatch != null)
{
stopWatch.Stop();
var actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;
var controllerName = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName;
Debug.Print(string.Format("[Execution of{0}- {1} took {2}.]", controllerName, actionName, stopWatch.Elapsed));
}接口
}ip
private static bool SkipLogging(HttpActionContext actionContext)
{
return actionContext.ActionDescriptor.GetCustomAttributes<NoLogAttribute>().Any() ||
actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<NoLogAttribute>().Any();
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)]
public class NoLogAttribute : Attribute
{
}
}
而後在代碼裏註冊 GlobalConfiguration.Configuration.Filters.Add(new TimingActionFilter());