【问题标题】:Find the execution time of a code block using DropWizard timers使用 DropWizard 计时器查找代码块的执行时间
【发布时间】:2016-08-26 14:49:48
【问题描述】:

我通过这个问题DropWizard Metrics Meters vs Timers 并理解了计时器的概念。但是有没有一种方法可以记录代码块的执行时间,每次调用它?我不想要这个计时器的平均速率和东西,因为这个方法并不经常被调用,但在调用时会花费相当多的时间。那么有没有办法可以打印每个调用的执行时间?另外我怎样才能得到以下问题的答案

  1. 如何调查值出现峰值的原因?
  2. 我如何知道 Max time 事件何时发生,以便我可以查看日志并查看可能的原因?

任何帮助将不胜感激。

【问题讨论】:

    标签: java timer dropwizard metrics codahale-metrics


    【解决方案1】:

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

    它可以保持累积时间值,通过求导可以将其转换为图上的尖峰。 以 Graphite 的 derivative(..) 函数为例(注意,这不是“真正的”导数,只是值差异)。

    这种方法不适合频繁的事件,但扩展性不是很好。在高负载的情况下,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);
            }
        }
    
    

    【讨论】:

      【解决方案2】:

      我不知道有没有办法获取定时器上下文对象,但我有另一个想法。你说这个方法不常被调用。为什么不使用 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 步:创建动态特征

      @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

      【讨论】:

      • 我不知道为什么你的回答被否决了;但是当我不想使用 Dropwizard 的复杂计量时,你的模板对我来说是一个完美的模板。
      猜你喜欢
      • 1970-01-01
      • 2012-11-02
      • 1970-01-01
      • 1970-01-01
      • 2011-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多