From f28c3fb94327124f49acf03e920e66eef6a4552f Mon Sep 17 00:00:00 2001 From: radu-mocanu Date: Wed, 4 Feb 2026 13:13:34 +0200 Subject: [PATCH 1/4] wip: support for tracing custom attributes --- src/uipath/core/tracing/_utils.py | 14 ++++++++++++++ src/uipath/core/tracing/decorators.py | 6 ++++++ 2 files changed, 20 insertions(+) diff --git a/src/uipath/core/tracing/_utils.py b/src/uipath/core/tracing/_utils.py index 841aa67..a49b833 100644 --- a/src/uipath/core/tracing/_utils.py +++ b/src/uipath/core/tracing/_utils.py @@ -86,6 +86,7 @@ def set_span_input_attributes( span_type: str, run_type: Optional[str], input_processor: Optional[Callable[..., Any]], + input_attributes_callable: Optional[Callable[..., dict[str, Any]]] = None, ) -> None: """Set span attributes for metadata and inputs before function execution. @@ -122,11 +123,18 @@ def set_span_input_attributes( span.set_attribute("input.mime_type", "application/json") span.set_attribute("input.value", inputs) + try: + for key, value in input_attributes_callable(*args, **kwargs): + span.set_attribute(key, value) + except Exception: + # catch exceptions silently if there are some attributes we cannot set and return the already set ones + pass def set_span_output_attributes( span: Span, result: Any, output_processor: Optional[Callable[..., Any]], + output_attributes_callable: Optional[Callable[..., dict[str, Any]]] = None, ) -> None: """Set span attributes for outputs after function execution. @@ -140,3 +148,9 @@ def set_span_output_attributes( output = output_processor(result) if output_processor else result span.set_attribute("output.value", format_object_for_trace_json(output)) span.set_attribute("output.mime_type", "application/json") + try: + for key, value in output_attributes_callable(result): + span.set_attribute(key, value) + except Exception: + # catch exceptions silently if there are some attributes we cannot set and return the already set ones + pass diff --git a/src/uipath/core/tracing/decorators.py b/src/uipath/core/tracing/decorators.py index d1c751a..9ee40f6 100644 --- a/src/uipath/core/tracing/decorators.py +++ b/src/uipath/core/tracing/decorators.py @@ -32,6 +32,8 @@ def _opentelemetry_traced( span_type: Optional[str] = None, input_processor: Optional[Callable[..., Any]] = None, output_processor: Optional[Callable[..., Any]] = None, + input_attributes_callable: Optional[Callable[..., dict[str, Any]]] = None, + output_attributes_callable: Optional[Callable[..., dict[str, Any]]] = None, recording: bool = True, ): """Default tracer implementation using OpenTelemetry. @@ -264,6 +266,8 @@ def traced( span_type: Optional[str] = None, input_processor: Optional[Callable[..., Any]] = None, output_processor: Optional[Callable[..., Any]] = None, + input_attributes_callable: Optional[Callable[..., dict[str, Any]]] = None, + output_attributes_callable: Optional[Callable[..., dict[str, Any]]] = None, hide_input: bool = False, hide_output: bool = False, recording: bool = True, @@ -304,6 +308,8 @@ def _default_output_processor(outputs: Any) -> dict[str, str]: "span_type": span_type, "input_processor": input_processor, "output_processor": output_processor, + "input_attributes_callable": input_attributes_callable, + "output_attributes_callable": output_attributes_callable, "recording": recording, } From 3ed8f06db7e98714d1e2adca08bfbd2ec0a4c66d Mon Sep 17 00:00:00 2001 From: radu-mocanu Date: Wed, 4 Feb 2026 15:11:53 +0200 Subject: [PATCH 2/4] wip: support for tracing custom attributes --- src/uipath/core/tracing/_utils.py | 26 ++++++++++++++------------ src/uipath/core/tracing/decorators.py | 8 ++++++++ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/uipath/core/tracing/_utils.py b/src/uipath/core/tracing/_utils.py index a49b833..08377c6 100644 --- a/src/uipath/core/tracing/_utils.py +++ b/src/uipath/core/tracing/_utils.py @@ -123,12 +123,13 @@ def set_span_input_attributes( span.set_attribute("input.mime_type", "application/json") span.set_attribute("input.value", inputs) - try: - for key, value in input_attributes_callable(*args, **kwargs): - span.set_attribute(key, value) - except Exception: - # catch exceptions silently if there are some attributes we cannot set and return the already set ones - pass + if input_attributes_callable: + try: + for key, value in input_attributes_callable(*args, **kwargs): + span.set_attribute(key, value) + except Exception: + # Suppress exceptions from custom attributes to avoid breaking instrumentation (already-set attributes remain) + pass def set_span_output_attributes( span: Span, @@ -148,9 +149,10 @@ def set_span_output_attributes( output = output_processor(result) if output_processor else result span.set_attribute("output.value", format_object_for_trace_json(output)) span.set_attribute("output.mime_type", "application/json") - try: - for key, value in output_attributes_callable(result): - span.set_attribute(key, value) - except Exception: - # catch exceptions silently if there are some attributes we cannot set and return the already set ones - pass + if output_processor: + try: + for key, value in output_attributes_callable(result): + span.set_attribute(key, value) + except Exception: + # Suppress exceptions from custom attributes to avoid breaking instrumentation (already-set attributes remain) + pass diff --git a/src/uipath/core/tracing/decorators.py b/src/uipath/core/tracing/decorators.py index 9ee40f6..3177ed3 100644 --- a/src/uipath/core/tracing/decorators.py +++ b/src/uipath/core/tracing/decorators.py @@ -107,6 +107,7 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any: run_type=run_type, span_type=span_type or "function_call_sync", input_processor=input_processor, + input_attributes_callable=input_attributes_callable, ) # Execute the function @@ -117,6 +118,7 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any: span, result=result, output_processor=output_processor, + output_attributes_callable=output_attributes_callable, ) return result except Exception as e: @@ -144,6 +146,7 @@ async def async_wrapper(*args: Any, **kwargs: Any) -> Any: run_type=run_type, span_type=span_type or "function_call_async", input_processor=input_processor, + input_attributes_callable=input_attributes_callable, ) # Execute the function @@ -154,6 +157,7 @@ async def async_wrapper(*args: Any, **kwargs: Any) -> Any: span, result=result, output_processor=output_processor, + output_attributes_callable=output_attributes_callable, ) return result except Exception as e: @@ -183,6 +187,7 @@ def generator_wrapper(*args: Any, **kwargs: Any) -> Any: run_type=run_type, span_type=span_type or "function_call_generator_sync", input_processor=input_processor, + input_attributes_callable=input_attributes_callable, ) # Execute the generator and collect outputs @@ -197,6 +202,7 @@ def generator_wrapper(*args: Any, **kwargs: Any) -> Any: span, result=outputs, output_processor=output_processor, + output_attributes_callable=output_attributes_callable, ) except Exception as e: span.record_exception(e) @@ -225,6 +231,7 @@ async def async_generator_wrapper(*args: Any, **kwargs: Any) -> Any: run_type=run_type, span_type=span_type or "function_call_generator_async", input_processor=input_processor, + input_attributes_callable=input_attributes_callable, ) # Execute the generator and collect outputs @@ -239,6 +246,7 @@ async def async_generator_wrapper(*args: Any, **kwargs: Any) -> Any: span, result=outputs, output_processor=output_processor, + output_attributes_callable=output_attributes_callable, ) except Exception as e: span.record_exception(e) From 225978d51cad55b9a9a9031356902089bfdad4e8 Mon Sep 17 00:00:00 2001 From: radu-mocanu Date: Wed, 4 Feb 2026 15:38:33 +0200 Subject: [PATCH 3/4] wip: support for tracing custom attributes --- src/uipath/core/tracing/_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uipath/core/tracing/_utils.py b/src/uipath/core/tracing/_utils.py index 08377c6..82eb5b8 100644 --- a/src/uipath/core/tracing/_utils.py +++ b/src/uipath/core/tracing/_utils.py @@ -149,7 +149,7 @@ def set_span_output_attributes( output = output_processor(result) if output_processor else result span.set_attribute("output.value", format_object_for_trace_json(output)) span.set_attribute("output.mime_type", "application/json") - if output_processor: + if output_attributes_callable: try: for key, value in output_attributes_callable(result): span.set_attribute(key, value) From 057f52d7f45710adfe0831cd4eeb3e0dc127cbd5 Mon Sep 17 00:00:00 2001 From: radu-mocanu Date: Wed, 4 Feb 2026 15:44:28 +0200 Subject: [PATCH 4/4] wip: support for tracing custom attributes --- src/uipath/core/tracing/_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uipath/core/tracing/_utils.py b/src/uipath/core/tracing/_utils.py index 82eb5b8..28d25d4 100644 --- a/src/uipath/core/tracing/_utils.py +++ b/src/uipath/core/tracing/_utils.py @@ -125,7 +125,7 @@ def set_span_input_attributes( if input_attributes_callable: try: - for key, value in input_attributes_callable(*args, **kwargs): + for key, value in input_attributes_callable(*args, **kwargs).items(): span.set_attribute(key, value) except Exception: # Suppress exceptions from custom attributes to avoid breaking instrumentation (already-set attributes remain) @@ -151,7 +151,7 @@ def set_span_output_attributes( span.set_attribute("output.mime_type", "application/json") if output_attributes_callable: try: - for key, value in output_attributes_callable(result): + for key, value in output_attributes_callable(result).items(): span.set_attribute(key, value) except Exception: # Suppress exceptions from custom attributes to avoid breaking instrumentation (already-set attributes remain)