如何包装所有操作过滤器以进行性能监控?

发布于 2024-12-04 14:57:05 字数 821 浏览 0 评论 0原文

我正在将越来越多的面向方面的关注点转移到我的 ASP.NET MVC 站点上的 ActionFilters 中。因此,我怀疑我的一些性能瓶颈可能已经转移到 ActionFilters 中,而无法了解它们的性能。我想挂钩 MVC 的 ActionFilter 创建过程来包装每个 ActionFilter,以便我可以记录该 ActionFilter 的执行时间。

到目前为止,我发现了以下网络链接,它们暗示了如何开始,但不确定如何实际包装每个 ActionFilter。

I am moving more and more of my aspect-oriented concerns into ActionFilters on my ASP.NET MVC site. As a result, I suspect some of my performance bottlenecks may have moved into ActionFilters with no visibility of what their performance is. I would like to hook into ActionFilter creation process of MVC to wrap each ActionFilter so that I can log how long the execution of that ActionFilter takes.

So far, I have found the following web links which hint at how to start down the road but am not sure how to actually wrap each ActionFilter.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陪我终i 2024-12-11 14:57:05

您应该从 ControllerActionInvoker 派生新类并重写 GetFilters 方法。在此方法中,您应该创建一个诊断包装类的新实例,该类实现包装真实过滤器的相同接口 (IActionFilter)。 GetFilters 作为 InvokeAction 方法的一部分调用(也可以被重写),但 GetFilters 可能是最干净的。

另外,您也可以尝试覆盖 InvokeActionMethodWithFilters,这是实际调用操作过滤器的地方,但这可能会很混乱,但如果您只是添加了一些内容,则可能没问题
例如:

protected override ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters)
{
    Stopwatch diagWatch = Stopwatch.StartNew();

    var context = base.InvokeActionMethodWithFilters(controllerContext, filters, actionDescriptor, parameters);

    diagWatch.Stop();

    return context;
}

要实现 ControllerActionInvoker 类,请参阅:

public class DiagControllerActionInvoker : ControllerActionInvoker
{
    protected override FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    {
        FilterInfo baseFilters = base.GetFilters(controllerContext, actionDescriptor);

        //Add new filters
        //e.g. baseFilters.ActionFilters.Insert(0, actionFilter);

        return baseFilters;
    }
 }

要实际指定调用您的自定义 ControllerActionInvoker,您需要创建一个 DefaultControllerFactory 实现,例如:

public class SiteControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
        {
            return null;
        }

        // Create controller class. Here.
        IController controller = (IController)Activator.CreateInstance(controllerType)

        if (typeof(Controller).IsAssignableFrom(controllerType))
        {
            Controller controllerInstance = controller as Controller;

            if (controllerInstance != null)
            {
                controllerInstance.ActionInvoker = new DiagControllerActionInvoker();
            }
        }

        return controller;
    }
}

并且通过在应用程序代码中进行设置,如下所示:

ControllerBuilder.Current.SetControllerFactory(new SiteControllerFactory());

You should derive and new class from ControllerActionInvoker and override the GetFilters method. In this method you should create a new instance of a diagnostic wrapper class implementing the same interface (IActionFilter) that wrap the real filter. GetFilters is called as part of the InvokeAction method (also can be overridden) but GetFilters is probably the cleanest.

Also you could also try overriding InvokeActionMethodWithFilters which is where the action filters are actually invoked however again this could be messy but may be ok if you just added something
like:

protected override ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters)
{
    Stopwatch diagWatch = Stopwatch.StartNew();

    var context = base.InvokeActionMethodWithFilters(controllerContext, filters, actionDescriptor, parameters);

    diagWatch.Stop();

    return context;
}

To implement an ControllerActionInvoker class see:

public class DiagControllerActionInvoker : ControllerActionInvoker
{
    protected override FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    {
        FilterInfo baseFilters = base.GetFilters(controllerContext, actionDescriptor);

        //Add new filters
        //e.g. baseFilters.ActionFilters.Insert(0, actionFilter);

        return baseFilters;
    }
 }

To actually specify that your custom ControllerActionInvoker is called you need to create a DefaultControllerFactory implementation like:

public class SiteControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
        {
            return null;
        }

        // Create controller class. Here.
        IController controller = (IController)Activator.CreateInstance(controllerType)

        if (typeof(Controller).IsAssignableFrom(controllerType))
        {
            Controller controllerInstance = controller as Controller;

            if (controllerInstance != null)
            {
                controllerInstance.ActionInvoker = new DiagControllerActionInvoker();
            }
        }

        return controller;
    }
}

And like by setting is in the a your application code like so:

ControllerBuilder.Current.SetControllerFactory(new SiteControllerFactory());
花伊自在美 2024-12-11 14:57:05
  1. 一种更简单的方法可能是编写集成测试来测量每个操作过滤器或组合的性能。
  2. MVC3中有全局动作过滤器可用;您可能想要编写性能属性,该属性将启动和停止计时器,并为您提供过滤器运行的总时间操作。
  3. 如果您希望在生产中分析整个应用程序,可以使用许多商业产品 DotTrace、Dynatrace 等,它们可以深入了解每次调用的分解成本。
  1. A simpler approach might be to write integration tests to measure performance for each action filter or combination.
  2. There are global action filters available in MVC3; you might want to write performance attribute which would start and stop timer and give you total time actions filter ran for.
  3. If you are looking to analyze application as a whole in production there are lot of commercial products available DotTrace, Dynatrace and so on which provide drill down for break down cost of each call.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文