簡體   English   中英

如何使用ActionFilterAttribute記錄運行時間?

[英]How to use ActionFilterAttribute to log running times?

我創建了一個動作過濾器,用於測量Web API v2中每個操作的運行時間。

public class RunningTimeAttribute : ActionFilterAttribute
    {
        private readonly ILogFactory _logFactory;
        private readonly ITimerFactory _timerFactory;
        private ITimer _timer;
        private ILogger _logger;

        public RunningTimeAttribute(ILogFactory logFactory, ITimerFactory timerFactory) {
            if(logFactory == null)
                throw new ArgumentNullException("logFactory");
            if(timerFactory == null)
                throw new ArgumentNullException("timerFactory");

            _logFactory = logFactory;
            _timerFactory = timerFactory;
        }

        public override void OnActionExecuting(HttpActionContext actionContext) {
            base.OnActionExecuting(actionContext);
            OnBeforeAction(actionContext);
        }

        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) {
            OnAfterAction(actionExecutedContext);
            base.OnActionExecuted(actionExecutedContext);
        }

        private void OnBeforeAction(HttpActionContext actionContext) {
            var controllerName = actionContext.ControllerContext.Controller.GetType().FullName;
            var actionName = actionContext.ActionDescriptor.ActionName;

            _logger = _logFactory.Create(controllerName);
            _logger.Trace("Action \"{0}\" begins execution", actionName);

            _timer = _timerFactory.Create();
            _timer.Start();
        }

        private void OnAfterAction(HttpActionExecutedContext actionExecutedContext) {
            var actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;

            _timer.Stop();
            _logger.Trace("Time elapsed for action \"{0}\": {1} msec", actionName, _timer.ElapsedMilliseconds);
        }

}

但是,動作過濾器充當單例,因此當OnActionExecuted運行時,我無法確定_logger_timer對應於為同一動作OnActionExecuting創建的那些。

例如。

  1. Action Foo1開始執行。 _logger = "logger1"_timer = "timer1"
  2. Action Foo2開始執行。 _logger = "logger2"_timer = "timer2" (它們被覆蓋)
  3. Action Foo1結束執行。 它會停止計時器並記錄經過的時間,這是無意義的(end1-start2)。

問題OnActionExecuted是否有一種方式可以OnActionExecuting它對應的OnActionExecuting 如果有一些唯一的動作標識符,我可以將它用作Dictionary的一個鍵來存儲任何與動作相關的對象,如記錄器和定時器。 有沒有? 或其他一些解決方案?

就Web API而言,並不總能保證System.Web.HttpContext.Current 這取決於您是否使用Web API Self托管。 這是重寫System.Web.Http.Filters.ActionFilterAttribute.OnActionExecuting你沒有在HttpActionContext參數上獲得httpcontext屬性的HttpActionContext (在你做的AspNet MVC中)。

執行相同操作的最佳方法是actionContext.Request.Properties字典。

在這里查看這個答案

System.Web.HttpContext.Current.Items是每請求緩存存儲。
您可以安全地在OnBeforeAction方法的Items中添加計時器對象,並從OnAfterAction方法中的Items中檢索此計時器對象

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM