Spend Logs UI regression: upstream provider failures are hidden because /spend/logs/ui returns metadata as JSON text

用户在 LiteLLM Proxy 中配置上游提供商(如 OpenAI、Anthropic 等)时,当上游返回失败状态码(如 403),LiteLLM 会记录失败元数据(如 status == "failure" 和 metadata.error_information.error_code ==

Spend Logs UI regression: upstream provider failures are hidden because /spend/logs/ui returns metadata as JSON text

Spend Logs UI regression: upstream provider failures are hidden because /spend/logs/ui returns metadata as JSON text

快速结论:该报错发生在 LiteLLM Spend Logs UI 中,上游提供商请求失败(如 403)的记录被错误显示为成功,且嵌套错误详情在请求日志行或抽屉组件中丢失。优先排查版本是否包含修复提交 adf7c97714f94eabdcca1ee5c561d5c5b7ee6f01,否则需在 prisma_client.db.query_raw 之后手动反序列化 metadata JSON 文本。

问题场景

用户在 LiteLLM Proxy 中配置上游提供商(如 OpenAI、Anthropic 等)时,当上游返回失败状态码(如 403),LiteLLM 会记录失败元数据(如 status == "failure"metadata.error_information.error_code == "403")。但在 Spend Logs UI 中,这些失败行被显示为成功,且错误详情不可见。问题仅影响 Spend Logs UI 展示层,不影响 OTEL span 数据。

报错原文

issue: upstream provider failures are hidden because /spend/logs/ui returns metadata as JSON text

actual behavior: failed upstream provider calls appear as successful in spend logs UI
expected: failure rows show status="failure" and metadata.error_information.error_code="403"

core observation: spend logs UI still treats log.metadata as an object; reads like:
- metadata.status
- metadata.error_information

root cause: metadata is now a string (JSON text) on this code path, reads fail silently

relevant code paths:
- backend raw sql at litellm/proxy/spend_tracking/spend_management_endpoints.py
- dashboard at:
  - ui/litellm-dashboard/src/components/view_logs/columns.tsx
  - ui/.../LogDetailsDrawer/LogDetailsDrawer.tsx
  - ui/.../LogDetailsDrawer/LogDetailContent.tsx

原因分析

可能原因:LiteLLM Proxy 在版本 v1.88.0-rc.1 及后续版本中,/spend/logs/ui 端点通过原始 SQL 查询数据库并返回 metadata 字段作为 JSON 文本(字符串),而非解析后的对象。Spend Logs UI 前端代码(columns.tsx、LogDetailsDrawer.tsx、LogDetailContent.tsx)仍以对象形式访问 metadata.statusmetadata.error_information,当 metadata 是字符串时这些读取静默失败,导致失败行看起来像成功行,且错误详情被隐藏。

注意:该修复在 #29682 中实现,但截至 v1.89.2 仍未包含。提交 adf7c97714f94eabdcca1ee5c561d5c5b7ee6f01 之后的版本才可能包含此修复。

环境排查

  • LiteLLM 版本:确认是否为 v1.88.0-rc.1v1.89.1v1.89.2 等受影响版本
  • 检查 litellm/proxy/spend_tracking/spend_management_endpoints.pyprisma_client.db.query_raw 之后是否有 metadata JSON 反序列化代码块
  • 确认上游提供商(如 OpenAI)是否返回 403 等失败状态码
  • 验证 OTEL span 中 standard_logging_object.error_information 是否正常显示错误详情

解决步骤

  1. 方案一(可优先尝试):更新 LiteLLM 到包含修复的版本(如 v1.90.0 或之后版本)。如果无法立即更新,需手动应用补丁。
  2. 方案二(手动修复):编辑 litellm/proxy/spend_tracking/spend_management_endpoints.py,在 data = await prisma_client.db.query_raw(sql_query, *sql_params) 之后(约第 2138 行),添加 metadata JSON 文本反序列化逻辑。将 data 中每条记录的 metadata 字段从 JSON 字符串解析为 dict,然后再传递给 _build_ui_spend_logs_response()
  3. 方案三:修改前端代码,在 columns.tsxLogDetailsDrawer.tsxLogDetailContent.tsx 中防御性地处理 metadata 字段:如果是字符串则先 JSON.parse(),再访问 statuserror_information
  4. 方案四:优先使用顶层 status 字段(如果已选取)替代依赖 metadata.status

验证方法

修复后,模拟上游提供商返回 403 错误,在 Spend Logs UI 中查看对应请求日志行:

  • 该行应显示为“失败”状态(红色或错误标志)
  • 点击该行打开抽屉(drawer)组件,应能正常显示 error_information.error_code == "403" 等错误详情
  • 检查 /spend/logs/ui 接口返回的 JSON 中,metadata 应是一个对象({})而非字符串
  • 确认 OTEL span 数据不受影响(之前已正常工作)

参考来源

BerriAI/litellm #29674

修复 PR #29682

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

celebrityanime
celebrityanime
文章: 8736

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注