From 61074e7e5e6606a9fa24b09e858fbbe751be6028 Mon Sep 17 00:00:00 2001 From: Carl Bergquist Date: Mon, 26 Aug 2024 19:12:59 +0200 Subject: [PATCH] Devenv: Adds docker for prometheus with high cardinality labels. (#91035) Signed-off-by: bergquist --- .github/CODEOWNERS | 1 + .../blocks/prometheus/docker-compose.yaml | 5 + .../docker/blocks/prometheus/prometheus.yml | 4 + .../blocks/prometheus_high_card/Dockerfile | 15 +++ .../prometheus_high_card/docker-compose.yaml | 6 + .../docker/blocks/prometheus_high_card/go.mod | 20 +++ .../docker/blocks/prometheus_high_card/go.sum | 26 ++++ .../blocks/prometheus_high_card/main.go | 123 ++++++++++++++++++ 8 files changed, 200 insertions(+) create mode 100644 devenv/docker/blocks/prometheus_high_card/Dockerfile create mode 100644 devenv/docker/blocks/prometheus_high_card/docker-compose.yaml create mode 100644 devenv/docker/blocks/prometheus_high_card/go.mod create mode 100644 devenv/docker/blocks/prometheus_high_card/go.sum create mode 100644 devenv/docker/blocks/prometheus_high_card/main.go diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 82f950b572c..8c656594ef8 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -209,6 +209,7 @@ /devenv/docker/blocks/postgres_tests/ @grafana/oss-big-tent /devenv/docker/blocks/prometheus/ @grafana/observability-metrics /devenv/docker/blocks/prometheus_random_data/ @grafana/observability-metrics +/devenv/docker/blocks/prometheus_high_card/ @grafana/observability-metrics /devenv/docker/blocks/pyroscope/ @grafana/observability-traces-and-profiling /devenv/docker/blocks/redis/ @bergquist /devenv/docker/blocks/sensugo/ @grafana/grafana-backend-group diff --git a/devenv/docker/blocks/prometheus/docker-compose.yaml b/devenv/docker/blocks/prometheus/docker-compose.yaml index 6cda0259dc6..21410898b50 100644 --- a/devenv/docker/blocks/prometheus/docker-compose.yaml +++ b/devenv/docker/blocks/prometheus/docker-compose.yaml @@ -37,3 +37,8 @@ build: docker/blocks/prometheus_random_data ports: - "8081:8080" + + prometheus-high-card: + build: docker/blocks/prometheus_high_card + ports: + - "9111:9111" diff --git a/devenv/docker/blocks/prometheus/prometheus.yml b/devenv/docker/blocks/prometheus/prometheus.yml index 81d3c0a81c1..32d0161b2fe 100644 --- a/devenv/docker/blocks/prometheus/prometheus.yml +++ b/devenv/docker/blocks/prometheus/prometheus.yml @@ -38,6 +38,10 @@ scrape_configs: static_configs: - targets: ['prometheus-random-data:8080'] + - job_name: 'prometheus-high-card' + static_configs: + - targets: ['prometheus-high-card:9111'] + - job_name: 'mysql' static_configs: - targets: ['mysql-exporter:9104'] diff --git a/devenv/docker/blocks/prometheus_high_card/Dockerfile b/devenv/docker/blocks/prometheus_high_card/Dockerfile new file mode 100644 index 00000000000..36e515c907a --- /dev/null +++ b/devenv/docker/blocks/prometheus_high_card/Dockerfile @@ -0,0 +1,15 @@ +FROM golang:latest AS builder + +ADD main.go / +ADD go.mod / +ADD go.sum / +WORKDIR / + +RUN go mod download +RUN CGO_ENABLED=0 GOOS=linux go build -o main . + +FROM scratch +WORKDIR / +EXPOSE 9111 +COPY --from=builder /main /main +ENTRYPOINT ["/main"] diff --git a/devenv/docker/blocks/prometheus_high_card/docker-compose.yaml b/devenv/docker/blocks/prometheus_high_card/docker-compose.yaml new file mode 100644 index 00000000000..688fa626705 --- /dev/null +++ b/devenv/docker/blocks/prometheus_high_card/docker-compose.yaml @@ -0,0 +1,6 @@ + prometheus_high_card: + build: docker/blocks/prometheus_high_card + ports: + - "3012:3012" + extra_hosts: + - "host.docker.internal:host-gateway" \ No newline at end of file diff --git a/devenv/docker/blocks/prometheus_high_card/go.mod b/devenv/docker/blocks/prometheus_high_card/go.mod new file mode 100644 index 00000000000..be940ff6862 --- /dev/null +++ b/devenv/docker/blocks/prometheus_high_card/go.mod @@ -0,0 +1,20 @@ +module high-card + +go 1.22.4 + +require ( + github.com/prometheus/client_golang v1.20.2 + golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 +) + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + golang.org/x/sys v0.22.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect +) diff --git a/devenv/docker/blocks/prometheus_high_card/go.sum b/devenv/docker/blocks/prometheus_high_card/go.sum new file mode 100644 index 00000000000..742cb8092ff --- /dev/null +++ b/devenv/docker/blocks/prometheus_high_card/go.sum @@ -0,0 +1,26 @@ +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/prometheus/client_golang v1.20.2 h1:5ctymQzZlyOON1666svgwn3s6IKWgfbjsejTMiXIyjg= +github.com/prometheus/client_golang v1.20.2/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= +golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= diff --git a/devenv/docker/blocks/prometheus_high_card/main.go b/devenv/docker/blocks/prometheus_high_card/main.go new file mode 100644 index 00000000000..dc23a06f711 --- /dev/null +++ b/devenv/docker/blocks/prometheus_high_card/main.go @@ -0,0 +1,123 @@ +package main + +import ( + "fmt" + "log" + "net/http" + "strconv" + "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/prometheus/client_golang/prometheus/promhttp" + "golang.org/x/exp/rand" +) + +func randomValues(max int) func() (string, bool) { + i := 0 + return func() (string, bool) { + i++ + return strconv.Itoa(i), i < max+1 + } +} + +func staticList(input []string) func() string { + return func() string { + i := rand.Intn(len(input)) + + return input[i] + } +} + +type dimension struct { + label string + getNextValue func() string +} + +func main() { + + fakeMetrics := []dimension{ + { + label: "cluster", + getNextValue: staticList([]string{"prod-uk1", "prod-eu1", "prod-uk2", "prod-eu2", "prod-uk3", "prod-eu3", "prod-uk4", "prod-eu4", "prod-uk5", "prod-eu5"}), + }, + { + label: "namespace", + getNextValue: staticList([]string{"default", "kube-api", "kube-system", "kube-public", "kube-node-lease", "kube-ingress", "kube-logging", "kube-metrics", "kube-monitoring", "kube-network", "kube-storage"}), + }, + { + label: "pod", + getNextValue: staticList([]string{"default"}), + }, + { + label: "container", + getNextValue: staticList([]string{"container"}), + }, + { + label: "method", + getNextValue: staticList([]string{"GET", "POST", "DELETE", "PUT", "PATCH"}), + }, + { + label: "address", + getNextValue: staticList([]string{"/", "/api", "/api/dashboard", "/api/dashboard/:uid", "/api/dashboard/:uid/overview", "/api/dashboard/:uid/overview/:id", "/api/dashboard/:uid/overview/:id/summary", "/api/dashboard/:uid/overview/:id/summary/:type", "/api/dashboard/:uid/overview/:id/summary/:type/:subtype", "/api/dashboard/:uid/overview/:id/summary/:type/:subtype/:id"}), + }, + { + label: "extra_label_name1", + getNextValue: staticList([]string{"default"}), + }, + { + label: "extra_label_name2", + getNextValue: staticList([]string{"default"}), + }, + { + label: "extra_label_name3", + getNextValue: staticList([]string{"default"}), + }, + { + label: "extra_label_name4", + getNextValue: staticList([]string{"default"}), + }, + { + label: "extra_label_name5", + getNextValue: staticList([]string{"default"}), + }, + { + label: "extra_label_name6", + getNextValue: staticList([]string{"default"}), + }, + } + + dimensions := []string{} + for _, dim := range fakeMetrics { + dimensions = append(dimensions, dim.label) + } + + opsProcessed := promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "fakedata_highcard_http_requests_total", + Help: "a high cardinality counter", + }, dimensions) + + http.Handle("/metrics", promhttp.Handler()) + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + w.Write([]byte("Hello, is it me you're looking for?")) + }) + + go func() { + for { + labels := []string{} + for _, dim := range fakeMetrics { + value := dim.getNextValue() + labels = append(labels, value) + } + + opsProcessed.WithLabelValues(labels...).Inc() + + time.Sleep(time.Millisecond) + } + }() + + fmt.Printf("Server started at :9111\n") + + log.Fatal(http.ListenAndServe(":9111", nil)) +}