Generate Prometheus Text Exposition Format in Python
Mock a Prometheus metrics endpoint by formatting metrics into the text exposition format with HELP, TYPE, and sample lines.
Python code
35 linesimport time
from random import randint
# Mock a Prometheus metrics endpoint output
metrics = {
"http_requests_total": {
"help": "Total number of HTTP requests",
"type": "counter",
"samples": [
{"labels": {"method": "get", "code": "200"}, "value": randint(1000, 9999)},
{"labels": {"method": "post", "code": "201"}, "value": randint(100, 999)},
],
},
"process_cpu_seconds_total": {
"help": "Total user and system CPU time spent in seconds",
"type": "counter",
"samples": [{"labels": {}, "value": round(time.process_time(), 3)}],
}
}
def format_exposition(metrics):
lines = []
for metric_name, data in metrics.items():
lines.append(f"# HELP {metric_name} {data['help']}")
lines.append(f"# TYPE {metric_name} {data['type']}")
for sample in data["samples"]:
if sample["labels"]:
labels = ",".join(f'{k}="{v}"' for k, v in sample["labels"].items())
lines.append(f'{metric_name}{{{labels}}} {sample["value"]}')
else:
lines.append(f'{metric_name} {sample["value"]}')
return "\n".join(lines)
if __name__ == "__main__":
print(format_exposition(metrics))
Output
# HELP http_requests_total Total number of HTTP requests
# TYPE http_requests_total counter
http_requests_total{method="get",code="200"} 4387
http_requests_total{method="post",code="201"} 532
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 0.123
How it works
The function iterates over each metric, emitting a HELP and TYPE line followed by sample lines. Labels are formatted as key=value pairs and enclosed in braces, with no spaces after commas per the exposition format spec. The output is joined with newlines, ready to be served by an HTTP endpoint. This pattern matches what Prometheus scrapers expect, enabling local testing of dashboards and alerts.
Common mistakes
- Forgetting to escape double quotes in label values
- Omitting the HELP or TYPE lines for each metric
- Adding spaces after commas in label lists (Prometheus expects no spaces)
- Not sorting label names for consistent output
Variations
- Use the prometheus_client library to generate exposition format directly
- Build the output incrementally with a list and join for large metric sets
Real-world use cases
- Mocking a service's /metrics endpoint in integration tests without spinning a real Prometheus.
- Generating sample metrics to validate alert rules and dashboard queries offline.
- Serving custom application metrics in the Prometheus format from a lightweight HTTP server.
Sponsored
More from Observability & SRE
- Adding a Correlation ID to Log Context in Python medium
- Calculate Error Rate from Log Stream in Python easy
- Check if a Timestamp Falls in a Daily Maintenance Window in Python easy
- Export Metrics with OTLP Mock in Python medium
- Generate Mock CPU and Memory Metrics in Python easy
- Generate Synthetic CPU Utilization Metrics in Python easy
Keep learning
Related tutorials and quizzes for this topic.