Skip to main content
In this lesson/article we’ll build a small dummy application and walk through how to add Prometheus instrumentation. We’ll use Flask (a lightweight Python web framework) to create a few endpoints and then add metrics using the prometheus_client library.

Minimal Flask app

Here is a minimal Flask app that exposes a single GET endpoint at "/cars":
Focus on the decorator @app.get("/cars"): any GET request to "/cars" will execute the get_cars function. The app is started on port 5001.

Install the Prometheus client

Install the Python client library:

Add a Counter metric

Import and create a Prometheus Counter to track total requests:

Increment the counter in a handler

Increment the counter inside the request handler so it increases on every request:

Expose metrics with a separate HTTP server

The simplest way to expose metrics is to use start_http_server from the Prometheus client. This starts a separate HTTP server that serves all registered metrics (including the default Python metrics):
When run this way:
  • Flask App: port 5001
  • Prometheus metrics endpoint: port 8000
You can fetch the metrics with curl:

Expose metrics via Flask (same port)

If you prefer to expose metrics on the same port as your Flask app (e.g., at http://localhost:5001/metrics), use the WSGI helper make_wsgi_app and DispatcherMiddleware from werkzeug:
This makes the Prometheus metrics available at http://localhost:5001/metrics. Use whichever approach fits your deployment model: a separate metrics server (good for simple setups) or WSGI middleware (keeps everything on one port).

Multi-route application and counting across all endpoints

Let’s expand the app with additional endpoints and show two ways to ensure http_requests_total counts requests across your entire application.
  1. Manual increments in each handler:
  1. Increment once for every incoming request using a global hook (recommended to avoid repeating increments). If you expose metrics at "/metrics" via the same Flask app (for example, if /metrics is handled by Flask), make sure you do not count requests to /metrics itself. If you mount the Prometheus WSGI app via DispatcherMiddleware, requests to /metrics are handled by the metrics WSGI app and won’t trigger Flask before_request hooks:

Callouts

If you use start_http_server, the metrics endpoint is a separate HTTP server (different port) and will not be handled by Flask middleware or Flask hooks like before_request. If you want metrics to be part of the same Flask process and port, use make_wsgi_app with DispatcherMiddleware.
If you expose metrics at "/metrics" on the same Flask app, ensure you do not inadvertently count /metrics requests in your application metrics unless that is intentional.

Summary

  • Create and register Prometheus metrics (e.g., Counter, Gauge, Histogram) using prometheus_client.
  • Increment metrics where appropriate (inside handlers, or globally via before_request).
  • Expose metrics either with start_http_server (separate port) or with make_wsgi_app + DispatcherMiddleware (same port at "/metrics").
  • Avoid double-counting metrics (for example, counting scrapes of the /metrics endpoint itself).

Watch Video