Я тестирую метрики Dropwizard для моего Java-приложения.Вот пример кода.
private static Slf4jReporter reporter = createReporter();
MetricRegistry registry = SharedMetricRegistries.getOrCreate(Test.class.getName());
final Timer timer = registry.timer(name(Test.class, "duration"));
final Timer.Context context = timer.time();
Thread.sleep(2000);
context.stop();
reporter.report();
reporter.report();
Когда reporter.report (); вызывается дважды, он регистрирует одну и ту же метрику дважды.Чтобы избежать этого, я написал метод для создания нового экземпляра репортера.
static void refreshReporter() {
SharedMetricRegistries.remove(Test.class.getName());
reporter = createReporter();
}
private static Slf4jReporter createReporter() {
return Slf4jReporter
.forRegistry(SharedMetricRegistries.getOrCreate(Test.class.getName()))
.convertDurationsTo(TimeUnit.MILLISECONDS)
.convertRatesTo(TimeUnit.SECONDS)
.outputTo(LOGGER)
.filter((name, metric) -> metric instanceof Timer && name.contains("duration"))
.build();
}
Используя это, как только я сообщу и обновлю репортер, та же метрика больше не появится.
context.stop();
reporter.report();
refreshReporter();
reporter.report();
Проблема с этим подходом состоит в том, что если я запускаю это в многопоточной программе, если я обновляю , то репортер перед контекстом Таймера вызвал context.stop () егобудет потеряно и не будет сообщено в следующий раз, когда я вызову reporter.report ().
Так что есть хороший способ убедиться, что после того, как таймер был сообщен, он будет удален из реестра, чтобы следующийвызывается отчет о времени, регистрируются только метрики, которые ранее не были зарегистрированы.
И, основываясь на этом, следующий сценарий создает журналы для таймера, которые являются «пустыми», поскольку контекст не был остановлендо создания отчета.
reporter.report(); //Thread 1 does this first
context.stop(); // Thread 2 does this after reporter.report() is called
reporter.report(); // Thread 2 does this after context.stop()
Вывод этого:
Test - type=TIMER, name=Test.duration, count=0, min=0.0, max=0.0, mean=0.0...
Test - type=TIMER, name=Test.duration, count=1, min=2027.758347, max=2027.758347, mean=2027.758347...
В этом случае я не хочу сообщать о метриках, которые еще не были "остановлены".