Skip to content

Commit 521a49f

Browse files
committed
use prometheus instead of benchstat
1 parent 08a24d1 commit 521a49f

File tree

1 file changed

+128
-6
lines changed

1 file changed

+128
-6
lines changed

.github/workflows/benchmark.yaml

+128-6
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,136 @@ jobs:
3333
mkdir -p /tmp/artifacts/
3434
ARTIFACT_PATH=/tmp/artifacts make test-benchmark
3535
36-
- name: Compare with baseline
36+
- name: Convert Benchmark Output to Prometheus Metrics
3737
run: |
38-
go install golang.org/x/perf/cmd/benchstat@latest
39-
benchstat benchmarks/baseline.txt /tmp/artifacts/new.txt | tee /tmp/artifacts/output
38+
mkdir -p /tmp/artifacts/prometheus/
39+
cat << 'EOF' > benchmark_to_prometheus.py
40+
import sys
41+
import re
4042
41-
- name: Upload benchmark results
43+
def parse_benchmark_output(benchmark_output):
44+
metrics = []
45+
for line in benchmark_output.split("\n"):
46+
match = re.match(r"Benchmark([\w\d]+)-\d+\s+\d+\s+([\d]+)\s+ns/op\s+([\d]+)\s+B/op\s+([\d]+)\s+allocs/op", line)
47+
if match:
48+
benchmark_name = match.group(1).lower()
49+
time_ns = match.group(2)
50+
memory_bytes = match.group(3)
51+
allocs = match.group(4)
52+
53+
metrics.append(f"benchmark_{benchmark_name}_ns {time_ns}")
54+
metrics.append(f"benchmark_{benchmark_name}_allocs {allocs}")
55+
metrics.append(f"benchmark_{benchmark_name}_mem_bytes {memory_bytes}")
56+
57+
return "\n".join(metrics)
58+
59+
if __name__ == "__main__":
60+
benchmark_output = sys.stdin.read()
61+
metrics = parse_benchmark_output(benchmark_output)
62+
print(metrics)
63+
EOF
64+
65+
cat /tmp/artifacts/new.txt | python3 benchmark_to_prometheus.py > /tmp/artifacts/prometheus/metrics.txt
66+
67+
# - name: Compare with baseline
68+
# run: |
69+
# go install golang.org/x/perf/cmd/benchstat@latest
70+
# benchstat benchmarks/baseline.txt /tmp/artifacts/new.txt | tee /tmp/artifacts/output
71+
72+
- name: Upload Benchmark Metrics
73+
uses: actions/upload-artifact@v4
74+
with:
75+
name: benchmark-metrics
76+
path: /tmp/artifacts/prometheus/
77+
78+
start-prometheus:
79+
needs: benchmark
80+
runs-on: ubuntu-latest
81+
steps:
82+
- name: Checkout code
83+
uses: actions/checkout@v4
84+
with:
85+
fetch-depth: 0
86+
87+
- name: Download Benchmark Metrics
88+
uses: actions/download-artifact@v4
89+
with:
90+
name: benchmark-metrics
91+
path: ./
92+
93+
- name: List Downloaded Metrics files
94+
run: ls -lh
95+
96+
- name: Set Up Prometheus Config
97+
run: |
98+
cat << 'EOF' > prometheus.yml
99+
global:
100+
scrape_interval: 5s
101+
scrape_configs:
102+
- job_name: 'benchmark_metrics'
103+
static_configs:
104+
- targets: ['localhost:9000']
105+
EOF
106+
107+
- name: Run Prometheus
108+
run: |
109+
docker run -d --name prometheus -p 9090:9090 \
110+
-v ${{ github.workspace }}/prometheus.yml:/etc/prometheus/prometheus.yml \
111+
-v ${{ github.workspace }}/prometheus-data:/prometheus \
112+
prom/prometheus --config.file=/etc/prometheus/prometheus.yml \
113+
--storage.tsdb.path=/prometheus --storage.tsdb.retention.time=1h
114+
115+
- name: Wait for Prometheus to start
116+
run: sleep 10
117+
118+
- name: Check Prometheus is running
119+
run: curl -s http://localhost:9090/-/ready || (docker logs prometheus && exit 1)
120+
121+
- name: Start HTTP Server to Expose Metrics
122+
run: |
123+
cat << 'EOF' > server.py
124+
from http.server import SimpleHTTPRequestHandler, HTTPServer
125+
126+
class MetricsHandler(SimpleHTTPRequestHandler):
127+
def do_GET(self):
128+
if self.path == "/metrics":
129+
self.send_response(200)
130+
self.send_header("Content-type", "text/plain")
131+
self.end_headers()
132+
with open("metrics.txt", "r") as f:
133+
self.wfile.write(f.read().encode())
134+
else:
135+
self.send_response(404)
136+
self.end_headers()
137+
138+
if __name__ == "__main__":
139+
server = HTTPServer(('0.0.0.0', 9000), MetricsHandler)
140+
print("Serving on port 9000...")
141+
server.serve_forever()
142+
EOF
143+
144+
nohup python3 server.py &
145+
146+
- name: Wait for Prometheus to Collect Data
147+
run: sleep 30
148+
149+
- name: Trigger Prometheus Snapshot
150+
run: |
151+
curl -X POST http://localhost:9090/api/v1/admin/tsdb/snapshot
152+
153+
- name: Stop Prometheus
154+
run: docker stop prometheus
155+
156+
- name: Find and Upload Prometheus Snapshot
157+
run: |
158+
SNAPSHOT_PATH=$(ls -td /prometheus/snapshots/* | head -1)
159+
echo "Prometheus snapshot stored in: $SNAPSHOT_PATH"
160+
tar -czf prometheus_snapshot.tar.gz -C "$SNAPSHOT_PATH" .
161+
mv prometheus_snapshot.tar.gz $GITHUB_WORKSPACE/
162+
163+
- name: Upload Prometheus Snapshot
42164
uses: actions/upload-artifact@v4
43165
with:
44-
name: benchmark-artifacts
45-
path: /tmp/artifacts/
166+
name: prometheus-snapshot
167+
path: prometheus_snapshot.tar.gz
46168

0 commit comments

Comments
 (0)