记录ASP.NET Web API 服务接口响应时间
实现起来很简单,一个Filter就可以搞定!!!
/// <summary> /// 监控接口执行时间 /// </summary> public class TimingActionFilter : ActionFilterAttribute { private static readonly Logger logger = LogManager.GetCurrentClassLogger(); private const string Key = "__action_duration__"; /// <summary> /// 启用计时器 /// </summary> /// <param name="actionContext"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public override Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken) { /* await Trace.WriteAsync("Executing action named {0} for request {1}.", actionContext.ActionDescriptor.ActionName,actionContext.Request.GetCorrelationId()); */ if (SkipLogging(actionContext)) { return base.OnActionExecutingAsync(actionContext, cancellationToken); } var stopWatch = new Stopwatch(); actionContext.Request.Properties[Key] = stopWatch; stopWatch.Start(); return base.OnActionExecutingAsync(actionContext, cancellationToken); } /// <summary> /// 记录监控接口执行日志 /// </summary> /// <param name="actionExecutedContext"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public override Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken) { if (!actionExecutedContext.Request.Properties.ContainsKey(Key)) { return base.OnActionExecutedAsync(actionExecutedContext, cancellationToken); } 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; string log = string.Format("[execution controller:{0} - action:{1} take {2} time.]", controllerName, actionName, stopWatch.Elapsed); #if DEBUG Debug.Print(log); #endif logger.Info(log); } return base.OnActionExecutedAsync(actionExecutedContext, cancellationToken); } private static bool SkipLogging(HttpActionContext actionContext) { return actionContext.ActionDescriptor.GetCustomAttributes<NoLogAttribute>().Any() || actionContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<NoLogAttribute>().Any(); } } /// <summary> /// 不记录监控接口执行日志 /// </summary> [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true)] public class NoLogAttribute : Attribute { }
WebApiConfig中启用
public static void Register(HttpConfiguration config) { //启用监控接口执行时间 //config.Filters.Add(new TimingActionFilter()); //启用全局验证 config.Filters.Add(new ModelValidFilter()); //启用特性路由 config.MapHttpAttributeRoutes(); //默认路由 config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); }
配置NLog记录响应时间超过1秒的接口服务
<target name="database" xsi:type="Database" connectionString="Data Source=xxx;Initial Catalog=WebAPI_Log;Persist Security Info=True;User ID=xxx;Password=xxx" commandText="insert into [WebAPI_Log]([CreateOn],[Origin],[LogLevel], [Message], [Exception],[StackTrace]) values (getdate(), @origin, @logLevel, @message,@exception, @stackTrace);"> <!--日志来源--> <parameter name="@origin" layout="${callsite}"/> <!--日志等级--> <parameter name="@logLevel" layout="${level}"/> <!--日志消息--> <parameter name="@message" layout="${message}"/> <!--异常信息--> <parameter name="@exception" layout="${exception}" /> <!--堆栈信息--> <parameter name="@stackTrace" layout="${stacktrace}"/> </target>
Refer:
http://www.cnblogs.com/shanyou/p/3308058.html
http://stackoverflow.com/questions/14062028/how-to-intercept-all-the-asp-net-webapi-controller-action-methods-calls-with-nin