- Counters only increase; they are not suitable for values that go up and down.
- Up-down counters are for values your code explicitly increments/decrements (e.g., concurrent requests).
- Memory usage fluctuates and is independent of prior values, so a gauge is the correct metric type.
- An observable (async) gauge lets the SDK poll the current memory values periodically, so you do not need to manually update the metric inside your application code.
Observable gauges are polled by the metrics SDK (via the metric reader). You must provide a callback function that returns the current observations; the SDK will call that callback periodically according to the metric reader’s export interval.
Example: Flask app with an observable gauge (polled memory)
This self-contained example shows:- Meter/provider setup with a ConsoleMetricExporter and 5s periodic exporting.
- Synchronous metrics: request counters and an up-down counter for concurrent requests.
- An observable gauge that reports RSS and VMS memory values for the running process.
Example console-exported metric snapshot
The ConsoleMetricExporter prints resource and scope metrics as JSON-like structures. With the periodic reader configured to 5000 ms, the observable gauge will be polled every 5 seconds and you will see observations forrss and vms within the exported metrics.
Quick reference: metric types and when to use them
| Metric Type | Use Case | When to use |
|---|---|---|
| Counter | Monotonic counts of events | http_requests_total (increment on each request) |
| Up-down counter | Values you explicitly increase/decrease in code | concurrent_requests (add 1 / add -1) |
| Observable gauge | Polled values that can increase/decrease independently | application_memory_usage (RSS/VMS polled by psutil) |
Notes and best practices
- Use
rss(resident set size) to monitor actual memory resident in RAM. Usevmsto inspect the total virtual address space requested by the process. - The callback receives an
optionsparameter (not used in this example). Always return an iterable (e.g., a list) of Observation objects or(value, attributes)tuples. - The periodic exporter polls your observable callbacks at the configured interval (5 seconds in this example).
- For production, run behind a proper WSGI server (e.g., Gunicorn, uWSGI) and replace the ConsoleMetricExporter with a production-ready exporter such as OTLP.
Do not use Flask’s development server in production. Configure a production WSGI server and a proper exporter (e.g., OTLP) for reliable metric delivery and performance.
Links and references
- OpenTelemetry Python metrics: https://opentelemetry.io/docs/instrumentation/python/
- OpenTelemetry metrics SDK: https://opentelemetry.io/docs/reference/specification/metrics/
- psutil (process utilities for Python): https://pypi.org/project/psutil/
- Flask documentation: https://flask.palletsprojects.com/
- OTLP exporter information: https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/protocol/otlp