Starlette Prometheus Integration
Starlette-prometheus is a Python library that provides seamless Prometheus integration for Starlette applications. It includes a middleware to automatically expose key metrics such as total requests, request duration, and concurrent requests. The library is currently at version 0.10.0, released on September 3, 2024, with a development cadence that includes periodic updates and feature enhancements.
Common errors
-
Metrics endpoint is empty or not showing expected data.
cause The middleware or the metrics route handler is not correctly configured, or the application hasn't processed any requests yet.fixEnsure `app.add_middleware(PrometheusMiddleware)` is called and `app.add_route('/metrics', metrics)` is set up. Make sure to send requests to your application's endpoints (e.g., `/` or `/items/123`) before checking `/metrics`. -
UnboundLocalError: local variable 'status_code' referenced before assignment
cause This is a known bug in `starlette-prometheus` versions prior to `0.9.0`.fixUpgrade your `starlette-prometheus` package to version `0.9.0` or newer: `pip install --upgrade starlette-prometheus`. -
Prometheus shows too many unique `path` labels, leading to high cardinality warnings.
cause By default, `starlette-prometheus` tracks every unique request path, including 404s or dynamic paths without grouping.fixConfigure the middleware with `filter_unhandled_paths=True` to prevent metrics from being generated for 404 routes. If using dynamic paths, consider options provided by similar libraries (like `starlette_exporter`'s `group_paths`) if more fine-grained control is needed, but for `starlette-prometheus`, `filter_unhandled_paths` is the primary control.
Warnings
- gotcha Failing to filter unhandled paths (e.g., 404s) can lead to unbounded memory use and high cardinality metrics, potentially overwhelming your Prometheus server.
- breaking When deploying with multiple worker processes (e.g., Gunicorn or Uvicorn with `--workers`), Prometheus metrics will not aggregate correctly by default, leading to incomplete or incorrect data.
- deprecated Older versions (pre-0.9.0) of `starlette-prometheus` contained a bug (`UnboundLocalError`) when handling certain requests.
Install
-
pip install starlette-prometheus uvicorn
Imports
- PrometheusMiddleware
from starlette_prometheus import PrometheusMiddleware
- metrics
from starlette_prometheus.middleware import metrics
from starlette_prometheus import metrics
- Starlette
from starlette import Starlette
from starlette.applications import Starlette
Quickstart
import uvicorn
from starlette.applications import Starlette
from starlette.responses import PlainTextResponse
from starlette_prometheus import PrometheusMiddleware, metrics
app = Starlette()
app.add_middleware(PrometheusMiddleware, app_name='my_starlette_app', prefix='starlette_app_prefix')
app.add_route('/metrics', metrics)
@app.route('/')
async def homepage(request):
return PlainTextResponse('Hello, world!')
@app.route('/items/{item_id}')
async def read_item(request):
item_id = request.path_params['item_id']
return PlainTextResponse(f'Item: {item_id}')
if __name__ == '__main__':
# Run with: uvicorn quickstart:app --port 8000
uvicorn.run(app, host='0.0.0.0', port=8000)