Skip to content
This repository was archived by the owner on Mar 4, 2026. It is now read-only.

Commit 5e12071

Browse files
committed
alter traces
1 parent 99c78e6 commit 5e12071

1 file changed

Lines changed: 73 additions & 14 deletions

File tree

src/uipath/core/tracing/manager.py

Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,33 +28,92 @@ def register_current_span_provider(
2828
cls._current_span_provider = current_span_provider
2929

3030
@staticmethod
31-
def get_parent_context():
31+
def get_parent_context() -> context.Context:
3232
"""Get the parent context for span creation.
3333
3434
Prioritizes:
35-
1. Currently active OTel span (for recursion/children)
36-
2. External span provider (for top-level calls)
37-
3. Current context as fallback
35+
- Bottom-most span when both current_span and external_span exist
36+
- Single available span (current_span or external_span)
37+
- Current context as fallback
3838
"""
39-
# Always use the currently active OTel span if valid (recursion / children)
4039
current_span = trace.get_current_span()
40+
has_current_span = current_span is not None and current_span.get_span_context().is_valid
4141

42-
if current_span is not None and current_span.get_span_context().is_valid:
42+
external_span = UiPathTracingManager.get_external_current_span()
43+
has_external_span = external_span is not None
44+
45+
# Only one or no spans available
46+
if not has_current_span:
47+
return set_span_in_context(external_span) if has_external_span else context.get_current()
48+
if not has_external_span:
4349
return set_span_in_context(current_span)
4450

45-
# Only for the very top-level call, fallback to external span provider
51+
# Both spans exist - find the bottom-most one
52+
bottom_span = UiPathTracingManager._get_bottom_most_span(
53+
current_span, external_span
54+
)
55+
return set_span_in_context(bottom_span)
56+
57+
@staticmethod
58+
def _get_bottom_most_span(current_span: Any, external_span: Any) -> Any:
59+
"""Determine which span is deeper in the ancestor tree.
60+
61+
Args:
62+
current_span: The OTel current span
63+
external_span: The external span from the provider
64+
65+
Returns:
66+
The span that is deeper (closer to the bottom) in the call hierarchy
67+
"""
68+
ancestor_spans = UiPathTracingManager.get_ancestor_spans()
69+
if not ancestor_spans:
70+
return external_span
71+
72+
current_span_id = current_span.get_span_context().span_id
73+
external_span_id = external_span.get_span_context().span_id
74+
75+
current_index = None
76+
external_index = None
77+
78+
for i, ancestor in enumerate(ancestor_spans):
79+
ancestor_id = ancestor.get_span_context().span_id
80+
if ancestor_id == current_span_id:
81+
current_index = i
82+
if ancestor_id == external_span_id:
83+
external_index = i
84+
85+
# Both in tree: higher index = deeper
86+
if current_index is not None and external_index is not None:
87+
return current_span if current_index > external_index else external_span
88+
89+
# Only one in tree: that one is deeper
90+
if current_index is not None:
91+
return current_span
92+
if external_index is not None:
93+
return external_span
94+
95+
# Neither in tree: default to external
96+
return external_span
97+
98+
@staticmethod
99+
def get_external_current_span():
100+
"""Get the current span from the external provider, if any."""
46101
if UiPathTracingManager._current_span_provider is not None:
47102
try:
48-
external_span = UiPathTracingManager._current_span_provider()
49-
if external_span is not None:
50-
return set_span_in_context(external_span)
103+
return UiPathTracingManager._current_span_provider()
51104
except Exception as e:
52105
logger.warning(f"Error getting current span from provider: {e}")
106+
return None
53107

54-
# Last fallback
55-
ctx = context.get_current()
56-
57-
return ctx
108+
@classmethod
109+
def get_ancestor_spans(cls) -> List[Any]:
110+
"""Get the ancestor spans from the registered provider, if any."""
111+
if cls._current_span_ancestors_provider is not None:
112+
try:
113+
return cls._current_span_ancestors_provider()
114+
except Exception as e:
115+
logger.warning(f"Error getting ancestor spans from provider: {e}")
116+
return []
58117

59118
@classmethod
60119
def register_current_span_ancestors_provider(

0 commit comments

Comments
 (0)