Skip to content

Commit 05c6163

Browse files
Design doc for prometheus metrics from queries
1 parent b31cb27 commit 05c6163

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Prometheus Metrics From Queries
2+
3+
## The Problem
4+
5+
Users want to be able to monitor their Materialize workloads and data products.
6+
Setting up external tools to convert SQL queries into prometheus metrics is labor intensive, error prone, and often buggy.
7+
8+
This also applies to Materialize Cloud, as we run our own external SQL exporter which could be removed if this could be hosted by environmentd.
9+
10+
## Success Criteria
11+
12+
- Users can define SQL queries that get turned into prometheus metrics.
13+
- Users can group these metrics into HTTP endpoints, so they may have separate scrape configs (for different auth requirements and/or scrape frequency).
14+
- Materialize Cloud can remove the promsql exporter.
15+
16+
## Out of Scope
17+
18+
- Generic HTTP endpoint creation for formats other than Prometheus.
19+
20+
While the proposed solution could easily be extended for other API types, that is not required for this to work for prometheus.
21+
22+
## Solution Proposal
23+
24+
Allow users to create HTTP endpoints in SQL with custom prometheus metrics.
25+
26+
```sql
27+
CREATE API mydatabase.myschema.myprometheus FORMAT PROMETHEUS ON CLUSTER "mycluster" ON LISTENER "external";
28+
```
29+
This will create an HTTP endpoint at `/metrics/custom/mydatabase/myschema/myprometheus` on the "external" HTTP listener (as named in the listeners configmap), and a (currently empty) table with the following schema:
30+
```
31+
metric_name TEXT,
32+
metric_type TEXT,
33+
help TEXT,
34+
database TEXT,
35+
schema TEXT,
36+
view TEXT,
37+
value_column_name TEXT
38+
```
39+
40+
The `metric_name`, `metric_type`, and `help` fields describe the prometheus metric itself.
41+
42+
The `database`, `schema`, and `view` fields are a reference to a view containing the metric data. The `value_column_name` is the name of a column in that view which contains the value of the metric. All other columns in the view will be used as labels.
43+
44+
An example metric view:
45+
```sql
46+
CREATE VIEW converted_leads
47+
AS
48+
(SELECT Count(*),
49+
converted
50+
FROM (SELECT id,
51+
CASE
52+
WHEN converted_at IS NULL THEN 'FALSE'
53+
ELSE 'TRUE'
54+
END AS converted
55+
FROM leads)
56+
GROUP BY converted);
57+
```
58+
59+
This might look like:
60+
| count | converted |
61+
|-------|-----------|
62+
|22|TRUE|
63+
|67|FALSE|
64+
65+
The user can then add this metric to their registry:
66+
```sql
67+
INSERT INTO mydatabase.myschema.myprometheus
68+
VALUES ('leads',
69+
'gauge',
70+
'Count of leads and whether they have been converted',
71+
'mydatabase',
72+
'myschema',
73+
'converted_leads',
74+
'count')
75+
```
76+
77+
## Minimal Viable Prototype
78+
79+
- [Hackathon presentation from May 2025](https://docs.google.com/presentation/d/1ek0tOlECHfpoBp_-vtcDWhN4YHpaWBfRuQyENGFbWLw/edit?slide=id.g35c518b4039_14_3503#slide=id.g35c518b4039_14_3503)
80+
- [Hackathon code from May 2025](https://github.com/MaterializeInc/materialize/compare/main...alex-hunt-materialize:materialize:external_api)
81+
- [Hackathon brainstorming from May 2025](https://www.notion.so/materialize/Hackathon-Alex-Justin-1f913f48d37b805e88b0e25a8ad1a763)
82+
83+
While not the exact same interface, it captures the idea proposed here.
84+
85+
## Alternatives
86+
87+
External SQL exporters.
88+
89+
We currently use one of our own in Materialize Cloud, which we wrote after we hit numerous problems with third-party ones. We currently still recommend third-party solutions to our customers, which is not ideal.
90+
91+
## Open questions
92+
93+
- Exact syntax and SQL object types. We might want to have dedicated SQL syntax for creating metrics, or have some dedicated reference to the views rather than text fields, for example.
94+
- How to specify which listener a metrics endpoint is on. Users don't define the listeners configmap, so referencing the names we define there seems a bit weird.

0 commit comments

Comments
 (0)