diff --git a/dashboards/README.md b/dashboards/README.md index c3716859d0..7b15041154 100644 --- a/dashboards/README.md +++ b/dashboards/README.md @@ -24,12 +24,44 @@ For local development and debugging, it can be useful to spin up a local Prometh To expose metrics, we first need to expose a metrics collection endpoint. Add this to your code: ```go -import "github.com/prometheus/client_golang/prometheus/promhttp" +import ( + "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/grafana/pyroscope-go" +) go func() { - http.Handle("/debug/metrics/prometheus", promhttp.Handler()) - log.Fatal(http.ListenAndServe(":5001", nil)) +http.Handle("/debug/metrics/prometheus", promhttp.Handler()) +log.Fatal(http.ListenAndServe(":5001", nil)) }() + +pyroscope.Start(pyroscope.Config{ + ApplicationName: "simple.golang.app", + + // replace this with the address of pyroscope server + ServerAddress: "http://127.0.0.1:4040", + + // you can disable logging by setting this to nil + Logger: pyroscope.StandardLogger, + + // you can provide static tags via a map: + Tags: map[string]string{"hostname": os.Getenv("HOSTNAME")}, + + ProfileTypes: []pyroscope.ProfileType{ + // these profile types are enabled by default: + pyroscope.ProfileCPU, + pyroscope.ProfileAllocObjects, + pyroscope.ProfileAllocSpace, + pyroscope.ProfileInuseObjects, + pyroscope.ProfileInuseSpace, + + // these profile types are optional: + pyroscope.ProfileGoroutines, + pyroscope.ProfileMutexCount, + pyroscope.ProfileMutexDuration, + pyroscope.ProfileBlockCount, + pyroscope.ProfileBlockDuration, + }, +}) ``` This exposes a metrics collection endpoint at http://localhost:5001/debug/metrics/prometheus. Note that this is the same endpoint that [Kubo](https://github.com/ipfs/kubo) uses, so if you want to gather metrics from Kubo, you can skip this step. @@ -46,6 +78,15 @@ docker compose -f docker-compose.base.yml -f docker-compose-linux.yml up and opening Grafana at http://localhost:3000. +### Details on Pyroscope (Developer Profiling) + +Pyroscope is a continuous profiling platform that allows you to monitor the performance of your applications in real-time. In the provided code, it is used alongside Prometheus for profiling and metrics collection. + +#### Features: + +- Application Performance Monitoring: Tracks various profile types, including CPU usage, memory allocation. +- Real-time Insights: Enables detailed analysis of bottlenecks and issues in your code. + ### Making Dashboards usable with Provisioning The following section is only relevant for creators of dashboards. diff --git a/dashboards/datasources.yml b/dashboards/datasources.yml index ed47ec11a1..b7b8864a89 100644 --- a/dashboards/datasources.yml +++ b/dashboards/datasources.yml @@ -11,3 +11,9 @@ datasources: access: proxy url: http://prometheus:9090 editable: false + - name: Pyroscope + orgId: 1 + type: grafana-pyroscope-datasource + url: http://pyroscope:4040 + access: proxy + editable: true \ No newline at end of file diff --git a/dashboards/docker-compose.base.yml b/dashboards/docker-compose.base.yml index b46514af93..c45dc210c7 100644 --- a/dashboards/docker-compose.base.yml +++ b/dashboards/docker-compose.base.yml @@ -10,6 +10,7 @@ services: image: grafana/grafana:latest depends_on: - prometheus + - pyroscope ports: - "3000:3000" environment: @@ -27,3 +28,8 @@ services: - ./relaysvc/relaysvc.json:/var/lib/grafana/dashboards/relaysvc.json - ./swarm/swarm.json:/var/lib/grafana/dashboards/swarm.json - ./resource-manager/resource-manager.json:/var/lib/grafana/dashboards/resource-manager.json + - ./profiling/profiling.json:/var/lib/grafana/dashboards/profiling.json + pyroscope: + image: grafana/pyroscope:latest + ports: + - 4040:4040 \ No newline at end of file diff --git a/dashboards/profiling/profiling.json b/dashboards/profiling/profiling.json new file mode 100644 index 0000000000..389a9629f1 --- /dev/null +++ b/dashboards/profiling/profiling.json @@ -0,0 +1,231 @@ +{ + "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": 4, + "links": [], + "panels": [ + { + "datasource": { + "type": "grafana-pyroscope-datasource", + "uid": "${db}" + }, + "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": 6, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "grafana-pyroscope-datasource", + "uid": "${db}" + }, + "groupBy": [], + "labelSelector": "", + "profileTypeId": "${profile_type}", + "queryType": "metrics", + "refId": "A", + "spanSelector": [] + } + ], + "title": "${profile_type}", + "type": "timeseries" + }, + { + "datasource": { + "type": "grafana-pyroscope-datasource", + "uid": "${db}" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 23, + "w": 24, + "x": 0, + "y": 6 + }, + "id": 1, + "options": {}, + "pluginVersion": "11.3.1", + "targets": [ + { + "datasource": { + "type": "grafana-pyroscope-datasource", + "uid": "${db}" + }, + "groupBy": [], + "labelSelector": "${query}", + "profileTypeId": "${profile_type}", + "queryType": "profile", + "refId": "A", + "spanSelector": [] + } + ], + "title": "", + "type": "flamegraph" + } + ], + "preload": false, + "refresh": "5s", + "schemaVersion": 40, + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": "Pyroscope", + "value": "P02E4190217B50628" + }, + "hide": 2, + "name": "db", + "options": [], + "query": "grafana-pyroscope-datasource", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "current": { + "text": "process_cpu - cpu", + "value": "process_cpu:cpu:nanoseconds:cpu:nanoseconds" + }, + "datasource": { + "type": "grafana-pyroscope-datasource", + "uid": "${db}" + }, + "definition": "", + "label": "Profile Type", + "name": "profile_type", + "options": [], + "query": { + "type": "profileType" + }, + "refresh": 2, + "regex": "", + "sort": 1, + "type": "query" + }, + { + "baseFilters": [], + "datasource": { + "type": "grafana-pyroscope-datasource", + "uid": "${db}" + }, + "filters": [ + { + "condition": "", + "key": "target", + "keyLabel": "target", + "operator": "=", + "value": "all", + "valueLabels": [ + "all" + ] + } + ], + "label": "Query", + "name": "query", + "type": "adhoc" + } + ] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "go-libp2p Profiling", + "uid": "de4kea7bp648we", + "version": 1, + "weekStart": "" +} \ No newline at end of file