From 38c4f3d5ef8e37d7a0e0e3c493cde12f2bb30949 Mon Sep 17 00:00:00 2001 From: ismail simsek Date: Mon, 13 Jan 2025 18:28:50 +0100 Subject: [PATCH] Prometheus: UTF8 metrics for prometheus devenv (#98237) * utf8 metrics for prometheus devenv * add label value with quotes --- .github/CODEOWNERS | 1 + devenv/docker/blocks/prometheus/Dockerfile | 2 +- .../blocks/prometheus/docker-compose.yaml | 7 +- .../docker/blocks/prometheus/prometheus.yml | 6 +- .../docker/blocks/prometheus_utf8/Dockerfile | 15 +++ .../prometheus_utf8/docker-compose.yaml | 6 + devenv/docker/blocks/prometheus_utf8/go.mod | 20 ++++ devenv/docker/blocks/prometheus_utf8/go.sum | 34 ++++++ devenv/docker/blocks/prometheus_utf8/main.go | 112 ++++++++++++++++++ 9 files changed, 200 insertions(+), 3 deletions(-) create mode 100644 devenv/docker/blocks/prometheus_utf8/Dockerfile create mode 100644 devenv/docker/blocks/prometheus_utf8/docker-compose.yaml create mode 100644 devenv/docker/blocks/prometheus_utf8/go.mod create mode 100644 devenv/docker/blocks/prometheus_utf8/go.sum create mode 100644 devenv/docker/blocks/prometheus_utf8/main.go diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7abb5c32741..6966a9adb70 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -267,6 +267,7 @@ /devenv/docker/blocks/prometheus/ @grafana/oss-big-tent /devenv/docker/blocks/prometheus_random_data/ @grafana/oss-big-tent /devenv/docker/blocks/prometheus_high_card/ @grafana/oss-big-tent +/devenv/docker/blocks/prometheus_utf8/ @grafana/oss-big-tent /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/Dockerfile b/devenv/docker/blocks/prometheus/Dockerfile index a39b100a950..7fa6476b739 100644 --- a/devenv/docker/blocks/prometheus/Dockerfile +++ b/devenv/docker/blocks/prometheus/Dockerfile @@ -1,4 +1,4 @@ -FROM prom/prometheus:latest +FROM prom/prometheus:v3.1.0 ADD prometheus.yml /etc/prometheus/ ADD recording.yml /etc/prometheus/ ADD alert.yml /etc/prometheus/ diff --git a/devenv/docker/blocks/prometheus/docker-compose.yaml b/devenv/docker/blocks/prometheus/docker-compose.yaml index 21410898b50..49b64c60fcf 100644 --- a/devenv/docker/blocks/prometheus/docker-compose.yaml +++ b/devenv/docker/blocks/prometheus/docker-compose.yaml @@ -15,7 +15,7 @@ node_exporter: image: prom/node-exporter ports: - - "9100:9100" + - "9101:9100" fake-prometheus-data: image: grafana/fake-data-gen @@ -42,3 +42,8 @@ build: docker/blocks/prometheus_high_card ports: - "9111:9111" + + prometheus-utf8: + build: docker/blocks/prometheus_utf8 + ports: + - "9112:9112" diff --git a/devenv/docker/blocks/prometheus/prometheus.yml b/devenv/docker/blocks/prometheus/prometheus.yml index 32d0161b2fe..267dc8db7f4 100644 --- a/devenv/docker/blocks/prometheus/prometheus.yml +++ b/devenv/docker/blocks/prometheus/prometheus.yml @@ -24,7 +24,7 @@ scrape_configs: - job_name: 'node_exporter' static_configs: - - targets: ['node_exporter:9100'] + - targets: ['node_exporter:9101'] - job_name: 'fake-data-gen' static_configs: @@ -42,6 +42,10 @@ scrape_configs: static_configs: - targets: ['prometheus-high-card:9111'] + - job_name: 'prometheus-utf8' + static_configs: + - targets: [ 'prometheus-utf8:9112' ] + - job_name: 'mysql' static_configs: - targets: ['mysql-exporter:9104'] diff --git a/devenv/docker/blocks/prometheus_utf8/Dockerfile b/devenv/docker/blocks/prometheus_utf8/Dockerfile new file mode 100644 index 00000000000..2708da6c390 --- /dev/null +++ b/devenv/docker/blocks/prometheus_utf8/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 9112 +COPY --from=builder /main /main +ENTRYPOINT ["/main"] diff --git a/devenv/docker/blocks/prometheus_utf8/docker-compose.yaml b/devenv/docker/blocks/prometheus_utf8/docker-compose.yaml new file mode 100644 index 00000000000..8f9ee32fae5 --- /dev/null +++ b/devenv/docker/blocks/prometheus_utf8/docker-compose.yaml @@ -0,0 +1,6 @@ +prometheus_utf8: + build: docker/blocks/prometheus_utf8 + ports: + - "3012:3012" + extra_hosts: + - "host.docker.internal:host-gateway" diff --git a/devenv/docker/blocks/prometheus_utf8/go.mod b/devenv/docker/blocks/prometheus_utf8/go.mod new file mode 100644 index 00000000000..706d2d12e81 --- /dev/null +++ b/devenv/docker/blocks/prometheus_utf8/go.mod @@ -0,0 +1,20 @@ +module utf8-support + +go 1.22.4 + +require ( + github.com/prometheus/client_golang v1.20.5 + 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.60.1 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + golang.org/x/sys v0.25.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect +) diff --git a/devenv/docker/blocks/prometheus_utf8/go.sum b/devenv/docker/blocks/prometheus_utf8/go.sum new file mode 100644 index 00000000000..5b2f91420df --- /dev/null +++ b/devenv/docker/blocks/prometheus_utf8/go.sum @@ -0,0 +1,34 @@ +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/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/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.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc= +github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +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.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.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= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/devenv/docker/blocks/prometheus_utf8/main.go b/devenv/docker/blocks/prometheus_utf8/main.go new file mode 100644 index 00000000000..1aaf3f49b1f --- /dev/null +++ b/devenv/docker/blocks/prometheus_utf8/main.go @@ -0,0 +1,112 @@ +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" + "github.com/prometheus/common/model" + "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 init() { + // This can be removed when the default validation scheme in common is updated. + model.NameValidationScheme = model.UTF8Validation + model.NameEscapingScheme = model.ValueEncodingEscaping +} + +func main() { + + fakeUtf8Metrics := []dimension{ + { + label: "a_legacy_label", + getNextValue: staticList([]string{"legacy"}), + }, + { + label: "label with space", + getNextValue: staticList([]string{"space"}), + }, + { + label: "label with 📈", + getNextValue: staticList([]string{"metrics"}), + }, + { + label: "label.with.spaß", + getNextValue: staticList([]string{"this_is_fun"}), + }, + { + label: "site", + getNextValue: staticList([]string{"LA-EPI"}), + }, + { + label: "room", + getNextValue: staticList([]string{`"Friends Don't Lie"`}), + }, + } + + dimensions := []string{} + for _, dim := range fakeUtf8Metrics { + dimensions = append(dimensions, dim.label) + } + + utf8Metric := promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "a.utf8.metric 🤘", + Help: "a utf8 metric with utf8 labels", + }, dimensions) + + opsProcessed := promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "a_utf8_http_requests_total", + Help: "a metric with utf8 labels", + }, 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 fakeUtf8Metrics { + value := dim.getNextValue() + labels = append(labels, value) + } + + utf8Metric.WithLabelValues(labels...).Inc() + opsProcessed.WithLabelValues(labels...).Inc() + + time.Sleep(time.Second * 5) + } + }() + + fmt.Printf("Server started at :9112\n") + + log.Fatal(http.ListenAndServe(":9112", nil)) +}