diff --git a/golang/README.md b/golang/README.md new file mode 100644 index 0000000..a86a42e --- /dev/null +++ b/golang/README.md @@ -0,0 +1,73 @@ +# Golang Runtime Metrics Dashboard - Prometheus + + +### OS Threads Histogram Panel +1. Tracks the number of goroutines currently in use by the application. +2. Tracks CGO calls, which indicate OS-level threads involvement if CGO is used. + +The code snippet below calculates the `go_goroutines_count` and `go_cgo_calls_count` + +![OS Threads Histogram](assets/os-threads-histogram.png) + +``` +package main + +import ( + "log" + "net/http" + "runtime" + "time" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" +) + +var ( + // Gauge for OS-level goroutines count + goRoutineCount = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "go_goroutines_count", + Help: "Number of goroutines currently managed by the Go runtime.", + }) + + // Counter for CGO calls (proxy for OS thread use when working with CGO) + cgoCallCount = prometheus.NewCounterFunc( + prometheus.CounterOpts{ + Name: "go_cgo_calls_count", + Help: "Number of CGO calls made by the Go runtime.", + }, + func() float64 { + return float64(runtime.NumCgoCall()) + }, + ) +) + +func initMetrics() { + // Register the goroutine count gauge + prometheus.MustRegister(goRoutineCount) + prometheus.MustRegister(cgoCallCount) +} + +func main() { + initMetrics() + + // Goroutine to periodically update goroutine count + go func() { + for { + goRoutineCount.Set(float64(runtime.NumGoroutine())) + time.Sleep(5 * time.Second) + } + }() + + // Expose metrics on port 2112 + http.Handle("/metrics", promhttp.Handler()) + log.Println("Starting server on :2112") + if err := http.ListenAndServe(":2112", nil); err != nil { + log.Fatalf("Failed to start server: %v", err) + } +} + +``` + +### Sections + +- os-threads-histogram \ No newline at end of file diff --git a/golang/assets/os-threads-histogram.png b/golang/assets/os-threads-histogram.png new file mode 100644 index 0000000..d2c0918 Binary files /dev/null and b/golang/assets/os-threads-histogram.png differ diff --git a/golang/golang-prometheus.json b/golang/golang-prometheus.json new file mode 100644 index 0000000..94c54fc --- /dev/null +++ b/golang/golang-prometheus.json @@ -0,0 +1,179 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Prometheus Go runtime exporter ", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 45, + "links": [], + "panels": [ + { + "datasource": { + "type": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "bars", + "fillOpacity": 100, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.3.0", + "targets": [ + { + "datasource": { + "uid": "$datasource" + }, + "expr": "sum(rate(go_threads{job=\"$job\", instance=\"$instance\"}[5m])) by (instance)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "title": "OS Threads Histogram", + "type": "timeseries" + } + ], + "preload": false, + "refresh": "", + "schemaVersion": 40, + "tags": [ + "go", + "golang" + ], + "templating": { + "list": [ + { + "allValue": ".*", + "current": { + "text": "All", + "value": "$__all" + }, + "includeAll": true, + "name": "datasource", + "options": [], + "query": "prometheus", + "refresh": 1, + "type": "datasource" + }, + { + "current": { + "text": "go", + "value": "go" + }, + "datasource": { + "type": "prometheus" + }, + "name": "job", + "options": [], + "query": "label_values(go_threads, job)", + "refresh": 1, + "type": "query" + }, + { + "datasource": { + "type": "prometheus" + }, + "name": "instance", + "options": [], + "query": "label_values(go_threads, instance)", + "refresh": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-2d", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Golang Runtime Metrics Dashboard", + "uid": "ce293qxwouuwwd", + "version": 5, + "weekStart": "" + } \ No newline at end of file