Skip to content

Commit fd608dd

Browse files
committed
Add OpenTelemetry metrics with Prometheus + Grafana monitoring stack
1 parent ea9bbfd commit fd608dd

11 files changed

Lines changed: 882 additions & 61 deletions

File tree

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,21 @@ client.chat.completions.create(..., extra_headers={"X-Kompact-Disable": "toon,co
9191

9292
Comma-separated transform names: `toon`, `json_crusher`, `code_compressor`, `log_compressor`, `content_compressor`, `observation_masker`, `cache_aligner`, `schema_optimizer`.
9393

94+
## Monitoring
95+
96+
Kompact exports OpenTelemetry metrics (on by default, disable with `--no-otel`). A Prometheus + Grafana stack is included:
97+
98+
```bash
99+
cd monitoring
100+
docker compose up -d
101+
```
102+
103+
- **Grafana dashboard**: http://localhost:9473 (pre-built "Kompact" dashboard)
104+
- **Prometheus**: http://localhost:9090
105+
- **Metrics endpoint**: http://localhost:9464/metrics
106+
107+
The dashboard shows request rate, token savings, compression ratio, pipeline latency percentiles, and per-transform breakdowns.
108+
94109
## Running benchmarks
95110

96111
```bash

monitoring/docker-compose.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
services:
2+
prometheus:
3+
image: prom/prometheus:latest
4+
ports:
5+
- "9090:9090"
6+
volumes:
7+
- ./prometheus.yml:/etc/prometheus/prometheus.yml
8+
- prometheus-data:/prometheus
9+
extra_hosts:
10+
- "host.docker.internal:host-gateway"
11+
12+
grafana:
13+
image: grafana/grafana:latest
14+
ports:
15+
- "9473:3000"
16+
environment:
17+
- GF_SECURITY_ADMIN_PASSWORD=admin
18+
- GF_AUTH_ANONYMOUS_ENABLED=true
19+
- GF_AUTH_ANONYMOUS_ORG_ROLE=Viewer
20+
volumes:
21+
- ./grafana/provisioning:/etc/grafana/provisioning
22+
- ./grafana/dashboards:/var/lib/grafana/dashboards
23+
- grafana-data:/var/lib/grafana
24+
25+
volumes:
26+
prometheus-data:
27+
grafana-data:
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
{
2+
"title": "Kompact",
3+
"uid": "kompact",
4+
"editable": true,
5+
"time": { "from": "now-1h", "to": "now" },
6+
"refresh": "5s",
7+
"panels": [
8+
{
9+
"title": "Request Rate",
10+
"type": "timeseries",
11+
"gridPos": { "h": 8, "w": 8, "x": 0, "y": 0 },
12+
"targets": [
13+
{
14+
"expr": "rate(kompact_requests_total[1m])",
15+
"legendFormat": "{{model}}"
16+
}
17+
],
18+
"fieldConfig": {
19+
"defaults": { "unit": "reqps" }
20+
},
21+
"options": {
22+
"legend": { "displayMode": "list", "placement": "bottom" }
23+
}
24+
},
25+
{
26+
"title": "Tokens Saved (rate/min)",
27+
"type": "timeseries",
28+
"gridPos": { "h": 8, "w": 8, "x": 8, "y": 0 },
29+
"targets": [
30+
{
31+
"expr": "rate(kompact_tokens_saved_total[1m]) * 60",
32+
"legendFormat": "{{model}}"
33+
}
34+
],
35+
"fieldConfig": {
36+
"defaults": { "unit": "short" }
37+
},
38+
"options": {
39+
"legend": { "displayMode": "list", "placement": "bottom" }
40+
}
41+
},
42+
{
43+
"title": "Token Savings",
44+
"type": "gauge",
45+
"gridPos": { "h": 8, "w": 8, "x": 16, "y": 0 },
46+
"targets": [
47+
{
48+
"expr": "sum(rate(kompact_tokens_saved_total[5m])) / sum(rate(kompact_tokens_processed_total[5m]))",
49+
"legendFormat": "savings"
50+
}
51+
],
52+
"fieldConfig": {
53+
"defaults": {
54+
"unit": "percentunit",
55+
"min": 0,
56+
"max": 1,
57+
"thresholds": {
58+
"steps": [
59+
{ "color": "red", "value": null },
60+
{ "color": "yellow", "value": 0.2 },
61+
{ "color": "green", "value": 0.4 }
62+
]
63+
}
64+
}
65+
},
66+
"options": {
67+
"showThresholdLabels": true,
68+
"showThresholdMarkers": true,
69+
"text": { "titleSize": 14, "valueSize": 32 }
70+
}
71+
},
72+
{
73+
"title": "Total Tokens Saved",
74+
"type": "stat",
75+
"gridPos": { "h": 4, "w": 6, "x": 0, "y": 8 },
76+
"targets": [
77+
{
78+
"expr": "sum(kompact_tokens_saved_total)",
79+
"legendFormat": "tokens"
80+
}
81+
],
82+
"fieldConfig": {
83+
"defaults": { "unit": "short" }
84+
}
85+
},
86+
{
87+
"title": "Total Tokens Processed",
88+
"type": "stat",
89+
"gridPos": { "h": 4, "w": 6, "x": 6, "y": 8 },
90+
"targets": [
91+
{
92+
"expr": "sum(kompact_tokens_processed_total)",
93+
"legendFormat": "tokens"
94+
}
95+
],
96+
"fieldConfig": {
97+
"defaults": { "unit": "short" }
98+
}
99+
},
100+
{
101+
"title": "Total Requests",
102+
"type": "stat",
103+
"gridPos": { "h": 4, "w": 6, "x": 12, "y": 8 },
104+
"targets": [
105+
{
106+
"expr": "sum(kompact_requests_total)",
107+
"legendFormat": "requests"
108+
}
109+
]
110+
},
111+
{
112+
"title": "Pipeline Latency (p50 / p95 / p99)",
113+
"type": "timeseries",
114+
"gridPos": { "h": 4, "w": 6, "x": 18, "y": 8 },
115+
"targets": [
116+
{
117+
"expr": "histogram_quantile(0.50, sum(rate(kompact_pipeline_latency_ms_bucket[5m])) by (le))",
118+
"legendFormat": "p50"
119+
},
120+
{
121+
"expr": "histogram_quantile(0.95, sum(rate(kompact_pipeline_latency_ms_bucket[5m])) by (le))",
122+
"legendFormat": "p95"
123+
},
124+
{
125+
"expr": "histogram_quantile(0.99, sum(rate(kompact_pipeline_latency_ms_bucket[5m])) by (le))",
126+
"legendFormat": "p99"
127+
}
128+
],
129+
"fieldConfig": {
130+
"defaults": { "unit": "ms" }
131+
},
132+
"options": {
133+
"legend": { "displayMode": "list", "placement": "bottom" }
134+
}
135+
},
136+
{
137+
"title": "Tokens Saved by Transform",
138+
"type": "timeseries",
139+
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 12 },
140+
"targets": [
141+
{
142+
"expr": "rate(kompact_transform_tokens_saved_total[1m]) * 60",
143+
"legendFormat": "{{transform}}"
144+
}
145+
],
146+
"fieldConfig": {
147+
"defaults": { "unit": "short" }
148+
},
149+
"options": {
150+
"legend": { "displayMode": "list", "placement": "bottom" }
151+
}
152+
},
153+
{
154+
"title": "Transform Latency (p95)",
155+
"type": "timeseries",
156+
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 12 },
157+
"targets": [
158+
{
159+
"expr": "histogram_quantile(0.95, sum(rate(kompact_transform_latency_ms_bucket[5m])) by (le, transform))",
160+
"legendFormat": "{{transform}}"
161+
}
162+
],
163+
"fieldConfig": {
164+
"defaults": { "unit": "ms" }
165+
},
166+
"options": {
167+
"legend": { "displayMode": "list", "placement": "bottom" }
168+
}
169+
},
170+
{
171+
"title": "Savings Over Time (cumulative)",
172+
"type": "timeseries",
173+
"gridPos": { "h": 8, "w": 24, "x": 0, "y": 20 },
174+
"targets": [
175+
{
176+
"expr": "sum(kompact_tokens_saved_total)",
177+
"legendFormat": "saved"
178+
},
179+
{
180+
"expr": "sum(kompact_tokens_processed_total)",
181+
"legendFormat": "processed"
182+
}
183+
],
184+
"fieldConfig": {
185+
"defaults": { "unit": "short" }
186+
},
187+
"options": {
188+
"legend": { "displayMode": "list", "placement": "bottom" }
189+
}
190+
}
191+
]
192+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apiVersion: 1
2+
providers:
3+
- name: Kompact
4+
type: file
5+
options:
6+
path: /var/lib/grafana/dashboards
7+
foldersFromFilesStructure: false
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apiVersion: 1
2+
datasources:
3+
- name: Prometheus
4+
type: prometheus
5+
access: proxy
6+
url: http://prometheus:9090
7+
isDefault: true

monitoring/prometheus.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
global:
2+
scrape_interval: 5s
3+
4+
scrape_configs:
5+
- job_name: kompact
6+
static_configs:
7+
- targets: ["host.docker.internal:9464"]

pyproject.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "kompact"
3-
version = "0.2.0"
3+
version = "0.3.0"
44
description = "Multi-layer context optimization proxy for LLM agents"
55
readme = "README.md"
66
license = "MIT"
@@ -22,6 +22,11 @@ dependencies = [
2222
"httpx>=0.28.0",
2323
"tiktoken>=0.8.0",
2424
"click>=8.1.0",
25+
"opentelemetry-api>=1.20.0",
26+
"opentelemetry-sdk>=1.20.0",
27+
"opentelemetry-exporter-otlp-proto-grpc>=1.20.0",
28+
"opentelemetry-exporter-prometheus>=0.40b0",
29+
"prometheus-client>=0.20.0",
2530
]
2631

2732
[project.optional-dependencies]

0 commit comments

Comments
 (0)