commit e062b1b0d6b06ef9b5072f4afc9c9c18749c1d70 Author: Szymon Pankalla Date: Sun Sep 8 17:58:15 2024 +0200 init 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