Skip to content

Commit 1c35cc2

Browse files
fix(tracing): fix tracing attr parsing bugs (#117)
1 parent fbcc9ec commit 1c35cc2

File tree

4 files changed

+35
-13
lines changed

4 files changed

+35
-13
lines changed

tests/test_cloud.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,12 @@ async def test_cloud():
115115
mock_vefaas_client = Mock()
116116
mock_vefaas_in_app.return_value = mock_vefaas_client
117117
mock_vefaas_client.delete.return_value = None
118-
119-
cloud_app.delete_self()
120-
mock_vefaas_client.delete.assert_called_with("app-123")
118+
with patch.object(
119+
cloud_app, "_get_vefaas_application_id_by_name"
120+
) as mock_get_id_by_name:
121+
mock_get_id_by_name.return_value = None
122+
cloud_app.delete_self()
123+
mock_vefaas_client.delete.assert_called_with("app-123")
121124

122125
# Verify all mocks were called as expected
123126
mock_vefaas_service.deploy.assert_called_once()

veadk/tracing/telemetry/attributes/extractors/llm_attributes_extractors.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
ExtractorResponse,
1919
LLMAttributesParams,
2020
)
21+
from veadk.utils.misc import safe_json_serialize
2122

2223

2324
def llm_gen_ai_request_model(params: LLMAttributesParams) -> ExtractorResponse:
@@ -133,7 +134,7 @@ def llm_gen_ai_prompt(params: LLMAttributesParams) -> ExtractorResponse:
133134
else "<unknown_function_name>"
134135
)
135136
message[f"gen_ai.prompt.{idx}.tool_calls.0.function.arguments"] = (
136-
json.dumps(part.function_call.args)
137+
safe_json_serialize(part.function_call.args)
137138
if part.function_call.args
138139
else json.dumps({})
139140
)
@@ -168,7 +169,7 @@ def llm_gen_ai_completion(params: LLMAttributesParams) -> ExtractorResponse:
168169
else "<unknown_function_name>"
169170
)
170171
message[f"gen_ai.completion.{idx}.tool_calls.0.function.arguments"] = (
171-
json.dumps(part.function_call.args)
172+
safe_json_serialize(part.function_call.args)
172173
if part.function_call.args
173174
else json.dumps({})
174175
)
@@ -289,7 +290,7 @@ def llm_gen_ai_assistant_message(params: LLMAttributesParams) -> ExtractorRespon
289290
else "<unknown_function_name>"
290291
)
291292
message_part["tool_calls.0.function.arguments"] = (
292-
json.dumps(part.function_call.args)
293+
safe_json_serialize(part.function_call.args)
293294
if part.function_call.args
294295
else json.dumps({})
295296
)
@@ -326,7 +327,7 @@ def llm_gen_ai_choice(params: LLMAttributesParams) -> ExtractorResponse:
326327
else "<unknown_function_name>"
327328
)
328329
message["message.tool_calls.0.function.arguments"] = (
329-
json.dumps(part.function_call.args)
330+
safe_json_serialize(part.function_call.args)
330331
if part.function_call.args
331332
else json.dumps({})
332333
)
@@ -351,7 +352,7 @@ def llm_gen_ai_choice(params: LLMAttributesParams) -> ExtractorResponse:
351352
else "<unknown_function_name>"
352353
)
353354
message["message.tool_calls.0.function.arguments"] = (
354-
json.dumps(part.function_call.args)
355+
safe_json_serialize(part.function_call.args)
355356
if part.function_call.args
356357
else json.dumps({})
357358
)

veadk/tracing/telemetry/attributes/extractors/tool_attributes_extractors.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import json
16-
1715
from veadk.tracing.telemetry.attributes.extractors.types import (
1816
ExtractorResponse,
1917
ToolAttributesParams,
2018
)
19+
from veadk.utils.misc import safe_json_serialize
2120

2221

2322
def tool_gen_ai_operation_name(params: ToolAttributesParams) -> ExtractorResponse:
@@ -27,7 +26,7 @@ def tool_gen_ai_operation_name(params: ToolAttributesParams) -> ExtractorRespons
2726
def tool_gen_ai_tool_message(params: ToolAttributesParams) -> ExtractorResponse:
2827
tool_input = {
2928
"role": "tool",
30-
"content": json.dumps(
29+
"content": safe_json_serialize(
3130
{
3231
"name": params.tool.name,
3332
"description": params.tool.description,
@@ -45,7 +44,7 @@ def tool_gen_ai_tool_input(params: ToolAttributesParams) -> ExtractorResponse:
4544
"parameters": params.args,
4645
}
4746
return ExtractorResponse(
48-
content=json.dumps(tool_input, ensure_ascii=False) or "<unknown_tool_input>"
47+
content=safe_json_serialize(tool_input) or "<unknown_tool_input>"
4948
)
5049

5150

@@ -63,7 +62,7 @@ def tool_gen_ai_tool_output(params: ToolAttributesParams) -> ExtractorResponse:
6362
"response": function_response["response"],
6463
}
6564
return ExtractorResponse(
66-
content=json.dumps(tool_output, ensure_ascii=False) or "<unknown_tool_output>"
65+
content=safe_json_serialize(tool_output) or "<unknown_tool_output>"
6766
)
6867

6968

veadk/utils/misc.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import importlib.util
16+
import json
1617
import sys
1718
import time
1819
import types
@@ -81,3 +82,21 @@ def flatten_dict(
8182
else:
8283
items.append((new_key, v))
8384
return dict(items)
85+
86+
87+
def safe_json_serialize(obj) -> str:
88+
"""Convert any Python object to a JSON-serializable type or string.
89+
90+
Args:
91+
obj: The object to serialize.
92+
93+
Returns:
94+
The JSON-serialized object string or <non-serializable> if the object cannot be serialized.
95+
"""
96+
97+
try:
98+
return json.dumps(
99+
obj, ensure_ascii=False, default=lambda o: "<not serializable>"
100+
)
101+
except (TypeError, OverflowError):
102+
return "<not serializable>"

0 commit comments

Comments
 (0)