跟踪方法执行时间

卡塔琳娜

我试图在我的应用程序中“注入”自定义跟踪方法。

我想使其尽可能优雅,而无需修改许多现有代码,并可以轻松启用/禁用它。

我想到的一个解决方案是创建一个自定义Attribute,将其附加到我要跟踪的方法上。

基本思路:

public class MethodSnifferAttribute : Attribute
{
    private Stopwatch sw = null;

    public void BeforeExecution()
    {
        sw = new Stopwatch();
        sw.Start();
    }
    public void ExecutionEnd()
    {
        sw.Stop();
        LoggerManager.Logger.Log("Execution time: " + sw.ElapsedMilliseconds);
    }
}

public class MyClass
{
    [MethodSniffer]
    public void Function()
    {
        // do a long task
    }
}

是否有任何现有.NET属性可为调用/结束方法提供回调?

斯里拉姆·萨克提维(Sriram Sakthivel)

除非手动调用属性的方法,否则不会调用该方法。有一些由CLR调用的安全属性,但这超出了此问题的范围,并且无论如何都不会有用。

有一些技巧可以在不同级别上重写代码。源代码编织,IL编织等。

您需要研究一下修改IL并重写它以定时执行的方法。不用担心,您不必编写所有这些内容。人们已经做到了。例如,您可以使用PostSharp

这是提供示例文章

[Serializable]
[DebuggerStepThrough]
[AttributeUsage(AttributeTargets.Method)]
public sealed class LogExecutionTimeAttribute : OnMethodInvocationAspect
{
    private static readonly ILog Log = LogManager.GetLogger(typeof(LogExecutionTimeAttribute));

    // If no threshold is provided, then just log the execution time as debug
    public LogExecutionTimeAttribute() : this (int.MaxValue, true)
    {
    }
    // If a threshold is provided, then just flag warnning when threshold's exceeded
    public LogExecutionTimeAttribute(int threshold) : this (threshold, false)
    {
    }
    // Greediest constructor
    public LogExecutionTimeAttribute(int threshold, bool logDebug)
    {
        Threshold = threshold;
        LogDebug = logDebug;
    }

    public int Threshold { get; set; }
    public bool LogDebug { get; set; }

    // Record time spent executing the method
    public override void OnInvocation(MethodInvocationEventArgs eventArgs)
    {
        var sw = Stopwatch.StartNew();
        eventArgs.Proceed();
        sw.Stop();
        var timeSpent = sw.ElapsedMilliseconds;

        if (LogDebug)
        {
            Log.DebugFormat(
                "Method [{0}{1}] took [{2}] milliseconds to execute",
                eventArgs.Method.DeclaringType.Name,
                eventArgs.Method.Name,
                timeSpent);
        }

        if (timeSpent > Threshold)
        {
            Log.WarnFormat(
                "Method [{0}{1}] was expected to finish within [{2}] milliseconds, but took [{3}] instead!",
                eventArgs.Method.DeclaringType.Name,
                eventArgs.Method.Name,
                Threshold,
                timeSpent);
       }
}

注意:我修改了本文中的示例,以使用它,StopWatch而不是DateTime因为DateTime它不准确。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

PHP Imagick 的 setFont 方法执行时间过长

来自分类Dev

如何跟踪执行时间?

来自分类Dev

Java 8中的功能接口(方法执行时间记录器)

来自分类Dev

创建包装器类以捕获方法执行时间

来自分类Dev

如何在PHP中跟踪每行/每行/方法块的执行时间?

来自分类Dev

使用茉莉跟踪功能执行时间

来自分类Dev

使用茉莉跟踪功能执行时间

来自分类Dev

setter方法的执行时间

来自分类Dev

执行时间

来自分类Dev

功能执行时间

来自分类Dev

测量执行时间

来自分类Dev

功能执行时间

来自分类Dev

弹性搜索无法执行时间戳范围查询

来自分类Dev

在不同的计算机上相同的算法执行时间?

来自分类Dev

设置方法/线程的最大执行时间

来自分类Dev

模拟方法的执行时间和顺序

来自分类Dev

通过反射获取的方法的执行时间是否更长?

来自分类Dev

测量Keras层执行时间的正确方法

来自分类Dev

测量功能执行时间的最佳方法

来自分类Dev

C#方法的执行时间测试

来自分类Dev

减少mysql中此查询的执行时间的方法

来自分类Dev

Moq框架来测试方法的执行时间

来自分类Dev

SQL查询时间-执行时间

来自分类Dev

Spark作业执行时间

来自分类Dev

葫芦如何加快执行时间

来自分类Dev

相同请求的执行时间不同

来自分类Dev

如何减少查询执行时间

来自分类Dev

PHP while循环执行时间

来自分类Dev

Laravel从终端查看执行时间