mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-28 06:23:07 +00:00
Merge f0a9d5c270 into b6f91a221b
This commit is contained in:
commit
c3e375ec8b
2 changed files with 75 additions and 0 deletions
|
|
@ -117,6 +117,13 @@ class _FailureKwargsView(TypedDict, total=False):
|
|||
|
||||
_JSON_OBJECT: Final = TypeAdapter(Mapping[str, object], config=ConfigDict(hide_input_in_errors=True))
|
||||
|
||||
# Metadata keys dropped from spans when `litellm.redact_user_api_key_info` is set.
|
||||
_USER_API_KEY_METADATA_KEYS: Final = frozenset(
|
||||
key
|
||||
for key in StandardLoggingMetadata.__required_keys__ | StandardLoggingMetadata.__optional_keys__
|
||||
if key.startswith("user_api_key")
|
||||
)
|
||||
|
||||
|
||||
def _text_as_stored_on_span(span: Span, key: str, text: str) -> str:
|
||||
from opentelemetry.sdk.trace import ReadableSpan
|
||||
|
|
@ -1549,6 +1556,8 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger):
|
|||
in ``standard_logging_object.metadata``; propagating that to every
|
||||
span only adds noise that makes traces look mis-instrumented.
|
||||
"""
|
||||
if litellm.redact_user_api_key_info is True:
|
||||
return
|
||||
if team_id:
|
||||
self.safe_set_attribute(
|
||||
span=span,
|
||||
|
|
@ -2457,7 +2466,10 @@ class OpenTelemetry(OTELGenAISemconvMixin, CustomLogger):
|
|||
metadata: Final = cast( # cast-ok: payload metadata follows the standard logging contract
|
||||
StandardLoggingMetadata, standard_logging_payload["metadata"]
|
||||
)
|
||||
redact_user_api_key_info: Final = litellm.redact_user_api_key_info is True
|
||||
for key, value in metadata.items():
|
||||
if redact_user_api_key_info and key in _USER_API_KEY_METADATA_KEYS:
|
||||
continue
|
||||
self.safe_set_attribute(
|
||||
span=span,
|
||||
key=f"metadata.{key}",
|
||||
|
|
|
|||
63
tests/unit/integrations/test_opentelemetry_redaction.py
Normal file
63
tests/unit/integrations/test_opentelemetry_redaction.py
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
"""Regression tests for ``redact_user_api_key_info`` in OTEL spans (#36758)."""
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
import litellm
|
||||
from litellm.integrations.opentelemetry import OpenTelemetry
|
||||
|
||||
_USER_API_KEY_METADATA = {
|
||||
"user_api_key_hash": "hashed-secret",
|
||||
"user_api_key_user_id": "uid-123",
|
||||
"user_api_key_user_email": "user@example.com",
|
||||
"user_api_key_team_id": "team-456",
|
||||
}
|
||||
|
||||
|
||||
def _metadata_attribute_keys(redact: bool, monkeypatch: pytest.MonkeyPatch) -> list[str]:
|
||||
monkeypatch.setattr(litellm, "redact_user_api_key_info", redact)
|
||||
otel_logger = OpenTelemetry()
|
||||
otel_logger.safe_set_attribute = MagicMock()
|
||||
otel_logger._set_inference_identity_attributes = MagicMock()
|
||||
otel_logger._set_service_tier_attributes = MagicMock()
|
||||
otel_logger._capture_in_span = MagicMock(return_value=False)
|
||||
|
||||
otel_logger.set_attributes(
|
||||
span=MagicMock(),
|
||||
kwargs={
|
||||
"litellm_params": {"custom_llm_provider": "openai"},
|
||||
"standard_logging_object": {
|
||||
"call_type": "completion",
|
||||
"metadata": {**_USER_API_KEY_METADATA, "generation_name": "test-gen"},
|
||||
},
|
||||
},
|
||||
response_obj=None,
|
||||
)
|
||||
return [call.kwargs["key"] for call in otel_logger.safe_set_attribute.call_args_list]
|
||||
|
||||
|
||||
def test_set_attributes_drops_user_api_key_metadata_when_redaction_enabled(monkeypatch):
|
||||
attribute_keys = _metadata_attribute_keys(redact=True, monkeypatch=monkeypatch)
|
||||
|
||||
assert "metadata.generation_name" in attribute_keys
|
||||
for key in _USER_API_KEY_METADATA:
|
||||
assert f"metadata.{key}" not in attribute_keys
|
||||
|
||||
|
||||
def test_set_attributes_keeps_user_api_key_metadata_when_redaction_disabled(monkeypatch):
|
||||
attribute_keys = _metadata_attribute_keys(redact=False, monkeypatch=monkeypatch)
|
||||
|
||||
for key in _USER_API_KEY_METADATA:
|
||||
assert f"metadata.{key}" in attribute_keys
|
||||
|
||||
|
||||
@pytest.mark.parametrize("redact, expected_calls", [(True, 0), (False, 2)])
|
||||
def test_team_attributes_on_child_spans_respect_redaction(monkeypatch, redact, expected_calls):
|
||||
monkeypatch.setattr(litellm, "redact_user_api_key_info", redact)
|
||||
otel_logger = OpenTelemetry()
|
||||
otel_logger.safe_set_attribute = MagicMock()
|
||||
|
||||
otel_logger._set_team_attributes_on_span(span=MagicMock(), team_id="team-456", team_alias="team-alias")
|
||||
|
||||
assert otel_logger.safe_set_attribute.call_count == expected_calls
|
||||
Loading…
Add table
Reference in a new issue