如何使用ActionFilterAttribute登录的运行时间? [英] How to use ActionFilterAttribute to log running times?
问题描述
我创建了一个动作过滤器在网页API V2测量每一个动作的运行时间。
I created an action filter for measuring running times of every action in an 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
的
However, action filters act as singletons, so when OnActionExecuted
runs, I cannot be sure that the _logger
and _timer
correspond to the ones created for the same action OnActionExecuting
.
例如。
- 动作Foo1开始执行。
_logger =logger1
,_timer =定时器
。 - 动作foo2的开始执行。
_logger =logger2
,_timer =定时器2
(他们得到的被覆盖的) - 动作Foo1结束执行。它停止计时器,记录经过的时间是废话(END1-START2)。
- Action Foo1 begins execution.
_logger = "logger1"
,_timer = "timer1"
. - Action Foo2 begins execution.
_logger = "logger2"
,_timer = "timer2"
(they get overriden) - Action Foo1 ends execution. It stops timer and logs elapsed time which is nonsense (end1-start2).
问:有没有一种方法可以让我在知道 OnActionExecuted
到 OnActionExecuting
它对应?如果有采取行动的一些独特的标识符,我可以用它作为重点字典存储任何行动相关的对象,如记录器和定时器。有没有?或一些其他的解决方案?
Question: Is there a way I can know in OnActionExecuted
to which OnActionExecuting
it corresponds? If there was some unique identifier for actions, I could use it as a key to a Dictionary to store any action-related objects such as loggers and timers. Is there any? Or some other solution?
推荐答案
至于网页API来讲 System.Web.HttpContext.Current
并不总是保证。这取决于你是否在使用Web API自托管与否。这是主要的原因,当覆盖 System.Web.Http.Filters.ActionFilterAttribute.OnActionExecuting
你没有得到关于 HttpActionContext <一个HttpContext的属性/ code>参数(在ASPNET MVC你这样做)。
As far as Web API is concerned the System.Web.HttpContext.Current
is not always guaranteed. It depends on whether you are using Web API Self hosted or not. That is the main reason that when overriding System.Web.Http.Filters.ActionFilterAttribute.OnActionExecuting
you don't get an httpcontext property on the HttpActionContext
parameter (In AspNet MVC you do).
做同样的最好办法是在 actionContext.Request.Properties
词典。
The best way to do the same is the actionContext.Request.Properties
dictionary.
检查也是这个答案这里
这篇关于如何使用ActionFilterAttribute登录的运行时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!