add export to prometheus

This commit is contained in:
Anatoly Karlov 2023-08-15 18:17:16 +03:00
parent 3b8634840b
commit b8a6bf76ca
7 changed files with 93 additions and 26 deletions

View File

@ -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);
}
}

View File

@ -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<String, Double> limitsBoundaryAggregatesMap() {
return new ConcurrentHashMap<>();
}
@Bean
public Map<String, Double> limitsAmountAggregatesMap() {
return new ConcurrentHashMap<>();
}
}

View File

@ -37,8 +37,8 @@ public class LimitsData {
@AllArgsConstructor @AllArgsConstructor
public static class Limit { public static class Limit {
private Integer amount; private String amount;
private Integer boundary; private String boundary;
private Change change; private Change change;
@JsonProperty("config_id") @JsonProperty("config_id")
private String configId; private String configId;
@ -55,7 +55,7 @@ public class LimitsData {
@AllArgsConstructor @AllArgsConstructor
public static class Change { public static class Change {
private Integer amount; private String amount;
private String currency; private String currency;
} }
@ -66,9 +66,9 @@ public class LimitsData {
public static class Route { public static class Route {
@JsonProperty("provider_id") @JsonProperty("provider_id")
private Integer providerId; private String providerId;
@JsonProperty("terminal_id") @JsonProperty("terminal_id")
private Integer terminalId; private String terminalId;
} }
} }

View File

@ -6,6 +6,9 @@ import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor @RequiredArgsConstructor
public enum Metric { public enum Metric {
LIMITS_BOUNDARY(
formatWithPrefix("limits_boundary"),
"Limits boundary since last scrape"),
LIMITS_AMOUNT( LIMITS_AMOUNT(
formatWithPrefix("limits_amount"), formatWithPrefix("limits_amount"),
"Limits amount since last scrape"); "Limits amount since last scrape");

View File

@ -1,18 +1,54 @@
package dev.vality.exporter.limits.service; 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.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Map;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
@SuppressWarnings("LineLength")
public class LimitsService { public class LimitsService {
private final MeterRegistryService meterRegistryService;
private final Map<String, Double> limitsBoundaryAggregatesMap;
private final Map<String, Double> limitsAmountAggregatesMap;
private final OpenSearchService openSearchService; private final OpenSearchService openSearchService;
public void registerMetrics() { public void registerMetrics() {
var limitsData = openSearchService.getLimitsDataByInterval(); var limitsDataByInterval = openSearchService.getLimitsDataByInterval();
log.info("limitsData {}", limitsData); 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<String, Double> 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()));
} }
} }

View File

@ -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 <T> void registry(Gauge.Builder<T> 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();
}
}

View File

@ -39,11 +39,12 @@ public class OpenSearchService {
@SneakyThrows @SneakyThrows
public List<LimitsData> getLimitsDataByInterval() { public List<LimitsData> getLimitsDataByInterval() {
return openSearchClient.search(s -> s return openSearchClient.search(s -> s
.size(10000)
.index(openSearchProperties.getIndex()) .index(openSearchProperties.getIndex())
.sort(builder -> builder .sort(builder -> builder
.field(builder1 -> builder1 .field(builder1 -> builder1
.field(TIMESTAMP) .field(TIMESTAMP)
.order(SortOrder.Desc) .order(SortOrder.Asc)
.unmappedType(FieldType.Boolean))) .unmappedType(FieldType.Boolean)))
.docvalueFields(builder -> builder .docvalueFields(builder -> builder
.field(TIMESTAMP) .field(TIMESTAMP)