記録ASP.NET Web APIサービスインタフェース応答時間

8110 ワード

実現するのは簡単で、1つの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