You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
refactor(proxy): inject tracing receiver and access context - #44035
Create tracing inside the FastAPI application lifespan
Inject lifespan state into tracing and Lens routes
Flush queued spend logs and stop the logging task
Preserve validation and authorization error ordering
Intentional product change: startup waits for tracing initialization. If initialization fails, the proxy starts with tracing disabled and trace routes return the existing 501 response
Relevant issues
Prerequisite for #43975, which is stacked on this branch. Merge this PR first, then rebase #43975 and retarget it to main
Implementation
The tracing context manager yields its receiver. The proxy assembles ProxyLifespanState and yields it to Starlette before serving requests. The state schema lives with the existing proxy types. Tracing routes retrieve the receiver from request state. Lens gets the same application's storage through a FastAPI dependency. The shared ClickHouse bridge is named ClickHouseStorage; trace-specific queries live in TraceStore. The global receiver and no-argument accessor are removed
litellm-storage-clickhouse now exports generic Storage and Connection types plus bounded read and insert transport. litellm-traces keeps OTLP decoding, trace schema, row encoding, and named query selection. The PyO3 trace binding composes the shared Storage while preserving its Python API
The access dependency derives read scope and write tenant in one role-policy match. The context enforces those permissions inside each handler, after parameter validation. Shutdown removes its spend callback, signals the periodic worker to stop, awaits its current insert, and drains queued rows. The worker wakes immediately when idle and exits without cancellation during normal shutdown. This follows FastAPI lifespan and Starlette lifespan state
The existing SDK callback registry remains process-wide. This PR scopes the trace receiver and tracing/Lens reads to the application; it does not make the rest of the proxy's global configuration independent between applications
Validation
At 4921a1c81b, all eight batch logger tests pass and make check passes. New regression cases verify shutdown recovery after a transient failure and accounting after retry exhaustion across multiple batches. Removing the drain loop makes both cases fail
Review triage confirmed the stacked branch already uses the renamed storage classes. Multiple independently configured proxies inside one process remain unsupported because SDK configuration and callbacks are process-global. The transport's existing production callers enforce the encoded byte limit before sending
Live curl checks at 4921a1c81b against PostgreSQL and ClickHouse returned 200 for protobuf export and span detail, an empty list for another team, 401 without authentication, and 422 for invalid time input
Greptile reviewed 4921a1c81b at 5/5. Hosted checks remain pending. No Bugbot review is available on this tip Earlier coverage reported 90.56% patch coverage with uncovered lifespan and Lens branches; this is not a completed coverage gate
Pre-Submission checklist
Meaningful tests cover injection, tenant identity, and error ordering
Focused tests and local checks pass
All required CI checks pass
Scope is limited to tracing ownership and dependency injection
Greptile confidence is at least 4/5
Type
Refactoring
Caveats
Medium
Independently configured proxies sharing one process remain unsupported
Low
Full current merge-base live comparison has not been refreshed
Comparing litellm_tracing_dependencies (4921a1c) with main (ca05eca)1
Footnotes
No successful run was found on main (0da00d4) during the generation of this report, so ca05eca was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩
[High risk] Extracts ClickHouse storage into a shared crate and refactors trace code to use it.
The PR appears safe to merge based on the reviewed changes.
Summary
The PR moves tracing ownership into the proxy lifespan, injects application-scoped tracing access into trace and Lens routes, separates shared ClickHouse transport from trace-specific code, and drains queued spend rows on shutdown.
@greptileai Please review 4921a1c. Shutdown retries are fixed, and other findings have evidence explaining unsupported scenarios, existing bounds, and updated imports
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TLDR
Problem this solves:
How it solves it:
Intentional product change: startup waits for tracing initialization. If initialization fails, the proxy starts with tracing disabled and trace routes return the existing 501 response
Relevant issues
Prerequisite for #43975, which is stacked on this branch. Merge this PR first, then rebase #43975 and retarget it to
mainImplementation
The tracing context manager yields its receiver. The proxy assembles
ProxyLifespanStateand yields it to Starlette before serving requests. The state schema lives with the existing proxy types. Tracing routes retrieve the receiver from request state. Lens gets the same application's storage through a FastAPI dependency. The shared ClickHouse bridge is namedClickHouseStorage; trace-specific queries live inTraceStore. The global receiver and no-argument accessor are removedlitellm-storage-clickhousenow exports genericStorageandConnectiontypes plus bounded read and insert transport.litellm-traceskeeps OTLP decoding, trace schema, row encoding, and named query selection. The PyO3 trace binding composes the sharedStoragewhile preserving its Python APIThe access dependency derives read scope and write tenant in one role-policy match. The context enforces those permissions inside each handler, after parameter validation. Shutdown removes its spend callback, signals the periodic worker to stop, awaits its current insert, and drains queued rows. The worker wakes immediately when idle and exits without cancellation during normal shutdown. This follows FastAPI lifespan and Starlette lifespan state
The existing SDK callback registry remains process-wide. This PR scopes the trace receiver and tracing/Lens reads to the application; it does not make the rest of the proxy's global configuration independent between applications
Validation
At
4921a1c81b, all eight batch logger tests pass andmake checkpasses. New regression cases verify shutdown recovery after a transient failure and accounting after retry exhaustion across multiple batches. Removing the drain loop makes both cases failReview triage confirmed the stacked branch already uses the renamed storage classes. Multiple independently configured proxies inside one process remain unsupported because SDK configuration and callbacks are process-global. The transport's existing production callers enforce the encoded byte limit before sending
Live curl checks at
4921a1c81bagainst PostgreSQL and ClickHouse returned 200 for protobuf export and span detail, an empty list for another team, 401 without authentication, and 422 for invalid time inputGreptile reviewed
4921a1c81bat 5/5. Hosted checks remain pending. No Bugbot review is available on this tip Earlier coverage reported 90.56% patch coverage with uncovered lifespan and Lens branches; this is not a completed coverage gatePre-Submission checklist
Type
Refactoring
Caveats
Medium
Low
Full current merge-base live comparison has not been refreshed
Existing team-key detail-route rejection remains unchanged
Dependency scan flags existing
pypdfvulnerabilities in unchangeduv.lockHosted checks and final coverage remain pending
Bugbot review is unavailable on this tip
Final Attestation