Skip to content

feat(ui): add session id filter to request logs - #32647

Merged
4 commits merged into
litellm_internal_stagingfrom
litellm_ui_session_id_filter
Jul 9, 2026
Merged

feat(ui): add session id filter to request logs#32647
4 commits merged into
litellm_internal_stagingfrom
litellm_ui_session_id_filter

Conversation

@tin-berri

@tin-berri tin-berri commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Note

Copy of #32568 by @thibault-linktree, pushed to a litellm_-prefixed branch so the full CircleCI suite (which doesn't run on fork PRs) executes. Commit authorship is preserved — all commits remain authored by the original author. Full credit to @thibault-linktree.

Relevant issues

Fixes #32585
Original PR: #32568

Pre-Submission checklist

  • I have added meaningful tests
  • My PR passes all CI/CD checks (e.g., lint, format, unit tests)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review

Type

🆕 New Feature

Changes

The Requests logs tab lets you filter by request id but not by session id, so tracking a full conversation means clicking through rows manually. This adds a Session ID filter end to end.

On the backend, /spend/logs/v2 and /spend/logs/ui gain a session_id query parameter that does a partial (substring) match on the session_id column of LiteLLM_SpendLogs (already indexed), following the same pattern as the existing request_id filter. The pattern value has \, %, and _ escaped before being wrapped in %…%, so pasting a session-id prefix matches every request in that conversation.

On the dashboard, the Logs filter panel gains a Session ID text input wired through FILTER_KEYS, the debounced text filter list, and uiSpendLogsCall, which forwards it as the session_id query param. schema.d.ts is regenerated for the new parameter.

Tests: a new endpoint test asserts that filtering by session id (full id and substring prefixes) returns only that session's rows (the shared mock prisma helper now also supports the session-count enrichment queries, so endpoint tests can use rows that carry a session_id), and the frontend filter mapping test table gains the Session ID → session_id case.

Screenshots / Proof of Fix

The following live-proxy reproduction was captured by the original author (@thibault-linktree) at 9a4652ebdc against a live proxy (python litellm/proxy/proxy_cli.py --config litellm/proxy/dev_config.yaml --detailed_debug --use_v2_migration_resolver on localhost:4000 with a local Postgres), hitting the real OpenAI API with real spend.

Three real chat completions across two sessions, using the x-litellm-session-id header:

chatcmpl-DzYBwiyvPqgfkGKDCLWkaLuRCGfiZ -> First call.
chatcmpl-DzYBxzJOqKPt9xORX3c1EqsDMxTfm -> Second call.
chatcmpl-DzYByXcuTk8q7pj89gjgLYt7DvcQd -> Other session

Then the logs endpoint with the new session_id filter:

== filter session-filter-demo-1 ==
total: 2
chatcmpl-DzYBxzJOqKPt9xORX3c1EqsDMxTfm session-filter-demo-1
chatcmpl-DzYBwiyvPqgfkGKDCLWkaLuRCGfiZ session-filter-demo-1
== filter session-filter-demo-2 ==
total: 1
chatcmpl-DzYByXcuTk8q7pj89gjgLYt7DvcQd session-filter-demo-2
== no session filter ==
total: 3
image

Note

Low Risk
Additive filter on existing spend-log list endpoints and UI; no auth or spend-calculation changes, with LIKE escaping for wildcard safety.

Overview
Adds Session ID filtering for the Requests logs flow so you can narrow paginated spend logs to a conversation instead of hunting by individual request IDs.

Backend: /spend/logs/ui and /spend/logs/v2 accept a new session_id query parameter. When set, the raw SQL path applies session_id LIKE %…% with \, %, and _ escaped in the user input (substring match, not exact equality like request_id).

Dashboard: The logs filter panel gets a debounced Session ID text field, wired through FILTER_KEYS, uiSpendLogsCall, and regenerated OpenAPI types in schema.d.ts.

Tests: Backend coverage for full/partial session filters on /spend/logs/ui, plus mock Prisma helpers for group_by and MCP enrichment queries; frontend filter-param mapping includes Session ID → session_id.

Reviewed by Cursor Bugbot for commit 8a44fdd. Bugbot is set up for automated code reviews on this repo. Configure here.

@tin-berri

Copy link
Copy Markdown
Contributor Author

@greptileai

@greptile-apps

greptile-apps Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a Session ID filter to the request logs UI, letting users narrow the logs table to a single conversation without clicking through rows manually. The feature is implemented end-to-end: a new session_id query parameter on the shared /spend/logs/v2 + /spend/logs/ui handler, a debounced text-input in the dashboard filter panel, and a regenerated TypeScript schema.

  • Backend: session_id is injected as a parameterized LIKE $p condition (with \\, %, and _ escaped) directly into the raw-SQL path, after the access-control conditions — so it is always ANDed with the existing user/team scope, not bypassing it.
  • Frontend: SESSION_ID is added to FILTER_KEYS, TEXT_FILTER_KEYS (debounced), defaultFilters, and the uiSpendLogsCall params object; the generic query-param loop in networking.tsx forwards it without any other changes.
  • Tests: A parametrized backend test covers full-id, prefix, common-substring, and no-match cases; the mock prisma helper gains group_by and an MCP-query short-circuit so session-carrying rows work in all test paths; the frontend filter-mapping test table gains the Session ID row.

Confidence Score: 5/5

Safe to merge — additive feature with no changes to existing filters or auth logic.

The change is purely additive: a new optional query parameter that is wired through parameterized SQL (no interpolation), LIKE metacharacters are properly escaped, and the condition is always ANDed with the existing access-control WHERE clauses. The backend and frontend are both fully exercised by new tests. No existing behavior is altered.

No files require special attention.

Important Files Changed

Filename Overview
litellm/proxy/spend_tracking/spend_management_endpoints.py Adds session_id LIKE filter to the shared /spend/logs/v2 + /spend/logs/ui handler; correctly parameterized and escapes LIKE metacharacters before wrapping in %…%
tests/test_litellm/proxy/spend_tracking/test_spend_management_endpoints.py Adds parametrized test covering full-id, prefix, common-substring, and no-match cases; extends mock prisma with group_by and an early-return for mcp_tool_call_count queries so session-carrying rows work in all test paths
ui/litellm-dashboard/src/components/view_logs/log_filter_logic.tsx Adds SESSION_ID to FILTER_KEYS, TEXT_FILTER_KEYS (debounced), defaultFilters, and the uiSpendLogsCall params mapping — fully wired end-to-end
ui/litellm-dashboard/src/components/view_logs/filter_options.ts Adds Session ID as a non-searchable filter option, consistent with the existing Key Hash and Request ID entries
ui/litellm-dashboard/src/components/networking.tsx Extends UiSpendLogsParams with session_id?: string; picked up automatically by the existing generic query-param loop — no other changes needed
ui/litellm-dashboard/src/lib/http/schema.d.ts Auto-generated schema updated for both /spend/logs/v2 and /spend/logs/ui to include the new session_id query parameter
ui/litellm-dashboard/src/components/view_logs/log_filter_logic.test.tsx Adds the Session ID → session_id case to the frontend filter-mapping table test
ui/litellm-dashboard/eslint-metrics.json ESLint inline-object count bumped by 7 to account for the new filter option objects added in this PR

Reviews (3): Last reviewed commit: "chore(ui): refresh eslint metrics for re..." | Re-trigger Greptile

@greptile-apps

greptile-apps Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds an end-to-end session ID filter to the request logs view. Users can now type a session ID (or a prefix/substring) into the Logs filter panel and the /spend/logs/ui and /spend/logs/v2 endpoints will return only matching rows via a parameterized LIKE %…% query.

  • Backend (spend_management_endpoints.py): a session_id query parameter is added to ui_view_spend_logs; LIKE metacharacters (\, %, _) are escaped in the correct order before the parameterized $N placeholder is appended to sql_conditions, consistent with the existing key_alias and error_message partial-match filters.
  • Frontend (log_filter_logic.tsx, filter_options.ts, networking.tsx): SESSION_ID is wired through FILTER_KEYS, TEXT_FILTER_KEYS, defaultFilters, and UiSpendLogsParams in exact parallel with the existing REQUEST_ID path.
  • Tests: a parametrized backend test covers full-match, prefix, and non-matching queries; the shared mock prisma helper gains a group_by stub and an early-return for the MCP enrichment sub-query that was unreachable before session-id data appeared in test fixtures.

Confidence Score: 5/5

Safe to merge — the change is additive (new optional query parameter), all filtering goes through parameterized SQL, and authorization is respected.

The session_id filter follows the exact same patterns already used for key_alias and error_message (LIKE with proper metachar escaping, appended to sql_conditions after auth). No existing behaviour is changed, the new parameter is optional, and the test additions cover full-match, prefix, and no-match cases without weakening any prior assertions.

No files require special attention. The shared mock helper in the test file was extended, but the additions are straightforward stubs for code paths that were previously unreachable in tests.

Important Files Changed

Filename Overview
litellm/proxy/spend_tracking/spend_management_endpoints.py Adds session_id query parameter to ui_view_spend_logs, applying a LIKE %…% condition directly to sql_conditions after the authorization phase — consistent with existing partial-match filters (key_alias, error_message). LIKE metacharacters (\, %, _) are escaped in the correct order.
tests/test_litellm/proxy/spend_tracking/test_spend_management_endpoints.py Adds parametrized session-id filter test and extends the shared mock prisma helper with a group_by method and an early-return for the MCP enrichment query_raw. Both mock additions are legitimate: existing tests had no session-id data so group_by was never reached; the mcp_tool_call_count short-circuit avoids a query-shape mismatch without hiding any prior regression.
ui/litellm-dashboard/src/components/networking.tsx Adds session_id?: string to UiSpendLogsParams; the generic Object.entries loop that appends params already forwards it correctly.
ui/litellm-dashboard/src/components/view_logs/filter_options.ts Registers the new Session ID filter option with isSearchable: false, consistent with similar text-input filters (Key Hash, Request ID).
ui/litellm-dashboard/src/components/view_logs/log_filter_logic.tsx Adds SESSION_ID to FILTER_KEYS, TEXT_FILTER_KEYS, defaultFilters, and the uiSpendLogsCall params object — all exactly parallel to the existing REQUEST_ID additions.
ui/litellm-dashboard/src/components/view_logs/log_filter_logic.test.tsx Adds a { filterKey: 'Session ID', paramName: 'session_id', value: 'sess-42' } row to the filter-mapping table test, completing the round-trip coverage.
ui/litellm-dashboard/src/lib/http/schema.d.ts Regenerated OpenAPI schema adds `session_id?: string

Reviews (2): Last reviewed commit: "chore(ui): refresh eslint metrics for re..." | Re-trigger Greptile

@tin-berri tin-berri closed this Jul 9, 2026
@tin-berri tin-berri reopened this Jul 9, 2026
@tin-berri

Copy link
Copy Markdown
Contributor Author

bugbot run

@tin-berri tin-berri closed this pull request by merging all changes into litellm_internal_staging in 131aa05 Jul 9, 2026
@tin-berri
tin-berri deleted the litellm_ui_session_id_filter branch July 9, 2026 17:41

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8a44fdd. Configure here.

if session_id is not None and isinstance(session_id, str):
like_escaped_session_id = session_id.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_")
sql_conditions.append(f"session_id LIKE ${p}")
sql_params.append(f"%{like_escaped_session_id}%")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LIKE escape clause missing

Medium Severity

The session_id filter escapes \, %, and _ in the search text but uses session_id LIKE $p without an ESCAPE clause. In PostgreSQL, % and _ stay wildcard metacharacters in that form, so filters containing those characters (or a lone %) can return far more rows than a substring match should.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 8a44fdd. Configure here.

@codspeed-hq

codspeed-hq Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing litellm_ui_session_id_filter (8a44fdd) with litellm_internal_staging (60729f7)1

Open in CodSpeed

Footnotes

  1. No successful run was found on litellm_internal_staging (b340a26) during the generation of this report, so 60729f7 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Filter request logs by session ID in the Admin UI

2 participants