Add OpenTelemetry instrumentation for LiteLLM#88
Add OpenTelemetry instrumentation for LiteLLM#88whoIam0987 wants to merge 2 commits intoalibaba:mainfrom
Conversation
c26059b to
d8affed
Compare
There was a problem hiding this comment.
Pull request overview
This pull request adds OpenTelemetry instrumentation for the LiteLLM library, which provides a unified interface to 100+ LLM providers. The instrumentation captures telemetry data for LLM operations including completions, embeddings, streaming, tool calls, and retry mechanisms.
Changes:
- Added new instrumentation package for LiteLLM with support for sync/async completion and embedding APIs
- Implemented streaming response wrappers with proper span lifecycle management
- Added comprehensive test suite covering various LiteLLM features including tool calls, retries, and error handling
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 19 comments.
Show a summary per file
| File | Description |
|---|---|
__init__.py |
Main instrumentor class that wraps LiteLLM functions and manages telemetry handlers |
_wrapper.py |
Completion wrappers for sync/async calls with streaming support |
_embedding_wrapper.py |
Embedding operation wrappers for sync/async calls |
_stream_wrapper.py |
Stream response wrappers handling chunk accumulation and finalization |
_utils.py |
Utility functions for message conversion, provider parsing, and invocation creation |
version.py, package.py |
Package metadata and dependency declarations |
pyproject.toml |
Package configuration with build system and dependencies |
README.rst |
Documentation for installation, configuration, and usage |
test_*.py |
Comprehensive test suite covering completions, embeddings, streaming, tools, retries, and errors |
test-requirements.txt |
Test dependency specifications |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| # Create invocation object |
There was a problem hiding this comment.
Duplicate comment. The comment "Create invocation object" appears twice consecutively on lines 63 and 65. Remove one of these duplicate lines.
| # Create invocation object |
|
|
||
| # Create invocation object |
There was a problem hiding this comment.
Duplicate comment. The comment "Create invocation object" appears twice consecutively on lines 164 and 166. Remove one of these duplicate lines.
| # Create invocation object |
|
|
||
| # For streaming, we need special handling |
There was a problem hiding this comment.
Duplicate comment. The comment "For streaming, we need special handling" appears twice consecutively on lines 85 and 87. Remove one of these duplicate lines.
| # For streaming, we need special handling |
| stream_wrapper = AsyncStreamWrapper( | ||
| stream=response, | ||
| span=invocation.span, # For TTFT tracking | ||
| callback=lambda span, | ||
| last_chunk, | ||
| error: self._handle_stream_end_with_handler( | ||
| invocation, last_chunk, error, stream_wrapper | ||
| ), | ||
| ) |
There was a problem hiding this comment.
Potential circular reference in lambda callback. The lambda function references stream_wrapper (line 366) before it's assigned (line 360). While Python closures can handle this due to lazy evaluation, this creates a circular reference that could potentially cause issues with garbage collection. Consider restructuring to avoid the circular reference, perhaps by creating the callback after the AsyncStreamWrapper is instantiated or using a different callback pattern.
| * ``ENABLE_LITELLM_INSTRUMENTOR``: Enable/disable instrumentation (default: true) | ||
| * ``ARMS_LITELLM_INSTRUMENTATION_ENABLED``: Alternative enable/disable flag (default: true) |
There was a problem hiding this comment.
The documentation claims that the ENABLE_LITELLM_INSTRUMENTOR environment variable can be used to enable/disable instrumentation, but this variable is never referenced in the actual code. Only ARMS_LITELLM_INSTRUMENTATION_ENABLED is actually implemented. Either implement support for this environment variable or remove it from the documentation to avoid confusion.
| * ``ENABLE_LITELLM_INSTRUMENTOR``: Enable/disable instrumentation (default: true) | |
| * ``ARMS_LITELLM_INSTRUMENTATION_ENABLED``: Alternative enable/disable flag (default: true) | |
| * ``ARMS_LITELLM_INSTRUMENTATION_ENABLED``: Enable/disable instrumentation (default: true) |
| suppress_token = context.attach( | ||
| context.set_value(SUPPRESS_LLM_SDK_KEY, True) | ||
| ) | ||
| except Exception: |
There was a problem hiding this comment.
'except' clause does nothing but pass and there is no explanatory comment.
| except Exception: | ||
| pass |
There was a problem hiding this comment.
'except' clause does nothing but pass and there is no explanatory comment.
| except Exception: | |
| pass | |
| except Exception as decode_error: | |
| # Ignore JSON parsing errors and fall back to the raw string, | |
| # but log at debug level for diagnosability. | |
| logger.debug( | |
| "Failed to JSON-decode tool call arguments %r: %s", | |
| arguments, | |
| decode_error, | |
| ) |
| except Exception: | ||
| pass |
There was a problem hiding this comment.
'except' clause does nothing but pass and there is no explanatory comment.
| except Exception: | |
| pass | |
| except Exception as handler_error: | |
| # Swallow exceptions from telemetry failure reporting, but log them for diagnostics. | |
| logger.debug( | |
| "Error while reporting LLM failure in _handle_stream_end_with_handler: %s", | |
| handler_error, | |
| ) |
| suppress_token = context.attach( | ||
| context.set_value(SUPPRESS_LLM_SDK_KEY, True) | ||
| ) | ||
| except Exception: |
There was a problem hiding this comment.
'except' clause does nothing but pass and there is no explanatory comment.
| context.set_value(SUPPRESS_LLM_SDK_KEY, True) | ||
| ) | ||
| except Exception: | ||
| pass |
There was a problem hiding this comment.
'except' clause does nothing but pass and there is no explanatory comment.
| pass | |
| # Failed to attach suppression context; proceed without suppression. | |
| logger.exception( | |
| "Failed to attach suppression context for LiteLLM instrumentation" | |
| ) |
Description
Instrument Litellm with genai util.
Fixes # (issue)
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
Does This PR Require a Core Repo Change?
Checklist:
See contributing.md for styleguide, changelog guidelines, and more.