Skip to content

Commit ea9d066

Browse files
committed
chore: refactor tracer
1 parent 9383776 commit ea9d066

File tree

2 files changed

+144
-2
lines changed

2 files changed

+144
-2
lines changed

src/strands/telemetry/config.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ def setup_console_exporter(self) -> None:
107107
try:
108108
logger.info("enabling console export")
109109
console_processor = SimpleSpanProcessor(ConsoleSpanExporter())
110-
self.tracer_provider.add_span_processor(console_processor)
110+
if self.tracer_provider:
111+
self.tracer_provider.add_span_processor(console_processor)
111112
except Exception as e:
112113
logger.exception("error=<%s> | Failed to configure console exporter", e)
113114

@@ -116,7 +117,8 @@ def setup_otlp_exporter(self) -> None:
116117
try:
117118
otlp_exporter = OTLPSpanExporter()
118119
batch_processor = BatchSpanProcessor(otlp_exporter)
119-
self.tracer_provider.add_span_processor(batch_processor)
120+
if self.tracer_provider:
121+
self.tracer_provider.add_span_processor(batch_processor)
120122
logger.info("endpoint=<%s> | OTLP exporter configured")
121123
except Exception as e:
122124
logger.exception("error=<%s> | Failed to configure OTLP exporter", e)
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
from unittest import mock
2+
3+
import pytest
4+
5+
from strands.telemetry import StrandsTelemetry
6+
7+
8+
@pytest.fixture
9+
def mock_tracer_provider():
10+
with mock.patch("strands.telemetry.config.SDKTracerProvider") as mock_provider:
11+
yield mock_provider
12+
13+
14+
@pytest.fixture
15+
def mock_get_tracer_provider():
16+
with mock.patch("strands.telemetry.config.trace_api.get_tracer_provider") as mock_get_tracer_provider:
17+
mock_provider = mock.MagicMock()
18+
mock_get_tracer_provider.return_value = mock_provider
19+
yield mock_provider
20+
21+
22+
@pytest.fixture
23+
def mock_tracer():
24+
with mock.patch("strands.telemetry.config.trace_api.get_tracer") as mock_get_tracer:
25+
mock_tracer = mock.MagicMock()
26+
mock_get_tracer.return_value = mock_tracer
27+
yield mock_tracer
28+
29+
30+
@pytest.fixture
31+
def mock_set_tracer_provider():
32+
with mock.patch("strands.telemetry.config.trace_api.set_tracer_provider") as mock_set:
33+
yield mock_set
34+
35+
36+
@pytest.fixture
37+
def mock_set_global_textmap():
38+
with mock.patch("strands.telemetry.config.propagate.set_global_textmap") as mock_set_global_textmap:
39+
yield mock_set_global_textmap
40+
41+
42+
@pytest.fixture
43+
def mock_console_exporter():
44+
with mock.patch("strands.telemetry.config.ConsoleSpanExporter") as mock_console_exporter:
45+
yield mock_console_exporter
46+
47+
48+
@pytest.fixture
49+
def mock_otlp_exporter():
50+
with mock.patch("strands.telemetry.config.OTLPSpanExporter") as mock_otlp_exporter:
51+
yield mock_otlp_exporter
52+
53+
54+
@pytest.fixture
55+
def mock_batch_processor():
56+
with mock.patch("strands.telemetry.config.BatchSpanProcessor") as mock_batch_processor:
57+
yield mock_batch_processor
58+
59+
60+
@pytest.fixture
61+
def mock_simple_processor():
62+
with mock.patch("strands.telemetry.config.SimpleSpanProcessor") as mock_simple_processor:
63+
yield mock_simple_processor
64+
65+
66+
@pytest.fixture
67+
def mock_resource():
68+
with mock.patch("strands.telemetry.config.get_otel_resource") as mock_resource:
69+
mock_resource_instance = mock.MagicMock()
70+
mock_resource.return_value = mock_resource_instance
71+
yield mock_resource
72+
73+
74+
@pytest.fixture
75+
def mock_initialize_tracer():
76+
with mock.patch("strands.telemetry.StrandsTelemetry._initialize_tracer") as mock_initialize_tracer:
77+
yield mock_initialize_tracer
78+
79+
80+
def test_init_default(mock_resource, mock_tracer_provider, mock_set_tracer_provider, mock_set_global_textmap):
81+
"""Test initializing the Tracer."""
82+
83+
StrandsTelemetry()
84+
85+
mock_resource.assert_called()
86+
mock_tracer_provider.assert_called_with(resource=mock_resource.return_value)
87+
mock_set_tracer_provider.assert_called_with(mock_tracer_provider.return_value)
88+
mock_set_global_textmap.assert_called()
89+
90+
91+
def test_setup_console_exporter(mock_resource, mock_tracer_provider, mock_console_exporter, mock_simple_processor):
92+
"""Test add console exporter"""
93+
94+
telemetry = StrandsTelemetry()
95+
# Set the tracer_provider directly
96+
telemetry.tracer_provider = mock_tracer_provider.return_value
97+
telemetry.setup_console_exporter()
98+
99+
mock_console_exporter.assert_called_once()
100+
mock_simple_processor.assert_called_once_with(mock_console_exporter.return_value)
101+
102+
mock_tracer_provider.return_value.add_span_processor.assert_called()
103+
104+
105+
def test_setup_otlp_exporter(mock_resource, mock_tracer_provider, mock_otlp_exporter, mock_batch_processor):
106+
"""Test add otlp exporter."""
107+
108+
telemetry = StrandsTelemetry()
109+
# Set the tracer_provider directly
110+
telemetry.tracer_provider = mock_tracer_provider.return_value
111+
telemetry.setup_otlp_exporter()
112+
113+
mock_otlp_exporter.assert_called_once()
114+
mock_batch_processor.assert_called_once_with(mock_otlp_exporter.return_value)
115+
116+
mock_tracer_provider.return_value.add_span_processor.assert_called()
117+
118+
119+
def test_setup_console_exporter_exception(mock_resource, mock_tracer_provider, mock_console_exporter):
120+
"""Test console exporter with exception."""
121+
mock_console_exporter.side_effect = Exception("Test exception")
122+
123+
telemetry = StrandsTelemetry()
124+
telemetry.tracer_provider = mock_tracer_provider.return_value
125+
# This should not raise an exception
126+
telemetry.setup_console_exporter()
127+
128+
mock_console_exporter.assert_called_once()
129+
130+
131+
def test_setup_otlp_exporter_exception(mock_resource, mock_tracer_provider, mock_otlp_exporter):
132+
"""Test otlp exporter with exception."""
133+
mock_otlp_exporter.side_effect = Exception("Test exception")
134+
135+
telemetry = StrandsTelemetry()
136+
telemetry.tracer_provider = mock_tracer_provider.return_value
137+
# This should not raise an exception
138+
telemetry.setup_otlp_exporter()
139+
140+
mock_otlp_exporter.assert_called_once()

0 commit comments

Comments
 (0)