Fork me on GitHub

记录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

posted @ 2015-10-21 15:52  花儿笑弯了腰  阅读(3783)  评论(1编辑  收藏  举报