From ea40d98ee8868132914e7259d903d48c212b50a1 Mon Sep 17 00:00:00 2001 From: Pablo Deputter Date: Thu, 1 Oct 2026 10:38:40 +0200 Subject: [PATCH] feat(boto3): align span names with OTel conventions - use modeled `ServiceID` and operation for span names: `aws..` to `.`; e.g. `aws.s3.GetObject` => `S3.GetObject` --- .../integrations/boto3/_instrumentation.py | 7 +++---- tests/integrations/boto3/test_client.py | 19 +++++++++++++++---- tests/integrations/boto3/test_s3.py | 10 +++++----- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/sentry_sdk/integrations/boto3/_instrumentation.py b/sentry_sdk/integrations/boto3/_instrumentation.py index 4438921326..b56540e5bb 100644 --- a/sentry_sdk/integrations/boto3/_instrumentation.py +++ b/sentry_sdk/integrations/boto3/_instrumentation.py @@ -152,10 +152,9 @@ def _start_client_span( if sentry_sdk.get_current_span() is None: return None - # use "unknown" if `service_id_hyphenized` is not set so span name can still be created. - # e.g. "aws.unknown.GetObject" - service_name = ctx.service_id_hyphenized or "unknown" - span_name = f"aws.{service_name}.{ctx.operation_name}" + # https://opentelemetry.io/docs/specs/semconv/cloud-providers/aws-sdk/#aws-sdk-spans + service_name = ctx.service_id or "unknown" + span_name = f"{service_name}.{ctx.operation_name}" attributes: "Attributes" = { SPANDATA.RPC_METHOD: ctx.operation_name, SPANDATA.RPC_SYSTEM_NAME: AWS_RPC_SYSTEM_NAME, diff --git a/tests/integrations/boto3/test_client.py b/tests/integrations/boto3/test_client.py index 8c0c2aac90..9d20c192ca 100644 --- a/tests/integrations/boto3/test_client.py +++ b/tests/integrations/boto3/test_client.py @@ -123,7 +123,7 @@ def record_client_span(request, **kwargs): client_spans = [ span for span in spans - if span["name"] == "aws.s3.GetObject" + if span["name"] == "S3.GetObject" and ( span["attributes"].get(SPANDATA.SENTRY_ORIGIN) == ORIGIN and span["attributes"].get(SPANDATA.SENTRY_OP) == OP.HTTP_CLIENT @@ -139,7 +139,7 @@ def record_client_span(request, **kwargs): stream_spans = [ span for span in spans - if span["name"] == "aws.s3.GetObject" + if span["name"] == "S3.GetObject" and (span["attributes"].get(SPANDATA.SENTRY_OP) == OP.HTTP_CLIENT_STREAM) ] assert len(client_spans) == 1 @@ -366,7 +366,7 @@ def get_response_attributes(self, ctx, response): "s3", "head_object", {"Bucket": "bucket", "Key": "foo"}, - "aws.s3.HeadObject", + "S3.HeadObject", "S3", "HeadObject", "http://localhost:4566", @@ -377,13 +377,24 @@ def get_response_attributes(self, ctx, response): "events", "list_event_buses", {}, - "aws.eventbridge.ListEventBuses", + "EventBridge.ListEventBuses", "EventBridge", "ListEventBuses", None, "events.eu-north-1.amazonaws.com", 443, ), + ( + "apigateway", + "get_rest_apis", + {}, + "API Gateway.GetRestApis", + "API Gateway", + "GetRestApis", + None, + "apigateway.eu-north-1.amazonaws.com", + 443, + ), ], ) def test_client_call_has_common_attributes( diff --git a/tests/integrations/boto3/test_s3.py b/tests/integrations/boto3/test_s3.py index 60dcbd8403..aefdf360b0 100644 --- a/tests/integrations/boto3/test_s3.py +++ b/tests/integrations/boto3/test_s3.py @@ -48,7 +48,7 @@ def test_basic( assert len(spans) == 2 span = spans[0] assert span["attributes"]["sentry.op"] == "http.client" - assert span["name"] == "aws.s3.ListObjects" + assert span["name"] == "S3.ListObjects" def test_streaming(sentry_init, capture_items): @@ -79,11 +79,11 @@ def test_streaming(sentry_init, capture_items): stream_span, client_span, parent_span = spans assert stream_span["attributes"]["sentry.op"] == "http.client.stream" - assert stream_span["name"] == "aws.s3.GetObject" + assert stream_span["name"] == "S3.GetObject" assert stream_span["parent_span_id"] == client_span["span_id"] assert client_span["attributes"]["sentry.op"] == "http.client" - assert client_span["name"] == "aws.s3.GetObject" + assert client_span["name"] == "S3.GetObject" assert client_span["parent_span_id"] == parent_span["span_id"] assert parent_span["name"] == "custom parent" @@ -137,11 +137,11 @@ def test_streaming_close(sentry_init, capture_items): stream_span, client_span, parent_span = spans assert stream_span["attributes"]["sentry.op"] == "http.client.stream" - assert stream_span["name"] == "aws.s3.GetObject" + assert stream_span["name"] == "S3.GetObject" assert stream_span["parent_span_id"] == client_span["span_id"] assert client_span["attributes"]["sentry.op"] == "http.client" - assert client_span["name"] == "aws.s3.GetObject" + assert client_span["name"] == "S3.GetObject" assert client_span["parent_span_id"] == parent_span["span_id"] assert parent_span["name"] == "custom parent"