summaryrefslogtreecommitdiffstats
path: root/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/prometheus/PrometheusUtil.java
diff options
context:
space:
mode:
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.java76
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);
+ }
+
+}