Удалить метрики Dropwizard после сообщения - как предотвратить повторение тех же метрик - PullRequest
0 голосов
/ 20 сентября 2018

Я тестирую метрики 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...

В этом случае я не хочу сообщать о метриках, которые еще не были "остановлены".

...