Skip to content

Commit 1b7b6f2

Browse files
committed
perf: only force flush tracer provider when ending agent spans
Reduce overhead by limiting force_flush calls to agent span completion instead of every span end. Add flush parameter to _end_span() with default False, passing True only from end_agent_span().
1 parent c5342cc commit 1b7b6f2

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

src/strands/telemetry/tracer.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ def _end_span(
186186
attributes: dict[str, AttributeValue] | None = None,
187187
error: BaseException | None = None,
188188
error_message: str | None = None,
189+
flush: bool = False,
189190
) -> None:
190191
"""Generic helper method to end a span.
191192
@@ -194,6 +195,7 @@ def _end_span(
194195
attributes: Optional attributes to set before ending the span
195196
error: Optional exception if an error occurred
196197
error_message: Optional error message to set in the span status
198+
flush: Force the tracer provider to flush after ending the span
197199
"""
198200
if not span or not span.is_recording():
199201
return
@@ -217,8 +219,7 @@ def _end_span(
217219
logger.warning("error=<%s> | error while ending span", e, exc_info=True)
218220
finally:
219221
span.end()
220-
# Force flush to ensure spans are exported
221-
if self.tracer_provider and hasattr(self.tracer_provider, "force_flush"):
222+
if flush and self.tracer_provider and hasattr(self.tracer_provider, "force_flush"):
222223
try:
223224
self.tracer_provider.force_flush()
224225
except Exception as e:
@@ -699,7 +700,7 @@ def end_agent_span(
699700
}
700701
)
701702

702-
self._end_span(span, attributes, error)
703+
self._end_span(span, attributes, error, flush=True)
703704

704705
def _construct_tool_definitions(self, tools_config: dict) -> list[dict[str, Any]]:
705706
"""Constructs a list of tool definitions from the provided tools_config."""

tests/strands/telemetry/test_tracer.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,21 +1089,40 @@ def test_end_span_with_exception_handling(mock_span):
10891089
pytest.fail("_end_span should not raise exceptions")
10901090

10911091

1092+
def test_end_span_does_not_force_flush_by_default(mock_span, mock_get_tracer_provider):
1093+
"""Test that ending a regular span does not force flush by default."""
1094+
tracer = Tracer()
1095+
mock_tracer_provider = mock_get_tracer_provider.return_value
1096+
1097+
tracer._end_span(mock_span)
1098+
1099+
mock_tracer_provider.force_flush.assert_not_called()
1100+
1101+
10921102
def test_force_flush_with_error(mock_span, mock_get_tracer_provider):
10931103
"""Test force flush with error handling."""
1094-
# Setup the tracer with a provider that raises an exception on force_flush
10951104
tracer = Tracer()
10961105

10971106
mock_tracer_provider = mock_get_tracer_provider.return_value
10981107
mock_tracer_provider.force_flush.side_effect = Exception("Force flush error")
10991108

11001109
# Should not raise an exception
1101-
tracer._end_span(mock_span)
1110+
tracer._end_span(mock_span, flush=True)
11021111

11031112
# Verify force_flush was called
11041113
mock_tracer_provider.force_flush.assert_called_once()
11051114

11061115

1116+
def test_end_agent_span_force_flushes(mock_span, mock_get_tracer_provider):
1117+
"""Test that ending an agent span forces a flush."""
1118+
tracer = Tracer()
1119+
mock_tracer_provider = mock_get_tracer_provider.return_value
1120+
1121+
tracer.end_agent_span(mock_span)
1122+
1123+
mock_tracer_provider.force_flush.assert_called_once()
1124+
1125+
11071126
def test_end_agent_span_with_empty_error_message_uses_exception_name(mock_span):
11081127
"""Test that agent spans fall back to the exception type name for empty errors."""
11091128
tracer = Tracer()

0 commit comments

Comments
 (0)