使用DropWizard计时器查找代码块的执行时间

时间:2016-08-26 14:49:48

标签: java timer dropwizard metrics codahale-metrics

我经历了这个问题DropWizard Metrics Meters vs Timers并理解了计时器的概念。但有没有一种方法可以记录每次调用代码块的执行时间?我不想要这个计时器的平均速率和东西,因为这种方法不经常调用,但在调用时需要相当长的时间。那么有没有办法可以打印每次通话的执行时间?另外,我如何获得以下问题的答案

  1. 如何调查值出现峰值的原因?
  2. 我如何知道最长时间事件发生的时间,以便我可以浏览日志并查看可能的原因?
  3. 非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

要报告确切的代码块执行时间,可以使用Counter

它可以保留累积时间值,该值可以通过求导数转换为图形上的峰值。 以Graphite的derivative(..)函数为例(请注意,这不是'true'导数,只是值的差异)。

这种方法虽然不适用于频繁发生的事件,但伸缩性却不高。在高负载的情况下,Timers更适合。

简单的Java助手:

    timed(String metricName, Runnable body) {
        Counter counter = metricsRegistry.counter(metricName);
        long t = System.currentTimeMillis();
        try {
            body.run();
        finally {
            counter.inc(System.currentTimeMillis() - t);
        }
    }

答案 1 :(得分:-1)

我不知道是否有办法获取计时器上下文对象,但我有另一个想法。你说过这种方法并不常见。为什么不使用DynamicFeature并打印容器的执行时间?

下面我将向您展示如何实施。我不确定这是否有效,我只是在没有任何测试的情况下对其编码,所以请尝试并根据需要进行更改。如果ExecutionTimeFilter由于实现了接口而需要在两个单独的类中进行拆分,则相应地进行更改。

第1步:创建过滤器

@Provider
public class ExecutionTimeFilter implements ContainerRequestFilter, ContainerResponseFilter {
    public static final String EXECUTION_TIME_HEADER = "X-Execution-Time"

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        requestContext.getHeaders().add(EXECUTION_TIME_HEADER, ZonedDateTime.now().toString());
    }

        @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        ZonedDateTime executionStartHeader = ZonedDateTime.parse(requestContext.getHeaderString(EXECUTION_TIME_HEADER));
        Duration executionTime = Duration.between(executionStartHeader, ZonedDateTime.now());
        //you can also print some url informations or whatever you need; check out the informations from both mehtod params
        System.out.println("The execution time was:" + executionTime);
    }
}

第2步:创建DynamicFeature

@Provider
public class ExecutionTimeFeature implements DynamicFeature {
    @Override
    public void configure(ResourceInfo resourceInfo, FeatureContext context) {
        if (resourceInfo.getResourceMethod().getAnnotation(ExecutionTime.class) != null) {
            context.register(ExecutionTimeFilter.class);
        }
    }
}

第3步:创建注释

@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface ExecutionTime {
}

第4步:为您的资源添加注释

@GET
@ExecutionTime
public String getExcpensiveCalculation(@QueryParam("number") @DefaultValue("1") IntegerParam number) {
    return getCalculation(number);
}

第5步:注册功能

environment.jersey().register(ExecutionTimeFeature.class);

参考文献:Dropwizard Dynamic Feature with Filters