Skip to content

Commit cc00167

Browse files
fix(grafana): add metrics update loop and clean up comparison dashboard
Add concurrent Prometheus metrics update loop that exports test progress and throughput metrics every second during performance test runs. This fixes "No Data" panels in the Overview dashboard. Remove redundant P50 delta panels from the comparison dashboard and adjust grid positions for cleaner layout.
1 parent 68310d9 commit cc00167

File tree

2 files changed

+71
-101
lines changed

2 files changed

+71
-101
lines changed

configs/dashboards/comparison.json

Lines changed: 10 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -403,99 +403,9 @@
403403
"title": "Latency Comparison Over Time",
404404
"type": "timeseries"
405405
},
406-
{
407-
"datasource": { "type": "prometheus", "uid": "prometheus" },
408-
"description": "Positive = slower (regression). Negative = faster (improvement).",
409-
"fieldConfig": {
410-
"defaults": {
411-
"color": { "mode": "thresholds" },
412-
"mappings": [],
413-
"thresholds": {
414-
"mode": "absolute",
415-
"steps": [
416-
{ "color": "green", "value": null },
417-
{ "color": "yellow", "value": 5 },
418-
{ "color": "red", "value": 15 }
419-
]
420-
},
421-
"unit": "percent"
422-
},
423-
"overrides": []
424-
},
425-
"gridPos": { "h": 4, "w": 6, "x": 0, "y": 10 },
426-
"id": 10,
427-
"options": {
428-
"colorMode": "value",
429-
"graphMode": "none",
430-
"justifyMode": "auto",
431-
"orientation": "auto",
432-
"reduceOptions": {
433-
"calcs": ["lastNotNull"],
434-
"fields": "",
435-
"values": false
436-
},
437-
"textMode": "auto"
438-
},
439-
"pluginVersion": "10.0.0",
440-
"targets": [
441-
{
442-
"datasource": { "type": "prometheus", "uid": "prometheus" },
443-
"expr": "cow_perf_baseline_comparison_percent{metric=\"submission_latency_p50\", baseline_id=~\"$baseline_id\"}",
444-
"legendFormat": "P50",
445-
"refId": "A"
446-
}
447-
],
448-
"title": "Submission P50 Delta",
449-
"type": "stat"
450-
},
451-
{
452-
"datasource": { "type": "prometheus", "uid": "prometheus" },
453-
"description": "Positive = slower (regression). Negative = faster (improvement).",
454-
"fieldConfig": {
455-
"defaults": {
456-
"color": { "mode": "thresholds" },
457-
"mappings": [],
458-
"thresholds": {
459-
"mode": "absolute",
460-
"steps": [
461-
{ "color": "green", "value": null },
462-
{ "color": "yellow", "value": 5 },
463-
{ "color": "red", "value": 15 }
464-
]
465-
},
466-
"unit": "percent"
467-
},
468-
"overrides": []
469-
},
470-
"gridPos": { "h": 4, "w": 6, "x": 6, "y": 10 },
471-
"id": 11,
472-
"options": {
473-
"colorMode": "value",
474-
"graphMode": "none",
475-
"justifyMode": "auto",
476-
"orientation": "auto",
477-
"reduceOptions": {
478-
"calcs": ["lastNotNull"],
479-
"fields": "",
480-
"values": false
481-
},
482-
"textMode": "auto"
483-
},
484-
"pluginVersion": "10.0.0",
485-
"targets": [
486-
{
487-
"datasource": { "type": "prometheus", "uid": "prometheus" },
488-
"expr": "cow_perf_baseline_comparison_percent{metric=\"settlement_latency_p50\", baseline_id=~\"$baseline_id\"}",
489-
"legendFormat": "P50",
490-
"refId": "A"
491-
}
492-
],
493-
"title": "Settlement P50 Delta",
494-
"type": "stat"
495-
},
496406
{
497407
"collapsed": false,
498-
"gridPos": { "h": 1, "w": 24, "x": 0, "y": 14 },
408+
"gridPos": { "h": 1, "w": 24, "x": 0, "y": 10 },
499409
"id": 12,
500410
"panels": [],
501411
"title": "Throughput",
@@ -520,7 +430,7 @@
520430
},
521431
"overrides": []
522432
},
523-
"gridPos": { "h": 4, "w": 6, "x": 0, "y": 15 },
433+
"gridPos": { "h": 4, "w": 6, "x": 0, "y": 11 },
524434
"id": 13,
525435
"options": {
526436
"colorMode": "value",
@@ -565,7 +475,7 @@
565475
},
566476
"overrides": []
567477
},
568-
"gridPos": { "h": 4, "w": 6, "x": 6, "y": 15 },
478+
"gridPos": { "h": 4, "w": 6, "x": 6, "y": 11 },
569479
"id": 14,
570480
"options": {
571481
"colorMode": "value",
@@ -624,7 +534,7 @@
624534
},
625535
"overrides": []
626536
},
627-
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 15 },
537+
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 11 },
628538
"id": 15,
629539
"options": {
630540
"legend": {
@@ -666,7 +576,7 @@
666576
},
667577
"overrides": []
668578
},
669-
"gridPos": { "h": 4, "w": 6, "x": 0, "y": 19 },
579+
"gridPos": { "h": 4, "w": 6, "x": 0, "y": 15 },
670580
"id": 16,
671581
"options": {
672582
"colorMode": "value",
@@ -694,7 +604,7 @@
694604
},
695605
{
696606
"collapsed": false,
697-
"gridPos": { "h": 1, "w": 24, "x": 0, "y": 23 },
607+
"gridPos": { "h": 1, "w": 24, "x": 0, "y": 19 },
698608
"id": 17,
699609
"panels": [],
700610
"title": "Regressions",
@@ -717,7 +627,7 @@
717627
},
718628
"overrides": []
719629
},
720-
"gridPos": { "h": 4, "w": 4, "x": 0, "y": 24 },
630+
"gridPos": { "h": 4, "w": 4, "x": 0, "y": 20 },
721631
"id": 18,
722632
"options": {
723633
"colorMode": "background",
@@ -760,7 +670,7 @@
760670
},
761671
"overrides": []
762672
},
763-
"gridPos": { "h": 4, "w": 4, "x": 4, "y": 24 },
673+
"gridPos": { "h": 4, "w": 4, "x": 4, "y": 20 },
764674
"id": 19,
765675
"options": {
766676
"colorMode": "background",
@@ -803,7 +713,7 @@
803713
},
804714
"overrides": []
805715
},
806-
"gridPos": { "h": 4, "w": 4, "x": 8, "y": 24 },
716+
"gridPos": { "h": 4, "w": 4, "x": 8, "y": 20 },
807717
"id": 20,
808718
"options": {
809719
"colorMode": "background",
@@ -866,7 +776,7 @@
866776
}
867777
]
868778
},
869-
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 24 },
779+
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 20 },
870780
"id": 21,
871781
"options": {
872782
"cellHeight": "sm",

src/cow_performance/cli/commands/run.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import asyncio
44
import signal
55
import sys
6+
import time
67
from datetime import datetime
78
from pathlib import Path
89
from typing import Any
@@ -66,6 +67,43 @@ def handle_signal(self, signum: int, frame: Any) -> None:
6667
self.orchestrator._running = False
6768

6869

70+
async def update_prometheus_metrics(
71+
exporter: PrometheusExporter,
72+
orchestrator: TraderOrchestrator,
73+
test_duration: float,
74+
target_rate: float,
75+
) -> None:
76+
"""Periodically update Prometheus progress and throughput metrics.
77+
78+
Args:
79+
exporter: The Prometheus exporter to update
80+
orchestrator: The trader orchestrator (to check running state and get order counts)
81+
test_duration: Total test duration in seconds
82+
target_rate: Target orders per second
83+
"""
84+
start_time = time.time()
85+
86+
while orchestrator._running:
87+
elapsed = time.time() - start_time
88+
89+
# Update progress (0-100%)
90+
progress_percent = min(100.0, (elapsed / test_duration) * 100)
91+
exporter.update_progress(progress_percent)
92+
93+
# Calculate actual rate
94+
total_orders = orchestrator.trader_pool.get_total_orders_submitted()
95+
actual_rate = total_orders / elapsed if elapsed > 0 else 0.0
96+
97+
# Update throughput metrics
98+
exporter.update_throughput(
99+
orders_per_second=actual_rate,
100+
target_rate=target_rate,
101+
actual_rate=actual_rate,
102+
)
103+
104+
await asyncio.sleep(1.0) # Update every second
105+
106+
69107
async def run_performance_test(
70108
config: PerformanceTestConfig,
71109
traders: int | None = None,
@@ -449,7 +487,29 @@ async def run_performance_test(
449487
try:
450488
# Start test
451489
start_time = datetime.now()
452-
await orchestrator.run()
490+
491+
if prometheus_exporter:
492+
# Calculate target rate from behavior config (orders per minute -> per second)
493+
target_rate = behavior_config.base_rate / 60.0
494+
495+
# Run orchestrator and metrics update loop concurrently
496+
metrics_task = asyncio.create_task(
497+
update_prometheus_metrics(
498+
prometheus_exporter,
499+
orchestrator,
500+
float(test_duration),
501+
target_rate,
502+
)
503+
)
504+
await orchestrator.run()
505+
metrics_task.cancel() # Stop metrics loop when test completes
506+
try:
507+
await metrics_task
508+
except asyncio.CancelledError:
509+
pass
510+
else:
511+
await orchestrator.run()
512+
453513
end_time = datetime.now()
454514

455515
progress.update(task, description="[bold green]Test completed!")

0 commit comments

Comments
 (0)