From e062b1b0d6b06ef9b5072f4afc9c9c18749c1d70 Mon Sep 17 00:00:00 2001 From: Szymon Pankalla Date: Sun, 8 Sep 2024 17:58:15 +0200 Subject: [PATCH] init --- .dockerignore | 1 + Dockerfile | 14 + README.md | 11 + Taskfile.yml | 9 + compose.yaml | 28 ++ dashboard.json | 486 +++++++++++++++++++++++++++++ go.mod | 17 + go.sum | 24 ++ main.go | 75 +++++ volumes/prometheus/prometheus.yaml | 9 + 10 files changed, 674 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 Taskfile.yml create mode 100644 compose.yaml create mode 100644 dashboard.json create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 volumes/prometheus/prometheus.yaml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..347e267 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +volumes/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f165366 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM golang:1.23.1 AS builder + +WORKDIR /build +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . +RUN go build -o app . + +FROM ubuntu:24.04 + +COPY --from=builder /build/app /app + +CMD ["/app"] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..0b3d3e9 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# grafana - test + +## wnioski + +- liczba bucketów nie zmienia wyników +- to ich dobór względem danych ma znaczenie, więc jak dodamy duzo zaduzych bucketów to to nie wpłynie na wyniki + +## adresy + +- https://stackoverflow.com/questions/51146578/what-use-cases-really-make-prometheuss-summary-metrics-type-necessary-unique +- https://www.youtube.com/watch?v=TgINvIK9SYc&t=1233s \ No newline at end of file diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..774129d --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,9 @@ +# https://taskfile.dev + +version: '3' + +tasks: + default: + cmds: + - docker compose up --build --pull always + silent: true diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..b200476 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,28 @@ +services: + app: + build: + context: . + dockerfile: Dockerfile + environment: + - APP_PORT=9100 + ports: + - 9100:9100 + app2: + build: + context: . + dockerfile: Dockerfile + environment: + - APP_PORT=9200 + ports: + - 9200:9200 + grafana: + image: grafana/grafana:latest + ports: + - 3000:3000 + prometheus: + image: prom/prometheus:latest + command: --config.file=/etc/prometheus/prometheus.yml --enable-feature=native-histograms + ports: + - 9090:9090 + volumes: + - ./volumes/prometheus/prometheus.yaml:/etc/prometheus/prometheus.yml diff --git a/dashboard.json b/dashboard.json new file mode 100644 index 0000000..a820150 --- /dev/null +++ b/dashboard.json @@ -0,0 +1,486 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 1, + "links": [], + "panels": [ + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "adxa1mg0zfym8a" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "adxa1mg0zfym8a" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.95, sum(rate(app_times_seconds_bucket[30s])) by (le,status))\n", + "instant": false, + "legendFormat": "p95", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "adxa1mg0zfym8a" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.75, sum(rate(app_times_seconds_bucket[30s])) by (le,status))\n", + "hide": false, + "instant": false, + "legendFormat": "p75", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "adxa1mg0zfym8a" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.50, sum(rate(app_times_seconds_bucket[30s])) by (le,status))\n", + "hide": false, + "instant": false, + "legendFormat": "p50", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "adxa1mg0zfym8a" + }, + "editorMode": "code", + "expr": "rate(app_times_seconds_sum[1m]) / rate(app_times_seconds_count[1m])", + "hide": false, + "instant": false, + "legendFormat": "mean", + "range": true, + "refId": "D" + } + ], + "title": "Histogram", + "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "adxa1mg0zfym8a" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "adxa1mg0zfym8a" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "app_times_summary_seconds{}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{quantile}}", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Summary", + "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "adxa1mg0zfym8a" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "adxa1mg0zfym8a" + }, + "disableTextWrap": false, + "editorMode": "code", + "expr": "avg_over_time(go_goroutines[5m])", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Basic", + "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "adxa1mg0zfym8a" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "adxa1mg0zfym8a" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(rate(app_times_seconds_count[$__rate_interval]))", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{rps}}", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Requests", + "type": "timeseries" + } + ], + "refresh": "", + "schemaVersion": 39, + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "App", + "uid": "bdxa1umuwhs00d", + "version": 12, + "weekStart": "" +} \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..8c9e8f5 --- /dev/null +++ b/go.mod @@ -0,0 +1,17 @@ +module git.appsdev.pl/dom3k/grafana-test + +go 1.23.1 + +require github.com/prometheus/client_golang v1.20.3 + +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/go.sum b/go.sum new file mode 100644 index 0000000..b488e49 --- /dev/null +++ b/go.sum @@ -0,0 +1,24 @@ +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.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4= +github.com/prometheus/client_golang v1.20.3/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/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/main.go b/main.go new file mode 100644 index 0000000..864b739 --- /dev/null +++ b/main.go @@ -0,0 +1,75 @@ +package main + +import ( + "context" + "log/slog" + "net/http" + "os" + "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/prometheus/client_golang/prometheus/promhttp" +) + +var ( + times = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "app_times_seconds", + Buckets: []float64{0.01, 0.013, 0.015, 0.02, 0.03, 0.04, 0.05, 0.06, 1, 2, 3, 4, 5, 6, 7}, + }, []string{"status"}) + timesSummary = promauto.NewSummaryVec(prometheus.SummaryOpts{ + Name: "app_times_summary_seconds", + Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, + }, []string{"status"}) + timesNative = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Name: "app_times_native_seconds", + NativeHistogramBucketFactor: 1.1, + }, []string{"status"}) +) + +func main() { + slog.Info("application started") + if err := start(context.Background()); err != nil { + slog.Error("unable to start application", "error", err) + os.Exit(1) + } + + slog.Info("application stopped") +} + +func start(_ context.Context) error { + port := os.Getenv("APP_PORT") + go func() { + var max time.Duration + for { + t := time.Now() + time.Sleep(10 * time.Millisecond) + duration := time.Since(t) + times.WithLabelValues("10ms").Observe(duration.Seconds()) + timesNative.WithLabelValues("10ms").Observe(duration.Seconds()) + timesSummary.WithLabelValues("10ms").Observe(duration.Seconds()) + if duration > max { + max = duration + } + slog.Info("duration", "duration", duration, "max", max) + } + }() + go func() { + var max time.Duration + for { + t := time.Now() + time.Sleep(100 * time.Millisecond) + duration := time.Since(t) + times.WithLabelValues("100ms").Observe(duration.Seconds()) + timesNative.WithLabelValues("100ms").Observe(duration.Seconds()) + timesSummary.WithLabelValues("100ms").Observe(duration.Seconds()) + if duration > max { + max = duration + } + // slog.Info("duration", "duration", duration, "max", max) + } + }() + + http.Handle("/metrics", promhttp.Handler()) + return http.ListenAndServe(":"+port, nil) +} diff --git a/volumes/prometheus/prometheus.yaml b/volumes/prometheus/prometheus.yaml new file mode 100644 index 0000000..f86f608 --- /dev/null +++ b/volumes/prometheus/prometheus.yaml @@ -0,0 +1,9 @@ + scrape_configs: + - job_name: 'app' + scrape_interval: 3s + static_configs: + - targets: ['app:9100'] + - job_name: 'app_2' + scrape_interval: 3s + static_configs: + - targets: ['app2:9200'] \ No newline at end of file