Follow-up from #5920 (Improve Feature Server Observability).
Problem
sdk/python/feast/metrics.py currently defines all Feature Server metrics directly with prometheus_client (Counter, Gauge, Histogram), including custom multiprocess-mode handling for Gunicorn workers. This issue asks for metrics to use native OpenTelemetry APIs (opentelemetry-api / opentelemetry-sdk) so they work with any OTEL-compatible collector/exporter (Prometheus, OTEL Collector, Grafana, Datadog, etc.), not just a Prometheus-specific scrape endpoint.
Proposed solution
- Refactor sdk/python/feast/metrics.py to define metrics via the OTel Metrics API (Counter, Histogram, UpDownCounter/Gauge equivalents from opentelemetry.metrics).
- Preserve Prometheus scrape compatibility via the OTLP → Prometheus exporter path (or the OpenTelemetry Prometheus exporter) so existing dashboards/alerts keep working.
- Preserve current Gunicorn multiprocess aggregation behavior (this is the trickiest part — OTel's SDK doesn't have a drop-in equivalent to prometheus_client's multiprocess mode, so this needs explicit design).
- Keep the existing metric names and label sets unchanged where possible to avoid breaking existing consumers; note any unavoidable breaking changes in the PR description.
- All existing tracking helpers (track_request_latency, track_online_features_entities, track_push, track_materialization, etc.) should keep the same call signatures.
- Add additional test cases
cc: @jyejare @ntkathole
Reactions are currently unavailable
Follow-up from #5920 (Improve Feature Server Observability).
Problem
sdk/python/feast/metrics.py currently defines all Feature Server metrics directly with prometheus_client (Counter, Gauge, Histogram), including custom multiprocess-mode handling for Gunicorn workers. This issue asks for metrics to use native OpenTelemetry APIs (opentelemetry-api / opentelemetry-sdk) so they work with any OTEL-compatible collector/exporter (Prometheus, OTEL Collector, Grafana, Datadog, etc.), not just a Prometheus-specific scrape endpoint.
Proposed solution
cc: @jyejare @ntkathole