fix: restore explicit span.end() to fix span end_time regression#2032
Merged
zastrowm merged 2 commits intostrands-agents:mainfrom Apr 1, 2026
Merged
fix: restore explicit span.end() to fix span end_time regression#2032zastrowm merged 2 commits intostrands-agents:mainfrom
zastrowm merged 2 commits intostrands-agents:mainfrom
Conversation
PR strands-agents#1293 wrapped event_loop_cycle() in use_span(end_on_exit=True) and removed explicit span.end() calls. Because event_loop_cycle is an async generator, yield keeps the context manager open across recursive cycles, causing all execute_event_loop_cycle spans to share the same OTel end_time. Switch to end_on_exit=False and explicitly call span.end() via _end_span() in end_event_loop_cycle_span() and end_model_invoke_span(), restoring end_span_with_error() in all exception paths.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Review SummaryAssessment: Approve ✅ This PR correctly fixes the OTel span timing regression by switching from Review Notes
All 112 tests pass. Clean fix that resolves the regression correctly. |
lizradway
previously approved these changes
Apr 1, 2026
lizradway
approved these changes
Apr 1, 2026
Member
Author
This was referenced Apr 1, 2026
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Since v1.24.0 (PR #1293),
execute_event_loop_cyclespans no longer reflect per-cycle duration. When a cycle performs tool use and recurses, the parent cycle's OTel span stays open until all recursive children complete, producing cumulative bottom-up latency instead of per-step latency in observability backends (Langfuse, Jaeger, etc.).The root cause:
event_loop_cycle()is an async generator whose body was wrapped inuse_span(end_on_exit=True). Becauseyieldkeeps the context manager open across recursive cycles, allspan.end()calls fire simultaneously when the generator chain unwinds.This is a cherry-pick of the first commit from #1939 (by @Di-Is), isolated to the core span timing fix.
The fix switches to
end_on_exit=Falseand restores explicitspan.end()calls via_end_span()inend_event_loop_cycle_span()andend_model_invoke_span(), withend_span_with_error()on all exception paths.Related Issues
Resolves #1930
Documentation PR
N/A
Type of Change
Bug fix
Testing
hatch run prepareChecklist
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.