Skip to content

Commit 0ce085d

Browse files
authored
Merge pull request #26 from UiPath/fix/add_trace_settings
fix: add trace settings to filter spans before export
2 parents 3128beb + 74ae729 commit 0ce085d

File tree

7 files changed

+337
-29
lines changed

7 files changed

+337
-29
lines changed

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
[project]
22
name = "uipath-core"
3-
version = "0.1.10"
3+
version = "0.2.0"
44
description = "UiPath Core abstractions"
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.11"
77
dependencies = [
8-
"opentelemetry-sdk>=1.39.0, <2.0.0",
9-
"opentelemetry-instrumentation>=0.60b0, <1.0.0",
8+
"opentelemetry-sdk>=1.39.1, <2.0.0",
9+
"opentelemetry-instrumentation>=0.60b1, <1.0.0",
1010
"pydantic>=2.12.5, <3.0.0",
1111
]
1212
classifiers = [

src/uipath/core/tracing/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
from uipath.core.tracing.decorators import traced
88
from uipath.core.tracing.span_utils import UiPathSpanUtils
99
from uipath.core.tracing.trace_manager import UiPathTraceManager
10+
from uipath.core.tracing.types import UiPathTraceSettings
1011

1112
__all__ = [
1213
"traced",
1314
"UiPathSpanUtils",
1415
"UiPathTraceManager",
16+
"UiPathTraceSettings",
1517
]

src/uipath/core/tracing/processors.py

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
"""Custom span processors for UiPath execution tracing."""
22

3-
from typing import Optional, cast
3+
from typing import cast
44

55
from opentelemetry import context as context_api
66
from opentelemetry import trace
7-
from opentelemetry.sdk.trace import Span
7+
from opentelemetry.sdk.trace import ReadableSpan, Span, SpanProcessor
88
from opentelemetry.sdk.trace.export import (
99
BatchSpanProcessor,
1010
SimpleSpanProcessor,
11+
SpanExporter,
1112
)
1213

14+
from uipath.core.tracing.types import UiPathTraceSettings
15+
1316

1417
class UiPathExecutionTraceProcessorMixin:
15-
def on_start(
16-
self, span: Span, parent_context: Optional[context_api.Context] = None
17-
):
18+
"""Mixin that propagates execution.id and optionally filters spans."""
19+
20+
_settings: UiPathTraceSettings | None = None
21+
22+
def on_start(self, span: Span, parent_context: context_api.Context | None = None):
1823
"""Called when a span is started."""
19-
parent_span: Optional[Span]
24+
parent_span: Span | None
2025
if parent_context:
2126
parent_span = cast(Span, trace.get_current_span(parent_context))
2227
else:
@@ -27,17 +32,42 @@ def on_start(
2732
if execution_id:
2833
span.set_attribute("execution.id", execution_id)
2934

35+
def on_end(self, span: ReadableSpan):
36+
"""Called when a span ends. Filters before delegating to parent."""
37+
span_filter = self._settings.span_filter if self._settings else None
38+
if span_filter is None or span_filter(span):
39+
parent = cast(SpanProcessor, super())
40+
parent.on_end(span)
41+
3042

3143
class UiPathExecutionBatchTraceProcessor(
3244
UiPathExecutionTraceProcessorMixin, BatchSpanProcessor
3345
):
34-
"""Batch span processor that propagates execution.id."""
46+
"""Batch span processor that propagates execution.id and optionally filters."""
47+
48+
def __init__(
49+
self,
50+
span_exporter: SpanExporter,
51+
settings: UiPathTraceSettings | None = None,
52+
):
53+
"""Initialize the batch trace processor."""
54+
super().__init__(span_exporter)
55+
self._settings = settings
3556

3657

3758
class UiPathExecutionSimpleTraceProcessor(
3859
UiPathExecutionTraceProcessorMixin, SimpleSpanProcessor
3960
):
40-
"""Simple span processor that propagates execution.id."""
61+
"""Simple span processor that propagates execution.id and optionally filters."""
62+
63+
def __init__(
64+
self,
65+
span_exporter: SpanExporter,
66+
settings: UiPathTraceSettings | None = None,
67+
):
68+
"""Initialize the simple trace processor."""
69+
super().__init__(span_exporter)
70+
self._settings = settings
4171

4272

4373
__all__ = [

src/uipath/core/tracing/trace_manager.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
UiPathExecutionBatchTraceProcessor,
1616
UiPathExecutionSimpleTraceProcessor,
1717
)
18+
from uipath.core.tracing.types import UiPathTraceSettings
1819

1920

2021
class UiPathTraceManager:
@@ -40,13 +41,22 @@ def add_span_exporter(
4041
self,
4142
span_exporter: SpanExporter,
4243
batch: bool = True,
44+
settings: UiPathTraceSettings | None = None,
4345
) -> UiPathTraceManager:
44-
"""Add a span processor to the tracer provider."""
46+
"""Add a span exporter to the tracer provider.
47+
48+
Args:
49+
span_exporter: The exporter to add.
50+
batch: Whether to use batch processing (default: True).
51+
settings: Optional trace settings for filtering, etc.
52+
"""
4553
span_processor: SpanProcessor
4654
if batch:
47-
span_processor = UiPathExecutionBatchTraceProcessor(span_exporter)
55+
span_processor = UiPathExecutionBatchTraceProcessor(span_exporter, settings)
4856
else:
49-
span_processor = UiPathExecutionSimpleTraceProcessor(span_exporter)
57+
span_processor = UiPathExecutionSimpleTraceProcessor(
58+
span_exporter, settings
59+
)
5060
self.tracer_span_processors.append(span_processor)
5161
self.tracer_provider.add_span_processor(span_processor)
5262
return self

src/uipath/core/tracing/types.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""Tracing types for UiPath SDK."""
2+
3+
from typing import Callable
4+
5+
from opentelemetry.sdk.trace import ReadableSpan
6+
from pydantic import BaseModel, Field
7+
8+
9+
class UiPathTraceSettings(BaseModel):
10+
"""Trace settings for UiPath SDK."""
11+
12+
model_config = {"arbitrary_types_allowed": True} # Needed for Callable
13+
14+
span_filter: Callable[[ReadableSpan], bool] | None = Field(
15+
default=None,
16+
description=(
17+
"Optional filter to decide whether a span should be exported. "
18+
"Called when a span ends with a ReadableSpan argument. "
19+
"Return True to export, False to skip."
20+
),
21+
)

0 commit comments

Comments
 (0)