Java 如何每X秒重置一次指标?

Java 如何每X秒重置一次指标?,java,quartz-scheduler,dropwizard,metrics,codahale-metrics,Java,Quartz Scheduler,Dropwizard,Metrics,Codahale Metrics,我正试图在我的应用程序上使用度量应用程序和jvm级别的度量 下面是我的metrics类,我在代码中使用它来增加/减少度量。我正在调用下面类的递增和递减方法来递增和递减度量 public class TestMetrics { private final MetricRegistry metricRegistry = new MetricRegistry(); private static class Holder { private static final TestMetri

我正试图在我的应用程序上使用度量应用程序和jvm级别的度量

下面是我的metrics类,我在代码中使用它来增加/减少度量。我正在调用下面类的
递增
递减
方法来递增和递减度量

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());
    }
  }
}
公共类SendMetrics实现作业{
@凌驾
public void execute(最终JobExecutionContext ctx)引发JobExecutionException异常{
MetricRegistry metricsRegistry=TestMetrics.getInstance().getMetricRegistry();
映射计数器=metricsRegistry.getCounters();
for(条目计数器:counters.entrySet()){
System.out.println(counter.getKey());
System.out.println(counter.getValue().getCount());
}
}
}
现在我的问题是:我想每30秒重置一次我的所有指标计数。这意味着当我的
execute
方法打印出度量值时,它应该只打印出30秒的度量值(对于所有度量值),而不是从程序运行时开始打印整个持续时间


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

作为回答,因为时间太长:

您想重置计数器。没有用于此的API。链接的
github
问题中讨论了原因。本文介绍了一种可能的解决方法。你有你的计数器,并且像往常一样使用它们——递增和递减。但是你不能重置它们。因此,添加新的
仪表
,该值位于向您报告后要重置的计数器后面。当您想要报告计数器值时,将调用
仪表的
getValue()
方法。存储当前值后,该方法将使用该值减小计数器的值。这将有效地将计数器重置为
0
。所以你有你的报告,也有计数器重置。这在
步骤1
中进行了描述


步骤2
添加了一个过滤器,该过滤器禁止报告实际计数器,因为您现在通过仪表进行报告。

作为回答,因为它太长:

您想重置计数器。没有用于此的API。链接的
github
问题中讨论了原因。本文介绍了一种可能的解决方法。你有你的计数器,并且像往常一样使用它们——递增和递减。但是你不能重置它们。因此,添加新的
仪表
,该值位于向您报告后要重置的计数器后面。当您想要报告计数器值时,将调用
仪表的
getValue()
方法。存储当前值后,该方法将使用该值减小计数器的值。这将有效地将计数器重置为
0
。所以你有你的报告,也有计数器重置。这在
步骤1
中进行了描述


步骤2
添加了一个过滤器,该过滤器禁止报告实际计数器,因为您现在通过仪表进行报告。

关于
SendMetrics
类。Dropwizard已经有了适当的抽象,您可以使用它们来实现自己的报告。例如,请参见它在
stdout
stderr
上打印度量值,并可针对报告期进行配置。还要看一下子模块。您可以使用那里的代码作为示例实现。关于更大的问题:查看这里->检查
度量项目
。这里有关于重置计数器的链接。我不太明白你给我的文章链接。我不知道这在我的课堂上会怎样?你能帮我理解吗?或者你能给我举个例子吗?Bcoz我正在调用
TestMetrics
类的increment方法来增加度量。关于
SendMetrics
类。Dropwizard已经有了适当的抽象,您可以使用它们来实现自己的报告。例如,请参见它在
stdout
stderr
上打印度量值,并可针对报告期进行配置。还要看一下子模块。您可以使用那里的代码作为示例实现。关于更大的问题:查看这里->检查
度量项目
。这里有关于重置计数器的链接。我不太明白你给我的文章链接。我不知道这在我的课堂上会怎样?你能帮我理解吗?或者你能给我举个例子吗?Bcoz我正在调用
TestMetrics
类的increment方法来增加度量。这意味着我需要为每个度量计数器设置
gauge
?我有一个非常通用的方法来增加度量,因为我没有为所有度量定义计数器变量。我使用enum定义所有度量变量,然后在我的
increment
方法中使用它来增加度量。因此,这意味着我需要为所有指标手动定义仪表?是否有任何方法可以根据我的代码使其通用?1)是的,每个要重置的计数器需要一个仪表;2) 问题太多且超出范围-解决方案是否有助于您以及如何实施取决于您的决定。因此,这意味着我需要为我的每个度量计数器配备
量表
?我有一个非常通用的方法来增加度量,因为我没有为度量定义计数器变量