Калибровочный расчет 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);