feat(boto3): trace logical AWS calls with common attributes - #7481
feat(boto3): trace logical AWS calls with common attributes#7481pabloDeputter wants to merge 12 commits into
Conversation
- wrapper owns a single botocore client-call lifecycle. - introduce service-extension architecture. - add generic response, retry, and error attributes. - add common attributes that are the same across services.
…an naming and `rpc.service` and `parse_url` patch target
…st.resend_count`
Codecov Results 📊✅ 126821 passed | ⏭️ 7148 skipped | Total: 133969 | Pass Rate: 94.66% | Execution Time: 432m 12s 📊 Comparison with Base Branch
All tests are passing successfully. ✅ Patch coverage is 95.74%. Project has 2537 uncovered lines. Files with missing lines (2)
Coverage diff@@ Coverage Diff @@
## master #PR +/-##
==========================================
+ Coverage 90.18% 90.20% +0.02%
==========================================
Files 193 196 +3
Lines 25790 25893 +103
Branches 9532 9562 +30
==========================================
+ Hits 23258 23356 +98
- Misses 2532 2537 +5
- Partials 1432 1447 +15Generated by Codecov Action |
…er attributes; remove direct testing of `_get_server_attributes`
| streaming_span = sentry_sdk.traces.start_span( | ||
| name=span.name, | ||
| parent_span=span, | ||
| attributes={ | ||
| SPANDATA.SENTRY_OP: OP.HTTP_CLIENT_STREAM, | ||
| SPANDATA.SENTRY_ORIGIN: Boto3Integration.origin, | ||
| }, | ||
| ) |
There was a problem hiding this comment.
Streaming body span remains active after the client call returns
The streaming span is created with the default active=True, so it replaces the current streamed span after the client span has ended and remains active until the response body is fully read or closed. Instrumented work performed in the same scope while the StreamingBody remains open can therefore be incorrectly parented under http.client.stream. Create this span with active=False unless that parenting is intentional.
Evidence
_finish_client_span()ends the client span before creating the streaming span withparent_span=span.traces.start_span()defaultsactive=True, andStreamedSpan._start()stores the new span inscope.streamed_span.- The streaming span is only removed from the scope by the wrapped body
read()reaching EOF, an exception, orclose(). - The legacy path uses
span.start_child()without activating the child, so this scope replacement is specific to span-streaming mode.
Identified by Warden · code-review · ERE-FHG
| except Exception: | ||
| if isinstance(streaming_span, StreamedSpan): | ||
| streaming_span.end() | ||
| else: | ||
| streaming_span.finish() | ||
| raise |
There was a problem hiding this comment.
Streaming-trace body read failures finish the stream span as successful
When span streaming is enabled, a body read exception ends the StreamedSpan through end(), leaving its default ok status. Invoke __exit__(type(exc), exc, exc.__traceback__) or set an error status before ending the span so failed body reads are recorded as errors.
Evidence
_finish_client_span()wrapsStreamingBody.readand catches body-read exceptions insentry_streaming_body_read().- On the exception path,
StreamedSpan.end()is called without the exception;StreamedSpaninitializes its status took, while only__exit__changes it toerror. _finish_client_span_with_error()demonstrates the existing error-aware pattern by callingspan.__exit__(type(exception), exception, exception.__traceback__).test_streaming_body_read_failure_finishes_stream_spanverifies completion but not the stream span status.
Also found at 1 additional location
tests/integrations/boto3/test_client.py:360-400
Identified by Warden · code-review · ZSA-X6F
| RPC_SYSTEM_NAME = "rpc.system.name" | ||
| """ | ||
| A string identifying the remoting system. | ||
| Example: "aws-api" | ||
| """ | ||
|
|
There was a problem hiding this comment.
RPC_SYSTEM_NAME uses non-standard attribute key rpc.system.name
Use rpc.system (OTEL AWS SDK / RPC semconv), not rpc.system.name; otherwise AWS spans emit a non-standard attribute backends won't recognize.
Evidence
- Hunk defines
RPC_SYSTEM_NAME = "rpc.system.name". _get_client_attributes()insentry_sdk/integrations/boto3/_instrumentation.pysetsSPANDATA.RPC_SYSTEM_NAMEto"aws-api"on every client span.- OTEL AWS SDK spans require
rpc.system=aws-api(same docs linked in that helper); RPC conventions userpc.system, unlike DB'sdb.system.name. - Tests assert the constant value only, so the wrong key is not caught.
Identified by Warden · find-bugs · VD7-M84
Description
Implements #7474 and #7475 by moving boto3 instrumentation from individual HTTP request attempts to botocore client-call lifecycle and adding common OTel AWS attributes.
...
Issues
Resolves #7474 & #7475