dd logger fix - handle objects that can't be JSON dumped (#7393)

* dd logger fix - handle objects that can't be dumped

* test_datadog_non_serializable_messages
This commit is contained in:
Ishaan Jaff 2024-12-23 18:21:49 -08:00 committed by GitHub
parent 4bcb422d31
commit 8aaa0b44c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 38 additions and 4 deletions

View file

@ -272,7 +272,7 @@ class DataDogLogger(CustomBatchLogger):
# Build the initial payload # Build the initial payload
truncate_standard_logging_payload_content(standard_logging_object) truncate_standard_logging_payload_content(standard_logging_object)
json_payload = json.dumps(standard_logging_object) json_payload = json.dumps(standard_logging_object, default=str)
verbose_logger.debug("Datadog: Logger - Logging payload = %s", json_payload) verbose_logger.debug("Datadog: Logger - Logging payload = %s", json_payload)
@ -298,7 +298,7 @@ class DataDogLogger(CustomBatchLogger):
import gzip import gzip
import json import json
compressed_data = gzip.compress(json.dumps(data).encode("utf-8")) compressed_data = gzip.compress(json.dumps(data, default=str).encode("utf-8"))
response = await self.async_client.post( response = await self.async_client.post(
url=self.intake_url, url=self.intake_url,
data=compressed_data, # type: ignore data=compressed_data, # type: ignore
@ -329,7 +329,7 @@ class DataDogLogger(CustomBatchLogger):
import json import json
_payload_dict = payload.model_dump() _payload_dict = payload.model_dump()
_dd_message_str = json.dumps(_payload_dict) _dd_message_str = json.dumps(_payload_dict, default=str)
_dd_payload = DatadogPayload( _dd_payload = DatadogPayload(
ddsource="litellm", ddsource="litellm",
ddtags="", ddtags="",
@ -433,7 +433,7 @@ class DataDogLogger(CustomBatchLogger):
"metadata": clean_metadata, "metadata": clean_metadata,
} }
json_payload = json.dumps(payload) json_payload = json.dumps(payload, default=str)
verbose_logger.debug("Datadog: Logger - Logging payload = %s", json_payload) verbose_logger.debug("Datadog: Logger - Logging payload = %s", json_payload)

View file

@ -498,3 +498,37 @@ def test_datadog_static_methods():
expected_custom_tags = "env:production,service:custom-service,version:1.0.0,HOSTNAME:test-host,POD_NAME:pod-123" expected_custom_tags = "env:production,service:custom-service,version:1.0.0,HOSTNAME:test-host,POD_NAME:pod-123"
print("DataDogLogger._get_datadog_tags()", DataDogLogger._get_datadog_tags()) print("DataDogLogger._get_datadog_tags()", DataDogLogger._get_datadog_tags())
assert DataDogLogger._get_datadog_tags() == expected_custom_tags assert DataDogLogger._get_datadog_tags() == expected_custom_tags
@pytest.mark.asyncio
async def test_datadog_non_serializable_messages():
"""Test logging events with non-JSON-serializable messages"""
dd_logger = DataDogLogger()
# Create payload with non-serializable content
standard_payload = create_standard_logging_payload()
non_serializable_obj = datetime.now() # datetime objects aren't JSON serializable
standard_payload["messages"] = [{"role": "user", "content": non_serializable_obj}]
standard_payload["response"] = {
"choices": [{"message": {"content": non_serializable_obj}}]
}
kwargs = {"standard_logging_object": standard_payload}
# Test payload creation
dd_payload = dd_logger.create_datadog_logging_payload(
kwargs=kwargs,
response_obj=None,
start_time=datetime.now(),
end_time=datetime.now(),
)
# Verify payload can be serialized
assert dd_payload["status"] == DataDogStatus.INFO
# Verify the message can be parsed back to dict
dict_payload = json.loads(dd_payload["message"])
# Check that the non-serializable objects were converted to strings
assert isinstance(dict_payload["messages"][0]["content"], str)
assert isinstance(dict_payload["response"]["choices"][0]["message"]["content"], str)