From d8fc284d54fedca331e0e259d642b2e8a1248641 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=B6ren=20Henning?= <soeren.henning@jku.at>
Date: Mon, 20 Nov 2023 14:06:16 +0100
Subject: [PATCH] Make Prometheus step resolution configurable

---
 .../rocks/theodolite/kubernetes/slo/AnalysisExecutor.kt     | 6 +++++-
 .../kotlin/rocks/theodolite/kubernetes/slo/MetricFetcher.kt | 4 ++--
 .../rocks/theodolite/kubernetes/slo/MetricFetcherTest.kt    | 1 +
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/AnalysisExecutor.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/AnalysisExecutor.kt
index a4a775ba..767be66a 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/AnalysisExecutor.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/AnalysisExecutor.kt
@@ -1,6 +1,5 @@
 package rocks.theodolite.kubernetes.slo
 
-import rocks.theodolite.core.strategies.Metric
 import rocks.theodolite.core.IOHandler
 import rocks.theodolite.kubernetes.model.KubernetesBenchmark.Slo
 import java.text.Normalizer
@@ -9,6 +8,8 @@ import java.time.Instant
 import java.util.*
 import java.util.regex.Pattern
 
+private val DEFAULT_STEP_SIZE = Duration.ofSeconds(5)
+
 /**
  * Contains the analysis. Fetches a metric from Prometheus, documents it, and evaluates it.
  * @param slo Slo that is used for the analysis.
@@ -39,11 +40,14 @@ class AnalysisExecutor(
             val resultsFolder = ioHandler.getResultFolderURL()
             val fileURL = "${resultsFolder}exp${executionId}_${load}_${resource}_${slo.sloType.toSlug()}"
 
+            val stepSize = slo.properties["promQLStepSeconds"]?.toLong()?.let { Duration.ofSeconds(it) } ?: DEFAULT_STEP_SIZE
+
             val prometheusData = executionIntervals
                 .map { interval ->
                     fetcher.fetchMetric(
                         start = interval.first,
                         end = interval.second,
+                        stepSize = stepSize,
                         query = SloConfigHandler.getQueryString(slo = slo)
                     )
                 }
diff --git a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/MetricFetcher.kt b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/MetricFetcher.kt
index 3e43d5de..c6be137b 100644
--- a/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/MetricFetcher.kt
+++ b/theodolite/src/main/kotlin/rocks/theodolite/kubernetes/slo/MetricFetcher.kt
@@ -34,7 +34,7 @@ class MetricFetcher(private val prometheusURL: String, private val offset: Durat
      * @param query query for the prometheus server.
      * @throws ConnectException - if the prometheus server timed out/was not reached.
      */
-    fun fetchMetric(start: Instant, end: Instant, query: String): PrometheusResponse {
+    fun fetchMetric(start: Instant, end: Instant, stepSize: Duration, query: String): PrometheusResponse {
 
         val offsetStart = start.minus(offset)
         val offsetEnd = end.minus(offset)
@@ -46,7 +46,7 @@ class MetricFetcher(private val prometheusURL: String, private val offset: Durat
             val encodedQuery = URLEncoder.encode(query, StandardCharsets.UTF_8)
             val request = HttpRequest.newBuilder()
                     .uri(URI.create(
-                            "$prometheusURL/api/v1/query_range?query=$encodedQuery&start=$offsetStart&end=$offsetEnd&step=5s"))
+                            "$prometheusURL/api/v1/query_range?query=$encodedQuery&start=$offsetStart&end=$offsetEnd&step={${stepSize.toSeconds()}}s"))
                     .GET()
                     .version(HttpClient.Version.HTTP_1_1)
                     .timeout(TIMEOUT)
diff --git a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/MetricFetcherTest.kt b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/MetricFetcherTest.kt
index 14b7a322..18d826f7 100644
--- a/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/MetricFetcherTest.kt
+++ b/theodolite/src/test/kotlin/rocks/theodolite/kubernetes/slo/MetricFetcherTest.kt
@@ -54,6 +54,7 @@ internal class MetricFetcherTest {
         val response = metricFetcher.fetchMetric(
                 exampleDateTime.minus(Duration.ofMinutes(10)),
                 exampleDateTime,
+                Duration.ofSeconds(5),
                 "sum by(consumergroup) (kafka_consumergroup_lag >= 0)")
 
         assertEquals(emptyPrometheusResponse, response)
-- 
GitLab