Калибровочный расчет DistributionSummary с микрометром и прометеем

Я хочу получить DistributionSummary для некоторых данных домена, которые меняются не очень часто. Так что речь не идет о мониторинге запросов или чего-то подобного.

Давайте возьмем количество мест в офисе в качестве примера. Ценность для каждого офиса может время от времени меняться, и могут быть новые офисы, а также офисы будут удалены.

Так что теперь мне нужен текущий DistributionSummary по всем офисам, который должен рассчитываться каждый раз, когда я думаю (аналогично датчику).

У меня есть приложение Spring Boot 2 с микрометром, я собираю метрики с помощью прометея и отображаю их в графане.

Что я пробовал до сих пор:

Когда я регистрирую DistributionSummary, я могу записать все значения один раз во время запуска... это дает мне распределение, но вычисленные значения, такие как max, со временем теряются, и я не могу обновить DistributionSummary (запись новых офисов будет работать, но без изменения существующих из них)

// during startup
seatsInOffice = DistributionSummary.builder("office.seats")
    .publishPercentileHistogram()
    .sla(1, 5, 20, 50)
    .register(meterRegistry);

officeService.getAllOffices().forEach(p -> seatsInOffice.record(o.getNumberOfSeats()));

Я также пытался использовать @Scheduled Задача удалить и полностью восстановить DistributionSummary. Кажется, это работает, но как-то не так. Это будет рекомендуемый подход? Это также, вероятно, потребует некоторой синхронизации, чтобы не собирать метрики между удалением и пересчетом распределения.

@Scheduled(fixedRate = 5 * 60 * 1000)
public void recalculateMetrics() {
    if (seatsInOffice != null) {
       meterRegistry.remove(seatsInOffice);
    }
    seatsInOffice = DistributionSummary.builder("office.seats")
        .publishPercentileHistogram()
        .sla(1, 5, 20, 50)
        .register(meterRegistry);

    officeService.getAllOffices().forEach(p -> seatsInOffice.record(o.getNumberOfSeats()));
}

Еще одна проблема, с которой я столкнулся при таком подходе: /actuator/prometheus конечная точка по-прежнему возвращает значения для старых (удаленных) метрик, поэтому все происходит несколько раз.

Для границ типа "как и я" я также мог бы использовать некоторые датчики для предоставления значений (вычисляя их самостоятельно), но это не дало бы мне квантилей. Можно ли создать новый DistributionSummary, не регистрируя его и просто предоставив значения, которые он каким-то образом собрал?

meterRegistry.gauge("office.seats", Tags.of("le", "1"), officeService,
    x -> x.getAllOfficesWithLessThanXSeats(1).size());
meterRegistry.gauge("office.seats", Tags.of("le", "5"), officeService,
    x -> x.getAllOfficesWithLessThanXSeats(5).size());
meterRegistry.gauge("office.seats", Tags.of("le", "20"), officeService,
    x -> x.getAllOfficesWithLessThanXSeats(20).size());
meterRegistry.gauge("office.seats", Tags.of("le", "50"), officeService,
    x -> x.getAllOfficesWithLessThanXSeats(50).size());

Я хотел бы иметь DistributionSummary, который принимает лямбда или что-то подобное, чтобы получить значения. Но, возможно, эти инструменты не предназначены для этого варианта использования, и я должен использовать что-то еще. Можете ли вы порекомендовать что-нибудь?

1 ответ

DistributionSummary имеет конфигурацию distributionStatisticExpiry для управления ротацией данных. Это обходной путь

Но PrometheusDistributionSummary не будет использовать это поле

                 case Prometheus:
                    histogram = new TimeWindowFixedBoundaryHistogram(clock, DistributionStatisticConfig.builder()
                            .expiry(Duration.ofDays(1825)) // effectively never roll over
                            .bufferLength(1)
                            .build()
                            .merge(distributionStatisticConfig), true);
Другие вопросы по тегам