如何每隔X秒重置指标?

时间:2016-12-01 05:44:07

标签: java quartz-scheduler dropwizard metrics codahale-metrics

我正在尝试使用DropWizard Metrics library在我的应用程序上衡量应用程序和jvm级别指标。

以下是我在我的代码中使用的增量/减少指标的指标类。我正在调用以下类的incrementdecrement方法来增加和减少指标。

public class TestMetrics {
  private final MetricRegistry metricRegistry = new MetricRegistry();

  private static class Holder {
    private static final TestMetrics INSTANCE = new TestMetrics();
  }

  public static TestMetrics getInstance() {
    return Holder.INSTANCE;
  }

  private TestMetrics() {}

  public void increment(final Names... metricsName) {
    for (Names metricName : metricsName)
      metricRegistry.counter(name(TestMetrics.class, metricName.value())).inc();
  }

  public void decrement(final Names... metricsName) {
    for (Names metricName : metricsName)
      metricRegistry.counter(name(TestMetrics.class, metricName.value())).dec();
  }

  public MetricRegistry getMetricRegistry() {
    return metricRegistry;
  }

  public enum Names {
    // some more fields here
    INVALID_ID("invalid-id"), MESSAGE_DROPPED("drop-message");

    private final String value;

    private Names(String value) {
      this.value = value;
    }

    public String value() {
      return value;
    }
  };
}

以下是我在TestMetrics类之上使用的方法,以便在我需要的情况下增加指标基础。下面的方法由多个线程调用。

  public void process(GenericRecord record) {
    // ... some other code here
    try {
      String clientId = String.valueOf(record.get("clientId"));
      String procId = String.valueOf(record.get("procId"));
      if (Strings.isNullOrEmpty(clientId) && Strings.isNullOrEmpty(procId)
          && !NumberUtils.isNumber(clientId)) {
        TestMetrics.getInstance().increment(Names.INVALID_ID,
            Names.MESSAGE_DROPPED);
        return;
      }
      // .. other code here

    } catch (Exception ex) {    
      TestMetrics.getInstance().increment(Names.MESSAGE_DROPPED);
    }
  }

现在我有另一个每30秒运行一次的类(我正在使用Quartz框架),我想打印出所有指标及其计数。一般情况下,我会每隔30秒将这些指标发送到其他系统,但现在我将其打印出来。以下是我的工作方式。

public class SendMetrics implements Job {

  @Override
  public void execute(final JobExecutionContext ctx) throws JobExecutionException {
    MetricRegistry metricsRegistry = TestMetrics.getInstance().getMetricRegistry();
    Map<String, Counter> counters = metricsRegistry.getCounters();
    for (Entry<String, Counter> counter : counters.entrySet()) {
      System.out.println(counter.getKey());
      System.out.println(counter.getValue().getCount());
    }
  }
}

现在我的问题是:我想每30秒重置一次所有指标计数。当我的execute方法打印出指标时,它应该打印出仅30秒(对于所有指标)的指标,而不是从程序运行时打印整个持续时间。

有没有办法让我的所有指标都只计算30秒。计算过去30秒内发生的事情。

1 个答案:

答案 0 :(得分:0)

作为答案,因为它太长了:

您想要重置计数器。这没有API。原因在链接的github问题中进行了讨论。本文介绍了一种可能的解决方法。你有你的计数器并像往常一样使用它们 - 递增和递减。但你无法重置它们。因此,添加新的Gauge哪个值在您向其报告后要重置的计数器之后。当您想要报告计数器值时,会调用getValue()的{​​{1}}方法。在存储当前值之后,该方法正在减少计数器的值。这有效地将计数器重置为Gauge。因此,您有报告并重置计数器。这在0

中有所描述

Step 1添加了一个过滤器,禁止报告实际的计数器,因为您现在通过量表进行报告。