From 00aca80180ca5c48480302fb551300a0136dd8fe Mon Sep 17 00:00:00 2001 From: mamad Date: Thu, 27 Aug 2026 20:52:58 +0330 Subject: [PATCH] feat(grafana): expand executive dashboard with all telemetry, rate, queue and ai metrics --- monitoring/grafana/Dockerfile | 1 + monitoring/grafana/dashboards/copykar.json | 233 +++++++++++++++--- .../provisioning/dashboards/dashboards.yml | 4 +- 3 files changed, 198 insertions(+), 40 deletions(-) diff --git a/monitoring/grafana/Dockerfile b/monitoring/grafana/Dockerfile index 8eac12f..7afb1b5 100644 --- a/monitoring/grafana/Dockerfile +++ b/monitoring/grafana/Dockerfile @@ -1,2 +1,3 @@ FROM grafana/grafana:11.2.0 COPY provisioning /etc/grafana/provisioning +COPY dashboards /etc/grafana/provisioning/dashboards diff --git a/monitoring/grafana/dashboards/copykar.json b/monitoring/grafana/dashboards/copykar.json index 75f2cc9..f152241 100644 --- a/monitoring/grafana/dashboards/copykar.json +++ b/monitoring/grafana/dashboards/copykar.json @@ -4,90 +4,200 @@ }, "editable": true, "fiscalYearStartMonth": 0, - "graphTooltip": 0, + "graphTooltip": 1, "id": null, "links": [], - "liveNow": false, + "liveNow": true, "panels": [ { "collapsed": false, - "gridPos": { "h": 6, "w": 6, "x": 0, "y": 0 }, + "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, + "id": 100, + "title": "📌 Key Performance Indicators", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { "h": 4, "w": 4, "x": 0, "y": 1 }, "id": 1, "title": "Total Posts Collected", "type": "stat", "targets": [ { - "expr": "sum(copykar_posts_collected_total)", - "legendFormat": "Collected Posts", + "expr": "sum(copykar_posts_collected_total) or vector(0)", + "legendFormat": "Collected", "refId": "A" } - ] + ], + "fieldConfig": { + "defaults": { + "color": { "mode": "palette-classic" }, + "mappings": [], + "thresholds": { "mode": "absolute", "steps": [{ "color": "blue", "value": null }] } + } + } }, { "collapsed": false, - "gridPos": { "h": 6, "w": 6, "x": 6, "y": 0 }, + "gridPos": { "h": 4, "w": 4, "x": 4, "y": 1 }, "id": 2, - "title": "Total Duplicates Caught", + "title": "Duplicates Intercepted", "type": "stat", "targets": [ { - "expr": "sum(copykar_duplicates_detected_total)", + "expr": "sum(copykar_duplicates_detected_total) or vector(0)", "legendFormat": "Duplicates", "refId": "A" } - ] + ], + "fieldConfig": { + "defaults": { + "color": { "mode": "palette-classic" }, + "thresholds": { "mode": "absolute", "steps": [{ "color": "orange", "value": null }] } + } + } }, { "collapsed": false, - "gridPos": { "h": 6, "w": 6, "x": 12, "y": 0 }, + "gridPos": { "h": 4, "w": 4, "x": 8, "y": 1 }, "id": 3, "title": "Admin Approvals", "type": "stat", "targets": [ { - "expr": "sum(copykar_admin_actions_total{action=\"approved\"})", + "expr": "sum(copykar_admin_actions_total{action=\"approved\"}) or vector(0)", "legendFormat": "Approved", "refId": "A" } - ] + ], + "fieldConfig": { + "defaults": { + "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] } + } + } }, { "collapsed": false, - "gridPos": { "h": 6, "w": 6, "x": 18, "y": 0 }, + "gridPos": { "h": 4, "w": 4, "x": 12, "y": 1 }, "id": 4, + "title": "Admin Rejections", + "type": "stat", + "targets": [ + { + "expr": "sum(copykar_admin_actions_total{action=\"rejected\"}) or vector(0)", + "legendFormat": "Rejected", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "thresholds": { "mode": "absolute", "steps": [{ "color": "red", "value": null }] } + } + } + }, + { + "collapsed": false, + "gridPos": { "h": 4, "w": 4, "x": 16, "y": 1 }, + "id": 5, "title": "Posts Published", "type": "stat", "targets": [ { - "expr": "sum(copykar_posts_published_total)", + "expr": "sum(copykar_posts_published_total) or vector(0)", "legendFormat": "Published", "refId": "A" } - ] + ], + "fieldConfig": { + "defaults": { + "thresholds": { "mode": "absolute", "steps": [{ "color": "purple", "value": null }] } + } + } }, { "collapsed": false, - "gridPos": { "h": 8, "w": 12, "x": 0, "y": 6 }, - "id": 5, - "title": "Post Ingestion Rate (per minute)", + "gridPos": { "h": 4, "w": 4, "x": 20, "y": 1 }, + "id": 6, + "title": "AI Requests Total", + "type": "stat", + "targets": [ + { + "expr": "sum(copykar_ai_requests_total) or vector(0)", + "legendFormat": "AI Calls", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "thresholds": { "mode": "absolute", "steps": [{ "color": "cyan", "value": null }] } + } + } + }, + { + "collapsed": false, + "gridPos": { "h": 1, "w": 24, "x": 0, "y": 5 }, + "id": 101, + "title": "📈 Pipeline Ingestion, Queues & Publishing", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { "h": 8, "w": 8, "x": 0, "y": 6 }, + "id": 7, + "title": "Ingestion Rate by Source (posts/min)", "type": "timeseries", "targets": [ { "expr": "rate(copykar_posts_collected_total[1m]) * 60", - "legendFormat": "Channel {{source_channel_id}}", + "legendFormat": "Source: {{source_channel_id}}", "refId": "A" } ] }, { "collapsed": false, - "gridPos": { "h": 8, "w": 12, "x": 12, "y": 6 }, - "id": 6, - "title": "Duplicates Detected by Method", + "gridPos": { "h": 8, "w": 8, "x": 8, "y": 6 }, + "id": 8, + "title": "Publishing Rate by Target (posts/min)", "type": "timeseries", "targets": [ { - "expr": "rate(copykar_duplicates_detected_total[1m]) * 60", + "expr": "rate(copykar_posts_published_total[1m]) * 60", + "legendFormat": "Target: {{target_channel_id}}", + "refId": "A" + } + ] + }, + { + "collapsed": false, + "gridPos": { "h": 8, "w": 8, "x": 16, "y": 6 }, + "id": 9, + "title": "Active Queue Depth", + "type": "timeseries", + "targets": [ + { + "expr": "copykar_posts_queue_gauge", + "legendFormat": "Queue: {{status}}", + "refId": "A" + } + ] + }, + { + "collapsed": false, + "gridPos": { "h": 1, "w": 24, "x": 0, "y": 14 }, + "id": 102, + "title": "🤖 AI Operations & Deduplication Analytics", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 15 }, + "id": 10, + "title": "Duplicates Intercepted by Method", + "type": "timeseries", + "targets": [ + { + "expr": "sum by (method) (rate(copykar_duplicates_detected_total[1m]) * 60)", "legendFormat": "Method: {{method}}", "refId": "A" } @@ -95,44 +205,89 @@ }, { "collapsed": false, - "gridPos": { "h": 8, "w": 12, "x": 0, "y": 14 }, - "id": 7, - "title": "AI Latency (p95 / Average in seconds)", + "gridPos": { "h": 8, "w": 12, "x": 12, "y": 15 }, + "id": 11, + "title": "AI Latency (p95 & Average Duration in sec)", "type": "timeseries", "targets": [ { "expr": "histogram_quantile(0.95, sum(rate(copykar_ai_latency_seconds_bucket[5m])) by (le, action))", - "legendFormat": "p95 - {{action}}", + "legendFormat": "p95: {{action}}", + "refId": "A" + }, + { + "expr": "rate(copykar_ai_latency_seconds_sum[5m]) / rate(copykar_ai_latency_seconds_count[5m])", + "legendFormat": "Avg: {{action}}", + "refId": "B" + } + ] + }, + { + "collapsed": false, + "gridPos": { "h": 1, "w": 24, "x": 0, "y": 23 }, + "id": 103, + "title": "⚡ Container & System Telemetry", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { "h": 7, "w": 8, "x": 0, "y": 24 }, + "id": 12, + "title": "Process CPU Usage (%)", + "type": "timeseries", + "targets": [ + { + "expr": "rate(process_cpu_seconds_total{job=\"copykar\"}[1m]) * 100", + "legendFormat": "CPU Usage %", "refId": "A" } ] }, { "collapsed": false, - "gridPos": { "h": 8, "w": 12, "x": 12, "y": 14 }, - "id": 8, - "title": "Pending Queue Depth", + "gridPos": { "h": 7, "w": 8, "x": 8, "y": 24 }, + "id": 13, + "title": "Process RAM Usage (MB)", "type": "timeseries", "targets": [ { - "expr": "copykar_posts_queue_gauge", - "legendFormat": "Status: {{status}}", + "expr": "process_resident_memory_bytes{job=\"copykar\"} / 1024 / 1024", + "legendFormat": "Memory (MB)", "refId": "A" } ] + }, + { + "collapsed": false, + "gridPos": { "h": 7, "w": 8, "x": 16, "y": 24 }, + "id": 14, + "title": "Active Threads & Open FDs", + "type": "timeseries", + "targets": [ + { + "expr": "process_threads_total{job=\"copykar\"}", + "legendFormat": "Threads", + "refId": "A" + }, + { + "expr": "process_open_fds{job=\"copykar\"}", + "legendFormat": "Open FDs", + "refId": "B" + } + ] } ], - "refresh": "10s", + "refresh": "5s", "schemaVersion": 38, "style": "dark", - "tags": ["copykar", "telegram"], + "tags": ["copykar", "telegram", "ai", "telemetry"], "time": { "from": "now-1h", "to": "now" }, "timepicker": {}, - "timezone": "", - "title": "Copykar Telegram Fleet Dashboard", - "uid": "copykar-fleet-metrics", - "version": 1 + "timezone": "browser", + "title": "Copykar Telegram Fleet Executive Dashboard", + "uid": "copykar-executive-dashboard", + "version": 2 } diff --git a/monitoring/grafana/provisioning/dashboards/dashboards.yml b/monitoring/grafana/provisioning/dashboards/dashboards.yml index 7c03472..bdd298c 100644 --- a/monitoring/grafana/provisioning/dashboards/dashboards.yml +++ b/monitoring/grafana/provisioning/dashboards/dashboards.yml @@ -3,9 +3,11 @@ apiVersion: 1 providers: - name: 'Copykar Dashboards' orgId: 1 - folder: '' + folder: 'Copykar Fleet' type: file disableDeletion: false editable: true + updateIntervalSeconds: 10 + allowUiUpdates: true options: path: /etc/grafana/provisioning/dashboards