diff --git a/src/main/java/dev/vality/exporter/limits/config/GaugeConfig.java b/src/main/java/dev/vality/exporter/limits/config/GaugeConfig.java deleted file mode 100644 index 6f9f5a3..0000000 --- a/src/main/java/dev/vality/exporter/limits/config/GaugeConfig.java +++ /dev/null @@ -1,18 +0,0 @@ -package dev.vality.exporter.limits.config; - -import dev.vality.exporter.limits.model.Metric; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.MultiGauge; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class GaugeConfig { - - @Bean - public MultiGauge multiGaugeLimitsAmount(MeterRegistry meterRegistry) { - return MultiGauge.builder(Metric.LIMITS_AMOUNT.getName()) - .description(Metric.LIMITS_AMOUNT.getDescription()) - .register(meterRegistry); - } -} diff --git a/src/main/java/dev/vality/exporter/limits/config/StorageConfig.java b/src/main/java/dev/vality/exporter/limits/config/StorageConfig.java new file mode 100644 index 0000000..9f1daf9 --- /dev/null +++ b/src/main/java/dev/vality/exporter/limits/config/StorageConfig.java @@ -0,0 +1,21 @@ +package dev.vality.exporter.limits.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Configuration +public class StorageConfig { + + @Bean + public Map limitsBoundaryAggregatesMap() { + return new ConcurrentHashMap<>(); + } + + @Bean + public Map limitsAmountAggregatesMap() { + return new ConcurrentHashMap<>(); + } +} diff --git a/src/main/java/dev/vality/exporter/limits/model/LimitsData.java b/src/main/java/dev/vality/exporter/limits/model/LimitsData.java index f52dbfc..c9cb8a8 100644 --- a/src/main/java/dev/vality/exporter/limits/model/LimitsData.java +++ b/src/main/java/dev/vality/exporter/limits/model/LimitsData.java @@ -37,8 +37,8 @@ public class LimitsData { @AllArgsConstructor public static class Limit { - private Integer amount; - private Integer boundary; + private String amount; + private String boundary; private Change change; @JsonProperty("config_id") private String configId; @@ -55,7 +55,7 @@ public class LimitsData { @AllArgsConstructor public static class Change { - private Integer amount; + private String amount; private String currency; } @@ -66,9 +66,9 @@ public class LimitsData { public static class Route { @JsonProperty("provider_id") - private Integer providerId; + private String providerId; @JsonProperty("terminal_id") - private Integer terminalId; + private String terminalId; } } diff --git a/src/main/java/dev/vality/exporter/limits/model/Metric.java b/src/main/java/dev/vality/exporter/limits/model/Metric.java index 73c4862..fa89ba3 100644 --- a/src/main/java/dev/vality/exporter/limits/model/Metric.java +++ b/src/main/java/dev/vality/exporter/limits/model/Metric.java @@ -6,6 +6,9 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor public enum Metric { + LIMITS_BOUNDARY( + formatWithPrefix("limits_boundary"), + "Limits boundary since last scrape"), LIMITS_AMOUNT( formatWithPrefix("limits_amount"), "Limits amount since last scrape"); diff --git a/src/main/java/dev/vality/exporter/limits/service/LimitsService.java b/src/main/java/dev/vality/exporter/limits/service/LimitsService.java index ea48032..63841e0 100644 --- a/src/main/java/dev/vality/exporter/limits/service/LimitsService.java +++ b/src/main/java/dev/vality/exporter/limits/service/LimitsService.java @@ -1,18 +1,54 @@ package dev.vality.exporter.limits.service; +import dev.vality.exporter.limits.model.CustomTag; +import dev.vality.exporter.limits.model.LimitsData; +import dev.vality.exporter.limits.model.Metric; +import io.micrometer.core.instrument.Gauge; +import io.micrometer.core.instrument.Tags; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import java.util.Map; + @Service @RequiredArgsConstructor @Slf4j +@SuppressWarnings("LineLength") public class LimitsService { + private final MeterRegistryService meterRegistryService; + private final Map limitsBoundaryAggregatesMap; + private final Map limitsAmountAggregatesMap; private final OpenSearchService openSearchService; public void registerMetrics() { - var limitsData = openSearchService.getLimitsDataByInterval(); - log.info("limitsData {}", limitsData); + var limitsDataByInterval = openSearchService.getLimitsDataByInterval(); + for (var limitsData : limitsDataByInterval) { + var id = limitsData.getMachine().getId() + "." + limitsData.getPayment().getId(); + gauge(limitsBoundaryAggregatesMap, Metric.LIMITS_BOUNDARY, id, getTags(limitsData), limitsData.getLimit().getBoundary()); + gauge(limitsAmountAggregatesMap, Metric.LIMITS_AMOUNT, id, getTags(limitsData), limitsData.getLimit().getAmount()); + } + var registeredMetricsSize = meterRegistryService.getRegisteredMetricsSize(Metric.LIMITS_BOUNDARY.getName()) + meterRegistryService.getRegisteredMetricsSize(Metric.LIMITS_AMOUNT.getName()); + log.info("Limits with final statuses metrics have been registered to 'prometheus', " + + "registeredMetricsSize = {}, clientSize = {}", registeredMetricsSize, limitsDataByInterval.size()); + } + + private void gauge(Map storage, Metric metric, String id, Tags tags, String value) { + if (!storage.containsKey(id)) { + var gauge = Gauge.builder(metric.getName(), storage, map -> map.get(id)) + .description(metric.getDescription()) + .tags(tags); + meterRegistryService.registry(gauge); + } + storage.put(id, Double.parseDouble(value)); + } + + private Tags getTags(LimitsData dto) { + return Tags.of( + CustomTag.terminalId(dto.getLimit().getRoute().getTerminalId()), + CustomTag.providerId(dto.getLimit().getRoute().getProviderId()), + CustomTag.currency(dto.getLimit().getChange().getCurrency()), + CustomTag.shopId(dto.getLimit().getShopId())); } } diff --git a/src/main/java/dev/vality/exporter/limits/service/MeterRegistryService.java b/src/main/java/dev/vality/exporter/limits/service/MeterRegistryService.java new file mode 100644 index 0000000..c6334f9 --- /dev/null +++ b/src/main/java/dev/vality/exporter/limits/service/MeterRegistryService.java @@ -0,0 +1,24 @@ +package dev.vality.exporter.limits.service; + +import io.micrometer.core.instrument.Gauge; +import io.micrometer.core.instrument.MeterRegistry; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class MeterRegistryService { + + private final MeterRegistry meterRegistry; + + public void registry(Gauge.Builder builder) { + builder.register(meterRegistry); + } + + public long getRegisteredMetricsSize(String name) { + return meterRegistry.getMeters().stream() + .filter(meter -> meter.getId().getName().equals(name)) + .filter(Gauge.class::isInstance) + .count(); + } +} diff --git a/src/main/java/dev/vality/exporter/limits/service/OpenSearchService.java b/src/main/java/dev/vality/exporter/limits/service/OpenSearchService.java index 29f0540..9461f26 100644 --- a/src/main/java/dev/vality/exporter/limits/service/OpenSearchService.java +++ b/src/main/java/dev/vality/exporter/limits/service/OpenSearchService.java @@ -39,11 +39,12 @@ public class OpenSearchService { @SneakyThrows public List getLimitsDataByInterval() { return openSearchClient.search(s -> s + .size(10000) .index(openSearchProperties.getIndex()) .sort(builder -> builder .field(builder1 -> builder1 .field(TIMESTAMP) - .order(SortOrder.Desc) + .order(SortOrder.Asc) .unmappedType(FieldType.Boolean))) .docvalueFields(builder -> builder .field(TIMESTAMP)