diff options
Diffstat (limited to 'metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/prometheus/PrometheusUtil.java')
-rw-r--r-- | metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/prometheus/PrometheusUtil.java | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/prometheus/PrometheusUtil.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/prometheus/PrometheusUtil.java new file mode 100644 index 00000000000..cbd4ad2ef8d --- /dev/null +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/prometheus/PrometheusUtil.java @@ -0,0 +1,76 @@ +/* + * Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + */ + +package ai.vespa.metricsproxy.metric.model.prometheus; + +import ai.vespa.metricsproxy.metric.model.MetricsPacket; +import ai.vespa.metricsproxy.metric.model.ServiceId; +import io.prometheus.client.Collector; +import io.prometheus.client.Collector.MetricFamilySamples; +import io.prometheus.client.Collector.MetricFamilySamples.Sample; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; + +/** + * @author yj-jtakagi + * @author gjoranv + */ +public class PrometheusUtil { + + public static PrometheusModel toPrometheusModel(List<MetricsPacket> metricsPackets) { + Map<ServiceId, List<MetricsPacket>> packetsByService = metricsPackets.stream() + .collect(Collectors.groupingBy(packet -> packet.service)); + + List<MetricFamilySamples> metricFamilySamples = new ArrayList<>(packetsByService.size()); + + packetsByService.forEach(((serviceId, packets) -> { + Map<String, List<Sample>> samples = new HashMap<>(); + + var serviceName = Collector.sanitizeMetricName(serviceId.id); + for (var packet : packets) { + var dimensions = packet.dimensions(); + List<String> labels = new ArrayList<>(dimensions.size()); + List<String> labelValues = new ArrayList<>(dimensions.size()); + for (var entry : dimensions.entrySet()) { + var labelName = Collector.sanitizeMetricName(entry.getKey().id); + labels.add(labelName); + labelValues.add(entry.getValue()); + } + + for (var metric : packet.metrics().entrySet()) { + var metricName = serviceName + "_" + Collector.sanitizeMetricName(metric.getKey().id); + List<Sample> sampleList; + if (samples.containsKey(metricName)) { + sampleList = samples.get(metricName); + } else { + sampleList = new ArrayList<>(); + samples.put(metricName, sampleList); + metricFamilySamples.add(new MetricFamilySamples(metricName, Collector.Type.UNTYPED, "", sampleList)); + } + sampleList.add(new Sample(metricName, labels, labelValues, metric.getValue().doubleValue(), packet.timestamp * 1000)); + } + } + // convert status message to 0,1 metric + var firstPacket = packets.get(0); + String statusMetricName = serviceName + "_status"; + // MetricsPacket status 0 means OK, but it's the opposite in Prometheus. + double statusMetricValue = (firstPacket.statusCode == 0) ? 1.0 : 0.0; + List<Sample> sampleList = singletonList(new Sample(statusMetricName, emptyList(), emptyList(), + statusMetricValue, firstPacket.timestamp * 1000)); + metricFamilySamples.add(new MetricFamilySamples(statusMetricName, Collector.Type.UNTYPED, "status of service", sampleList)); + })); + + return new PrometheusModel(metricFamilySamples); + } + +} |