Implementation:BerriAI Litellm Integration Handlers
| Knowledge Sources | Domains | Last Updated |
|---|---|---|
| [[1]] | Observability, Telemetry Export | 2026-02-15 |
Overview
Concrete tool for exporting LLM telemetry data to external monitoring platforms provided by provider-specific handler classes in the litellm/integrations/ directory.
Description
LiteLLM ships with handler implementations for major observability platforms. Each handler is a subclass of CustomLogger (or CustomBatchLogger) that overrides lifecycle hooks to transform the StandardLoggingPayload into the platform's native format and transmit it.
Key handlers include:
- OpenTelemetry (
OpenTelemetry) -- Creates OTel spans with semantic attributes, supports OTLP HTTP/gRPC export, optional metrics and events. - Prometheus (
PrometheusLogger) -- Updates counters (requests, tokens, spend), histograms (latency, TTFT), and gauges (budget remaining) using the prometheus_client library. - Langsmith (
LangsmithLogger) -- Batches run objects and POSTs them to the Langsmith API with configurable project, sampling rate, and tenant ID.
Each handler follows the same contract: receive kwargs (containing standard_logging_object), response_obj, start_time, and end_time, then export data in the platform-specific way.
Usage
These handlers are activated by registering their string identifier or class instance as a callback:
import litellm
# String-based activation (handlers instantiated automatically)
litellm.success_callback = ["otel", "prometheus", "langsmith"]
# Or instance-based activation
from litellm.integrations.opentelemetry import OpenTelemetry
litellm.callbacks = [OpenTelemetry()]
Code Reference
Source Locations
litellm/integrations/opentelemetry.py(lines 1-2398)litellm/integrations/langsmith.py(lines 1-547)litellm/integrations/prometheus.py(lines 67-3240)
Signatures
OpenTelemetry:
class OpenTelemetry(CustomLogger):
def __init__(
self,
config: Optional[OpenTelemetryConfig] = None,
callback_name: Optional[str] = None,
tracer_provider: Optional[Any] = None,
logger_provider: Optional[Any] = None,
meter_provider: Optional[Any] = None,
**kwargs,
): ...
async def async_log_success_event(
self, kwargs, response_obj, start_time, end_time
) -> None: ...
async def async_log_failure_event(
self, kwargs, response_obj, start_time, end_time
) -> None: ...
LangsmithLogger:
class LangsmithLogger(CustomBatchLogger):
def __init__(
self,
langsmith_api_key: Optional[str] = None,
langsmith_project: Optional[str] = None,
langsmith_base_url: Optional[str] = None,
langsmith_sampling_rate: Optional[float] = None,
langsmith_tenant_id: Optional[str] = None,
**kwargs,
): ...
async def async_log_success_event(
self, kwargs, response_obj, start_time, end_time
) -> None: ...
PrometheusLogger:
class PrometheusLogger(CustomLogger):
def __init__(self, **kwargs): ...
async def async_log_success_event(
self, kwargs, response_obj, start_time, end_time
) -> None: ...
async def async_log_failure_event(
self, kwargs, response_obj, start_time, end_time
) -> None: ...
Import
from litellm.integrations.opentelemetry import OpenTelemetry, OpenTelemetryConfig
from litellm.integrations.langsmith import LangsmithLogger
from litellm.integrations.prometheus import PrometheusLogger
I/O Contract
Inputs (async_log_success_event / async_log_failure_event)
| Parameter | Type | Required | Description |
|---|---|---|---|
| kwargs | dict |
Yes | Call metadata including kwargs["standard_logging_object"] (a StandardLoggingPayload), kwargs["model"], kwargs["litellm_params"], and other call details.
|
| response_obj | Any |
Yes | The LLM response object (e.g., ModelResponse, EmbeddingResponse)
|
| start_time | datetime |
Yes | When the API call started |
| end_time | datetime |
Yes | When the API call completed |
Outputs
| Handler | Output Type | Description |
|---|---|---|
| OpenTelemetry | OTel Span | A span is created with semantic attributes (model, tokens, cost, latency) and exported via the configured exporter (console, OTLP HTTP, gRPC). |
| Prometheus | Metric updates | Counters are incremented (litellm_spend_metric, litellm_total_tokens_metric, etc.) and histograms are observed (litellm_request_total_latency_metric).
|
| Langsmith | HTTP POST | A run object is queued and batch-posted to the Langsmith API at /runs.
|
Usage Examples
OpenTelemetry with Custom Endpoint
import litellm
from litellm.integrations.opentelemetry import OpenTelemetry, OpenTelemetryConfig
otel_config = OpenTelemetryConfig(
exporter="otlp_http",
endpoint="https://otel-collector.example.com:4318/v1/traces",
headers="x-api-key=my-secret-key",
)
otel_logger = OpenTelemetry(config=otel_config)
litellm.callbacks = [otel_logger]
# All subsequent litellm.completion() calls will export spans
response = litellm.completion(model="gpt-4", messages=[{"role": "user", "content": "Hi"}])
Prometheus Metrics
import litellm
# Activate Prometheus (metrics exposed on /metrics endpoint)
litellm.success_callback = ["prometheus"]
litellm.failure_callback = ["prometheus"]
# Prometheus metrics automatically tracked:
# - litellm_spend_metric (Counter)
# - litellm_total_tokens_metric (Counter)
# - litellm_request_total_latency_metric (Histogram)
# - litellm_proxy_total_requests_metric (Counter)
# - litellm_proxy_failed_requests_metric (Counter)
# - litellm_llm_api_time_to_first_token_metric (Histogram)
Langsmith with Custom Project
import os
import litellm
os.environ["LANGSMITH_API_KEY"] = "ls-..."
os.environ["LANGSMITH_PROJECT"] = "production-llm-logs"
litellm.success_callback = ["langsmith"]
response = litellm.completion(
model="gpt-4",
messages=[{"role": "user", "content": "Explain quantum computing"}],
)
# Run object is batched and posted to Langsmith