Skip to main content
In this lesson we’ll instrument a minimal Flask application with OpenTelemetry metrics. The goal is to introduce metrics support incrementally:
  • add and configure an OpenTelemetry MeterProvider,
  • register a metrics reader and exporter,
  • create metric instruments (counters, histograms, etc.),
  • record metrics from request handlers,
  • and validate exports locally (Console exporter) before moving to a production backend such as Prometheus.
Minimal Flask app This is the starting point — a minimal Flask API that exposes a single GET endpoint at /products:
We will extend this application to collect and export metrics using OpenTelemetry. Installation Install the OpenTelemetry API and SDK for Python:
You can verify the installed packages with:
(Exact versions will vary by environment.) Configure metrics Encapsulate the OpenTelemetry setup in a configure_meter() helper. The function:
  • creates a metric exporter (ConsoleMetricExporter for local testing),
  • creates a metrics reader (PeriodicExportingMetricReader) that periodically exports metrics,
  • builds a MeterProvider with the reader and a Resource,
  • sets it as the global meter provider,
  • and returns a Meter instance for creating instruments.
Example implementation (place this in main.py or in a separate module that you import):
Key components
ComponentPurposeExample / Notes
ConsoleMetricExporterSends metric data to stdout for quick local validationUseful in development; not for production
PeriodicExportingMetricReaderPeriodically collects and forwards metrics to an exporterPeriodicExportingMetricReader(exporter, export_interval_millis=5000)
MeterProviderCentral provider that manages meters and readersMeterProvider(metric_readers=[reader], resource=Resource.create({}))
ResourceDescribes the application/service (attributes like service.name)Resource.create({}) — replace with attributes as needed
Integrate with the Flask app Call configure_meter() at application startup, then create instruments from the returned meter. Record metrics inside request handlers. A compact main.py that includes the configuration and a counter instrument:
Tips and best practices
Use attributes (labels) on metric recordings to slice metrics by endpoint, HTTP method, status code, or other dimensions. For production, add meaningful Resource attributes such as service.name, service.version, and environment tags.
Running the app Start the application:
Typical Flask output:
While the app runs, the PeriodicExportingMetricReader will invoke the ConsoleMetricExporter at the configured interval (default 5 seconds). You should see exported metric lines printed to stdout when metrics have been recorded. Warnings
ConsoleMetricExporter and Flask’s built-in development server are intended for local development and testing only. For production, use a proper exporter (e.g., OTLP or Prometheus exporter) and a production WSGI server such as Gunicorn or uWSGI.
Next steps
  • Add more instruments: histograms for request latency, up-down counters for in-flight requests, or observable instruments.
  • Export to production backends:
    • Prometheus: use the Prometheus exporter/agent to scrape metrics.
    • OTLP: send metrics to an OpenTelemetry Collector and then route to your backend.
  • Enrich Resource.create({}) with metadata such as:
    • service.name, service.instance.id, service.version.
Links and references This guide gives you a minimal, reproducible path from a simple Flask app to basic OpenTelemetry metrics collection and local export. From here you can extend the instrumentation and switch exporters to match your observability stack.

Watch Video