feat(prometheus): add api_provider label to token, latency, request and cache metrics - #32043
Conversation
Greptile SummaryThis PR adds the
Confidence Score: 5/5Safe to merge — the change is additive (new label on existing metrics), the success path was already wired correctly, the failure path's new helper is narrowly scoped and never raises, and every affected metric family is covered by the new tests. All three changed files are coherent: the label lists, the runtime plumbing, and the tests agree on the same set of 14 metric families. The success path already carried api_provider in enum_values (line 1206 of prometheus.py), so no regression risk there. The new _extract_api_provider_from_request_data helper handles the failure path safely with priority-ordered fallbacks and well-scoped exception catching. The four new tests are all mock-only and cover label presence, factory value flow, and exception behavior. No pre-existing logic was altered; previously discussed concerns (time-series discontinuity, broad exception catch) have been addressed by the author. No files require special attention.
|
| Filename | Overview |
|---|---|
| litellm/types/integrations/prometheus.py | Adds API_PROVIDER to ten metric label lists (nine discrete lists plus the shared _cache_metric_labels); all five cache metrics that alias that shared list now carry the label, which is explicitly asserted in the new tests. |
| litellm/integrations/prometheus.py | Adds _extract_api_provider_from_request_data static helper and plumbs its result into UserAPIKeyLabelValues in async_post_call_failure_hook; success path already carried api_provider in enum_values from standard_logging_payload["custom_llm_provider"]. |
| tests/test_litellm/integrations/test_prometheus_labels.py | Four new unit tests added: label-list presence for all 14 affected metrics, label factory flow, helper function priority-chain logic, and exception-handling (BadRequestError vs unexpected errors). All mock-only, no network calls. |
Reviews (4): Last reviewed commit: "feat(prometheus): add api_provider label..." | Re-trigger Greptile
Greptile SummaryThis PR adds the
Confidence Score: 4/5Safe to merge; the label additions are additive and the new helper degrades gracefully to None on any error. The core logic is correct and well-tested. The two items that warrant a second look are: the bare litellm/types/integrations/prometheus.py — the _cache_metric_labels shared list change; litellm/integrations/prometheus.py — the exception handling in _extract_api_provider_from_request_data.
|
| Filename | Overview |
|---|---|
| litellm/integrations/prometheus.py | Adds _extract_api_provider_from_request_data static method and wires api_provider into async_post_call_failure_hook enum_values; success path already had api_provider from standard_logging_payload. |
| litellm/types/integrations/prometheus.py | Adds API_PROVIDER label to 9 metric label lists; the _cache_metric_labels shared list also propagates api_provider to litellm_cached_tokens_metric, litellm_provider_cache_read_input_tokens_metric, and litellm_provider_cache_creation_input_tokens_metric beyond what the PR description and tests enumerate. |
| tests/test_litellm/integrations/test_prometheus_labels.py | Adds three new unit tests covering label presence, value plumbing through the label factory, and failure-path provider inference; all use mocks or local lookups with no real network calls. |
Comments Outside Diff (1)
-
litellm/types/integrations/prometheus.py, line 685-703 (link)api_providerimplicitly added to three extra cache metrics via shared listAdding
API_PROVIDERto_cache_metric_labelspropagates to all five metrics that alias this list:litellm_cache_hits_metric,litellm_cache_misses_metric,litellm_cached_tokens_metric,litellm_provider_cache_read_input_tokens_metric, andlitellm_provider_cache_creation_input_tokens_metric. The PR description and the new tests only mention the first two. The three additional metrics silently gain the label without documentation or test coverage, which may surprise existing users whose TSDB already has those series recorded without the label dimension. If the intent is to addapi_providerto all five, the tests should assert it for all five and the PR description should note the broader scope.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Reviews (2): Last reviewed commit: "feat(prometheus): add api_provider label..." | Re-trigger Greptile
f270e52 to
59a2130
Compare
2f41286 to
9ee1dd5
Compare
|
Thanks for the PR. One thing I would like to address before merge: The tests cover labels/helpers, but not the real emit wiring; deleting the production |
…nd cache metrics The token (input/output/total), latency (llm_api, time_to_first_token, request_total, request_queue_time), proxy request (total/failed) and cache metrics were emitted from the same call sites as litellm_spend_metric and litellm_requests_metric, which already carry api_provider, yet these were missing it. That left no way to break tokens, latency, request counts or cache hits down by upstream provider even though the provider is already on the payload as custom_llm_provider. Add api_provider to each metric's label allow-list. The success path already populates enum_values.api_provider from standard_logging_payload, so those metrics emit it with no further plumbing. The cache label is added to the shared _cache_metric_labels list, so alongside litellm_cache_hits_metric and litellm_cache_misses_metric it also covers litellm_cached_tokens_metric and the provider prompt-cache read/creation token metrics; the label-presence test asserts all of them. For the client-side failure path, where a deployment may not have been resolved, derive it best-effort from litellm_params.custom_llm_provider, a partial standard_logging_object, or inference from the requested model name via litellm.get_llm_provider, falling back to empty rather than guessing. Resolves LIT-4178
9ee1dd5 to
ca48318
Compare
Good catch, thanks. You're right that the earlier tests only covered the label config and the helper, so deleting the real api_provider assignment would have slipped through. I've added two hook-level tests that run the actual loggers and inspect the collected metric samples: one drives async_log_success_event and asserts the emitted litellm_total_tokens_metric sample carries api_provider="openai" |
Relevant issues
LIT-4178
Linear ticket
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
@greptileaiand received a Confidence Score of at least 4/5 before requesting a maintainer reviewDelays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
Screenshots / Proof of Fix
Before


After


Type
🐛 Bug Fix
Changes
A subset of Prometheus metrics carried no api_provider label even though sibling metrics emitted from the same call sites (litellm_spend_metric, litellm_requests_metric) already did, so there was no way to break token usage, latency, request counts or cache hits down by upstream provider. This adds api_provider to the token metrics (litellm_input_tokens_metric, litellm_output_tokens_metric, litellm_total_tokens_metric), the latency metrics (litellm_llm_api_latency_metric, litellm_llm_api_time_to_first_token_metric, litellm_request_total_latency_metric, litellm_request_queue_time_seconds), the proxy request counters (litellm_proxy_total_requests_metric, litellm_proxy_failed_requests_metric) and the cache metrics.
The cache label is added to the shared _cache_metric_labels list, so the change covers all five metrics that use it: litellm_cache_hits_metric, litellm_cache_misses_metric, litellm_cached_tokens_metric, litellm_provider_cache_read_input_tokens_metric and litellm_provider_cache_creation_input_tokens_metric. The label-presence test asserts every one of them.
On the success path no new plumbing is needed; enum_values.api_provider is already populated from standard_logging_payload["custom_llm_provider"], so the value flows through as soon as the label is in the metric's list. For the client-side failure path, where a request can fail before a deployment resolves, the provider is derived best-effort from litellm_params.custom_llm_provider, then a partial standard_logging_object, then inference from the requested model name via litellm.get_llm_provider, falling back to empty rather than guessing.