mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-21 00:21:49 +00:00
* fix(otel): one v2 logger owns the global provider; scope tenant creds per exporter The proxy published the OTel global TracerProvider before callbacks were initialized, so no preset logger existed yet and a second generic logger was built that won the global provider. Server spans then exported through a different provider than the preset's gen-ai spans, orphaning the LLM span on the preset backend. Publish after callback init and reuse the already-built logger instead. Separately, per-request tenant OTLP credentials were stamped onto every OTLP exporter, leaking one backend's key onto a co-configured backend. Tag each exporter with the preset that contributed it and apply dynamic credentials only to the matching owner. * fix(otel): satisfy Any-discipline on changed lines Type the logger-selection parameter as Sequence[object] (isinstance narrows it), cast the list[Any] global at the single call site, and pass model_copy a typed dict[str, str] update so no changed line carries an Any value. * fix(otel): annotate the untyped-global boundary with any-ok select_global_otel_v2_logger consumes litellm._in_memory_loggers, a shared List[Any] global this change does not own. A cast doesn't satisfy the Any-discipline checker (it inspects the inner expression), and re-annotating the global is out of scope, so mark the single boundary line any-ok. * test(otel): cover the startup global-provider publish via injectable helper The publish step lived inline in proxy_startup_event (a FastAPI lifespan unit tests do not execute), so its lines were uncovered though the selection logic was tested. Extract publish_global_otel_v2_provider, which selects the single v2 logger and publishes its provider through an injected setter, and unit-test that the published provider is the selected logger's. proxy_server delegates to it. * refactor(otel): select global provider from the registered owner, not a list scan The startup publish picked the global TracerProvider by scanning _in_memory_loggers for the first OpenTelemetryV2, re-deriving an answer the factory already settled: the first logger built registers itself as proxy_server.open_telemetry_logger, and every other v2 path (guardrail, identity seeding, phase spans) routes through that owner via _registered_v2_logger. Pass that owner into select_global_otel_v2_logger so the global provider reuses the same logger instead of an independent, order-dependent guess; the list scan remains the SDK-path fallback. The owner is injected at the proxy call site to keep the helper free of hidden global reads. * refactor(otel): type ExporterSpec.owner as an ExporterOwner enum The owner field carried free-form strings that had to match preset callback names. Introduce a str-based ExporterOwner enum (values equal to the callback names, so per-request credential routing's owner==callback_name comparison still holds) and have each preset tag its exporter with the enum member. * refactor(otel): rename ExporterOwner.ARIZE to ARIZE_AX Distinguish the hosted Arize AX backend from Arize Phoenix at the member level while keeping the value 'arize' (the public callback name routing compares against). Add a comment noting AX and Phoenix are separate backends. |
||
|---|---|---|
| .. | ||
| _types | ||
| agentops | ||
| arize | ||
| azure_sentinel | ||
| azure_storage | ||
| bitbucket | ||
| cloudzero | ||
| compression_interception | ||
| datadog | ||
| deepeval | ||
| dotprompt | ||
| email_templates | ||
| focus | ||
| gcs_bucket | ||
| gcs_pubsub | ||
| generic_api | ||
| generic_prompt_management | ||
| gitlab | ||
| langfuse | ||
| levo | ||
| litellm_agent | ||
| mavvrik_focus | ||
| newrelic | ||
| opentelemetry_utils | ||
| opik | ||
| otel | ||
| prometheus_helpers | ||
| SlackAlerting | ||
| vantage | ||
| vector_store_integrations | ||
| weave | ||
| websearch_interception | ||
| __init__.py | ||
| additional_logging_utils.py | ||
| anthropic_cache_control_hook.py | ||
| argilla.py | ||
| athina.py | ||
| braintrust_logging.py | ||
| braintrust_mock_client.py | ||
| callback_configs.json | ||
| custom_batch_logger.py | ||
| custom_guardrail.py | ||
| custom_logger.py | ||
| custom_prompt_management.py | ||
| custom_secret_manager.py | ||
| custom_sso_handler.py | ||
| dynamodb.py | ||
| email_alerting.py | ||
| galileo.py | ||
| greenscale.py | ||
| helicone.py | ||
| helicone_mock_client.py | ||
| humanloop.py | ||
| lago.py | ||
| langsmith.py | ||
| langsmith_mock_client.py | ||
| langtrace.py | ||
| literal_ai.py | ||
| logfire_logger.py | ||
| lunary.py | ||
| mlflow.py | ||
| mock_client_factory.py | ||
| openmeter.py | ||
| opentelemetry.py | ||
| posthog.py | ||
| posthog_mock_client.py | ||
| prometheus.py | ||
| prometheus_services.py | ||
| prompt_layer.py | ||
| prompt_management_base.py | ||
| Readme.md | ||
| rubrik.py | ||
| s3.py | ||
| s3_v2.py | ||
| sqs.py | ||
| supabase.py | ||
| test_httpx.py | ||
| traceloop.py | ||
| weights_biases.py | ||
Integrations
This folder contains logging integrations for litellm
eg. logging to Datadog, Langfuse, Prometheus, s3, GCS Bucket, etc.