diff --git a/changelog.d/prometheus-metrics.feature.md b/changelog.d/prometheus-metrics.feature.md index c85e61979..68128f6a0 100644 --- a/changelog.d/prometheus-metrics.feature.md +++ b/changelog.d/prometheus-metrics.feature.md @@ -1 +1 @@ -Added an opt-in Prometheus metrics endpoint at `/_continuwuity/metrics` covering HTTP requests, federation, the sender queue, database and cache memory, and the tokio runtime. Contributed by @eleboucher. +Added an opt-in Prometheus metrics endpoint at `/_continuwuity/metrics` covering HTTP requests, federation, the sender queue, database and cache memory, and the tokio runtime, along with a Grafana dashboard. Contributed by @eleboucher. diff --git a/docs/guides/metrics.mdx b/docs/guides/metrics.mdx index b3873ac4b..25dcdbc85 100644 --- a/docs/guides/metrics.mdx +++ b/docs/guides/metrics.mdx @@ -47,3 +47,7 @@ All metrics are prefixed with `continuwuity_`. | `tokio_global_queue_depth` | gauge | | Tasks in the tokio global queue | | `tokio_worker_busy_seconds_total` | counter | | Time worker threads spent busy | | `tokio_worker_parks_total` | counter | | Number of times worker threads parked | + +## Grafana dashboard + +Import [grafana-dashboard.json](/guides/grafana-dashboard.json) under **Dashboards → New → Import**, or provision it from a file. diff --git a/docs/public/guides/grafana-dashboard.json b/docs/public/guides/grafana-dashboard.json new file mode 100644 index 000000000..854635a51 --- /dev/null +++ b/docs/public/guides/grafana-dashboard.json @@ -0,0 +1,1619 @@ +{ + "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": "Continuwuity homeserver metrics from /_continuwuity/metrics", + "editable": true, + "graphTooltip": 1, + "links": [], + "panels": [ + { + "type": "row", + "title": "Overview", + "id": 1, + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "panels": [] + }, + { + "type": "stat", + "title": "Version", + "description": "", + "id": 2, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 0, + "y": 1 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "continuwuity_build_info{instance=~\"$instance\"}", + "legendFormat": "{{version}}", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "short", + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "colorMode": "value", + "graphMode": "area", + "textMode": "name", + "justifyMode": "auto", + "orientation": "auto" + } + }, + { + "type": "stat", + "title": "Requests", + "description": "", + "id": 3, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 4, + "y": 1 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(continuwuity_http_request_duration_seconds_count{instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "reqps", + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "colorMode": "value", + "graphMode": "area", + "textMode": "auto", + "justifyMode": "auto", + "orientation": "auto" + } + }, + { + "type": "stat", + "title": "Server errors", + "description": "Share of requests answered with a 5xx status", + "id": 4, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 8, + "y": 1 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "(sum(rate(continuwuity_http_request_duration_seconds_count{instance=~\"$instance\",status=~\"5..\"}[$__rate_interval])) or vector(0)) / sum(rate(continuwuity_http_request_duration_seconds_count{instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "percentunit", + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 0.01 + }, + { + "color": "red", + "value": 0.05 + } + ] + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "colorMode": "value", + "graphMode": "area", + "textMode": "auto", + "justifyMode": "auto", + "orientation": "auto" + } + }, + { + "type": "stat", + "title": "p95 latency", + "description": "Includes long-polling /sync requests", + "id": 5, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 12, + "y": 1 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.95, sum by (le) (rate(continuwuity_http_request_duration_seconds_bucket{instance=~\"$instance\"}[$__rate_interval])))", + "legendFormat": "", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "s", + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "colorMode": "value", + "graphMode": "area", + "textMode": "auto", + "justifyMode": "auto", + "orientation": "auto" + } + }, + { + "type": "stat", + "title": "Sender queue", + "description": "", + "id": 6, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 16, + "y": 1 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(continuwuity_sender_queue_depth{instance=~\"$instance\"})", + "legendFormat": "", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "short", + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "colorMode": "value", + "graphMode": "area", + "textMode": "auto", + "justifyMode": "auto", + "orientation": "auto" + } + }, + { + "type": "stat", + "title": "Servers in backoff", + "description": "", + "id": 7, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 20, + "y": 1 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(continuwuity_federation_unhealthy_destinations{instance=~\"$instance\"})", + "legendFormat": "", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "short", + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 50 + } + ] + } + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "colorMode": "value", + "graphMode": "area", + "textMode": "auto", + "justifyMode": "auto", + "orientation": "auto" + } + }, + { + "type": "row", + "title": "HTTP", + "id": 8, + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 5 + }, + "panels": [] + }, + { + "type": "timeseries", + "title": "Requests by status class", + "description": "", + "id": 9, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 6 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (class) (label_replace(rate(continuwuity_http_request_duration_seconds_count{instance=~\"$instance\"}[$__rate_interval]), \"class\", \"${1}xx\", \"status\", \"([0-9])..\"))", + "legendFormat": "{{class}}", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "reqps", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 25, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "normal", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true, + "calcs": [] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + }, + { + "type": "timeseries", + "title": "Latency", + "description": "Includes long-polling /sync requests", + "id": 10, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 6 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.5, sum by (le) (rate(continuwuity_http_request_duration_seconds_bucket{instance=~\"$instance\"}[$__rate_interval])))", + "legendFormat": "p50", + "refId": "A", + "range": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.95, sum by (le) (rate(continuwuity_http_request_duration_seconds_bucket{instance=~\"$instance\"}[$__rate_interval])))", + "legendFormat": "p95", + "refId": "B", + "range": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum by (le) (rate(continuwuity_http_request_duration_seconds_bucket{instance=~\"$instance\"}[$__rate_interval])))", + "legendFormat": "p99", + "refId": "C", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "s", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "none", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true, + "calcs": [] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + }, + { + "type": "timeseries", + "title": "Top routes by request rate", + "description": "", + "id": 11, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 0, + "y": 14 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "topk(10, sum by (method, route) (rate(continuwuity_http_request_duration_seconds_count{instance=~\"$instance\"}[$__rate_interval])))", + "legendFormat": "{{method}} {{route}}", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "reqps", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "none", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "showLegend": true, + "calcs": [ + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + }, + { + "type": "timeseries", + "title": "Top routes by p95 latency", + "description": "", + "id": 12, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 10, + "w": 12, + "x": 12, + "y": 14 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "topk(10, histogram_quantile(0.95, sum by (le, method, route) (rate(continuwuity_http_request_duration_seconds_bucket{instance=~\"$instance\"}[$__rate_interval]))))", + "legendFormat": "{{method}} {{route}}", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "s", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "none", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "showLegend": true, + "calcs": [ + "mean", + "max" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + }, + { + "type": "timeseries", + "title": "Server errors by route", + "description": "", + "id": 13, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 24 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "topk(10, sum by (method, route, status) (rate(continuwuity_http_request_duration_seconds_count{instance=~\"$instance\",status=~\"5..\"}[$__rate_interval])))", + "legendFormat": "{{status}} {{method}} {{route}}", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "reqps", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "none", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true, + "calcs": [] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + }, + { + "type": "timeseries", + "title": "Requests in flight", + "description": "", + "id": 14, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 24 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(continuwuity_http_requests_in_flight{instance=~\"$instance\"})", + "legendFormat": "in flight", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "short", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "none", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true, + "calcs": [] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + }, + { + "type": "row", + "title": "Federation", + "id": 15, + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 32 + }, + "panels": [] + }, + { + "type": "timeseries", + "title": "Outgoing requests by outcome", + "description": "", + "id": 16, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 33 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (outcome) (rate(continuwuity_federation_request_duration_seconds_count{instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "{{outcome}}", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "reqps", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 25, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "normal", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true, + "calcs": [] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + }, + { + "type": "timeseries", + "title": "Outgoing request latency", + "description": "Successful requests only", + "id": 17, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 33 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.5, sum by (le) (rate(continuwuity_federation_request_duration_seconds_bucket{instance=~\"$instance\",outcome=\"success\"}[$__rate_interval])))", + "legendFormat": "p50", + "refId": "A", + "range": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.95, sum by (le) (rate(continuwuity_federation_request_duration_seconds_bucket{instance=~\"$instance\",outcome=\"success\"}[$__rate_interval])))", + "legendFormat": "p95", + "refId": "B", + "range": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "histogram_quantile(0.99, sum by (le) (rate(continuwuity_federation_request_duration_seconds_bucket{instance=~\"$instance\",outcome=\"success\"}[$__rate_interval])))", + "legendFormat": "p99", + "refId": "C", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "s", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "none", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true, + "calcs": [] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + }, + { + "type": "timeseries", + "title": "Sender transactions", + "description": "", + "id": 18, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 41 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (destination, outcome) (rate(continuwuity_sender_transactions_total{instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "{{destination}} {{outcome}}", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "ops", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "none", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true, + "calcs": [] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + }, + { + "type": "timeseries", + "title": "Sender queue depth", + "description": "", + "id": 19, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 41 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(continuwuity_sender_queue_depth{instance=~\"$instance\"})", + "legendFormat": "queued", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "short", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "none", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true, + "calcs": [] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + }, + { + "type": "timeseries", + "title": "Remote server health", + "description": "", + "id": 20, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 41 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(continuwuity_federation_unhealthy_destinations{instance=~\"$instance\"})", + "legendFormat": "in backoff", + "refId": "A", + "range": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(continuwuity_federation_stale_destinations{instance=~\"$instance\"})", + "legendFormat": "stale destination", + "refId": "B", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "short", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "none", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true, + "calcs": [] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + }, + { + "type": "row", + "title": "Database & caches", + "id": 21, + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 49 + }, + "panels": [] + }, + { + "type": "timeseries", + "title": "RocksDB memory", + "description": "Unflushed memtables are included in mem_tables", + "id": 22, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 50 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (name) (continuwuity_database_memory_bytes{instance=~\"$instance\"})", + "legendFormat": "{{name}}", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "bytes", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "none", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true, + "calcs": [] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + }, + { + "type": "timeseries", + "title": "RocksDB block cache", + "description": "", + "id": 23, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 50 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "topk(10, sum by (column) (continuwuity_database_block_cache_bytes{instance=~\"$instance\"}))", + "legendFormat": "{{column}}", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "bytes", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 25, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "normal", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "table", + "placement": "bottom", + "showLegend": true, + "calcs": [ + "lastNotNull" + ] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + }, + { + "type": "timeseries", + "title": "Cache entries", + "description": "", + "id": 24, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 50 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum by (name) (continuwuity_cache_entries{instance=~\"$instance\"})", + "legendFormat": "{{name}}", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "short", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "none", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true, + "calcs": [] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + }, + { + "type": "row", + "title": "Tokio runtime", + "id": 25, + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 58 + }, + "panels": [] + }, + { + "type": "timeseries", + "title": "Worker utilisation", + "description": "Average share of time worker threads spend busy", + "id": 26, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 59 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(continuwuity_tokio_worker_busy_seconds_total{instance=~\"$instance\"}[$__rate_interval])) / sum(continuwuity_tokio_workers{instance=~\"$instance\"})", + "legendFormat": "busy", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "percentunit", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "none", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true, + "calcs": [] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + }, + { + "type": "timeseries", + "title": "Tasks", + "description": "", + "id": 27, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 59 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(continuwuity_tokio_alive_tasks{instance=~\"$instance\"})", + "legendFormat": "alive", + "refId": "A", + "range": true + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(continuwuity_tokio_global_queue_depth{instance=~\"$instance\"})", + "legendFormat": "global queue", + "refId": "B", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "short", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "none", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true, + "calcs": [] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + }, + { + "type": "timeseries", + "title": "Worker parks", + "description": "", + "id": 28, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 59 + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "expr": "sum(rate(continuwuity_tokio_worker_parks_total{instance=~\"$instance\"}[$__rate_interval]))", + "legendFormat": "parks", + "refId": "A", + "range": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "ops", + "min": 0, + "color": { + "mode": "palette-classic" + }, + "custom": { + "drawStyle": "line", + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "mode": "none", + "group": "A" + } + } + }, + "overrides": [] + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true, + "calcs": [] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + } + } + ], + "refresh": "30s", + "schemaVersion": 41, + "tags": [ + "continuwuity", + "matrix" + ], + "templating": { + "list": [ + { + "name": "datasource", + "label": "Data source", + "type": "datasource", + "query": "prometheus", + "current": {}, + "hide": 0, + "refresh": 1, + "regex": "", + "options": [] + }, + { + "name": "instance", + "label": "Instance", + "type": "query", + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "definition": "label_values(continuwuity_build_info, instance)", + "query": { + "query": "label_values(continuwuity_build_info, instance)", + "refId": "instance" + }, + "includeAll": true, + "multi": true, + "allValue": ".*", + "current": {}, + "hide": 0, + "refresh": 2, + "regex": "", + "sort": 1, + "options": [] + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Continuwuity", + "uid": "continuwuity", + "version": 1 +} diff --git a/rspress.config.ts b/rspress.config.ts index d0571d812..5eb5e5e93 100644 --- a/rspress.config.ts +++ b/rspress.config.ts @@ -31,6 +31,7 @@ export default defineConfig({ '/advanced/delegated.docker-compose.with-traefik.yml', '/calls/livekit.docker-compose.with-caddy-labels.yml', '/calls/livekit.nginx.conf', + '/guides/grafana-dashboard.json', 'CONTRIBUTING.md' ] },