From 056095b7572289a524bc487d09586a81fa3ee4ea Mon Sep 17 00:00:00 2001 From: Pablo Deputter Date: Tue, 13 Oct 2026 13:50:53 +0200 Subject: [PATCH 1/3] feat(names): Add span name and description rules for `object.*` ops The `object.*` ops have no name or description templates. Name them like AWS SDK calls: `{rpc.service}.{rpc.method}` (`S3.GetObject`). (to be merged after #706) --- .../sentry-conventions/src/attributes.ts | 16 +++++++++++- model/attributes/rpc/rpc__method.json | 9 ++++++- model/attributes/rpc/rpc__service.json | 9 ++++++- model/description/object.json | 23 +++++++++++++++++ model/name/object.json | 25 +++++++++++++++++++ python/src/sentry_conventions/attributes.py | 19 ++++++++++++++ 6 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 model/description/object.json create mode 100644 model/name/object.json diff --git a/javascript/sentry-conventions/src/attributes.ts b/javascript/sentry-conventions/src/attributes.ts index 644461a67..b85ef07f3 100644 --- a/javascript/sentry-conventions/src/attributes.ts +++ b/javascript/sentry-conventions/src/attributes.ts @@ -15555,6 +15555,7 @@ export type RPC_GRPC_STATUS_CODE_TYPE = number; * Aliases: {@link AWS_OPERATION_NAME} `aws.operation_name` * * @example "com.example.ExampleService/exampleMethod" + * @example "GetObject" */ export const RPC_METHOD = 'rpc.method'; @@ -15599,6 +15600,8 @@ export type RPC_RESPONSE_STATUS_CODE_TYPE = string; * Visibility: public * * @example "myService.BestService" + * @example "S3" + * @example "ApiGateway" */ export const RPC_SERVICE = 'rpc.service'; @@ -33808,11 +33811,14 @@ export const ATTRIBUTE_METADATA: Record = { isInOtel: true, visibility: 'public', example: 'com.example.ExampleService/exampleMethod', + examples: ['com.example.ExampleService/exampleMethod', 'GetObject'], aliases: ['aws.operation_name'], changelog: [ + { version: 'next', description: 'Added AWS SDK example and additional context' }, { version: '0.19.0', prs: [536], description: 'Added aws.operation_name as an alias' }, { version: '0.7.0', prs: [351], description: 'Added rpc.method attribute' }, ], + additionalContext: ['For AWS SDK calls, this is the operation name only, as the SDK reports it, e.g. `GetObject`.'], }, 'rpc.response.status_code': { brief: 'Status code of the RPC returned by the RPC server or generated by the client.', @@ -33840,7 +33846,15 @@ export const ATTRIBUTE_METADATA: Record = { isInOtel: true, visibility: 'public', example: 'myService.BestService', - changelog: [{ version: '0.1.0', prs: [127] }, { version: '0.0.0' }], + examples: ['myService.BestService', 'S3', 'ApiGateway'], + changelog: [ + { version: 'next', description: 'Added AWS SDK examples and additional context' }, + { version: '0.1.0', prs: [127] }, + { version: '0.0.0' }, + ], + additionalContext: [ + 'For AWS SDK calls, this is the AWS service ID with all whitespace removed (`S3`, `APIGateway` for `API Gateway`).', + ], }, 'rpc.system': { brief: 'A string identifying the remoting system.', diff --git a/model/attributes/rpc/rpc__method.json b/model/attributes/rpc/rpc__method.json index 788843c98..5b867fec9 100644 --- a/model/attributes/rpc/rpc__method.json +++ b/model/attributes/rpc/rpc__method.json @@ -1,15 +1,22 @@ { "key": "rpc.method", "brief": "The fully-qualified logical name of the method from the RPC interface perspective.", + "additional_context": [ + "For AWS SDK calls, this is the operation name only, as the SDK reports it, e.g. `GetObject`." + ], "type": "string", "apply_scrubbing": { "key": "manual" }, "is_in_otel": true, - "example": "com.example.ExampleService/exampleMethod", + "examples": ["com.example.ExampleService/exampleMethod", "GetObject"], "visibility": "public", "alias": ["aws.operation_name"], "changelog": [ + { + "version": "next", + "description": "Added AWS SDK example and additional context" + }, { "version": "0.19.0", "prs": [536], diff --git a/model/attributes/rpc/rpc__service.json b/model/attributes/rpc/rpc__service.json index 5fa34caf5..db7372697 100644 --- a/model/attributes/rpc/rpc__service.json +++ b/model/attributes/rpc/rpc__service.json @@ -1,14 +1,21 @@ { "key": "rpc.service", "brief": "The full (logical) name of the service being called, including its package name, if applicable.", + "additional_context": [ + "For AWS SDK calls, this is the AWS service ID with all whitespace removed (`S3`, `APIGateway` for `API Gateway`)." + ], "type": "string", "apply_scrubbing": { "key": "manual" }, "is_in_otel": true, - "example": "myService.BestService", + "examples": ["myService.BestService", "S3", "ApiGateway"], "visibility": "public", "changelog": [ + { + "version": "next", + "description": "Added AWS SDK examples and additional context" + }, { "version": "0.1.0", "prs": [127] diff --git a/model/description/object.json b/model/description/object.json new file mode 100644 index 000000000..56b607fcc --- /dev/null +++ b/model/description/object.json @@ -0,0 +1,23 @@ +{ + "brief": "Object storage", + "operations": [ + { + "name": "Object", + "brief": "An operation on an object storage system such as Cloudflare R2, Amazon S3, and compatible services.", + "ops": [ + "object.get", + "object.head", + "object.put", + "object.copy", + "object.delete", + "object.list", + "object.upload_part", + "object.multipart_upload.abort", + "object.multipart_upload.create", + "object.multipart_upload.complete" + ], + "templates": ["{{aws.s3.bucket}}", "{{cloudflare.r2.bucket}}"], + "examples": ["invoices", "MY_BUCKET"] + } + ] +} diff --git a/model/name/object.json b/model/name/object.json new file mode 100644 index 000000000..34a345185 --- /dev/null +++ b/model/name/object.json @@ -0,0 +1,25 @@ +{ + "brief": "Object storage", + "operations": [ + { + "name": "Object", + "brief": "An operation on an object storage system such as Amazon S3, Cloudflare R2, and compatible services.", + "is_in_otel": true, + "otel_notes": "OpenTelemetry has no Object Storage conventions. It names S3 calls like any other AWS SDK span, `{rpc.service}.{rpc.method}`, which the first template matches.", + "ops": [ + "object.get", + "object.head", + "object.put", + "object.copy", + "object.delete", + "object.list", + "object.upload_part", + "object.multipart_upload.abort", + "object.multipart_upload.create", + "object.multipart_upload.complete" + ], + "templates": ["{{rpc.service}}.{{rpc.method}}", "R2.{{cloudflare.r2.operation}}", "Object storage operation"], + "examples": ["S3.GetObject", "R2.GetObject", "Object storage operation"] + } + ] +} diff --git a/python/src/sentry_conventions/attributes.py b/python/src/sentry_conventions/attributes.py index 6b1f9e863..b29a769fe 100644 --- a/python/src/sentry_conventions/attributes.py +++ b/python/src/sentry_conventions/attributes.py @@ -9251,6 +9251,7 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): Visibility: public Aliases: aws.operation_name Example: "com.example.ExampleService/exampleMethod" + Example: "GetObject" """ # Path: model/attributes/rpc/rpc__response__status_code.json @@ -9276,6 +9277,8 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): Defined in OTEL: Yes Visibility: public Example: "myService.BestService" + Example: "S3" + Example: "ApiGateway" """ # Path: model/attributes/rpc/rpc__system.json @@ -25461,8 +25464,13 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): is_in_otel=True, visibility=Visibility.PUBLIC, example="com.example.ExampleService/exampleMethod", + examples=["com.example.ExampleService/exampleMethod", "GetObject"], aliases=["aws.operation_name"], changelog=[ + ChangelogEntry( + version="next", + description="Added AWS SDK example and additional context", + ), ChangelogEntry( version="0.19.0", prs=[536], @@ -25472,6 +25480,9 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): version="0.7.0", prs=[351], description="Added rpc.method attribute" ), ], + additional_context=[ + "For AWS SDK calls, this is the operation name only, as the SDK reports it, e.g. `GetObject`." + ], ), "rpc.response.status_code": AttributeMetadata( brief="Status code of the RPC returned by the RPC server or generated by the client.", @@ -25506,10 +25517,18 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): is_in_otel=True, visibility=Visibility.PUBLIC, example="myService.BestService", + examples=["myService.BestService", "S3", "ApiGateway"], changelog=[ + ChangelogEntry( + version="next", + description="Added AWS SDK examples and additional context", + ), ChangelogEntry(version="0.1.0", prs=[127]), ChangelogEntry(version="0.0.0"), ], + additional_context=[ + "For AWS SDK calls, this is the AWS service ID with all whitespace removed (`S3`, `APIGateway` for `API Gateway`)." + ], ), "rpc.system": AttributeMetadata( brief="A string identifying the remoting system.", From 54885354899f0721bf4d960cf375f98b42eae044 Mon Sep 17 00:00:00 2001 From: Pablo Deputter Date: Tue, 13 Oct 2026 14:21:17 +0200 Subject: [PATCH 2/3] . --- model/description/object.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/model/description/object.json b/model/description/object.json index 56b607fcc..a1b550dc3 100644 --- a/model/description/object.json +++ b/model/description/object.json @@ -16,8 +16,11 @@ "object.multipart_upload.create", "object.multipart_upload.complete" ], - "templates": ["{{aws.s3.bucket}}", "{{cloudflare.r2.bucket}}"], - "examples": ["invoices", "MY_BUCKET"] + "templates": [ + "{{rpc.service}}.{{rpc.method}} {{aws.s3.bucket}}", + "R2.{{cloudflare.r2.operation}} {{cloudflare.r2.bucket}}" + ], + "examples": ["S3.GetObject invoices", "S3.DeleteObjects invoices", "R2.GetObject MY_BUCKET"] } ] } From 6b3b06471c2c5186c29cc304e990bbb2e04d7c6e Mon Sep 17 00:00:00 2001 From: Pablo Deputter Date: Wed, 14 Oct 2026 10:35:09 +0200 Subject: [PATCH 3/3] fix(names): faulty example "Apigateway" -> "APIGateway" --- javascript/sentry-conventions/src/attributes.ts | 4 ++-- model/attributes/rpc/rpc__service.json | 2 +- python/src/sentry_conventions/attributes.py | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/javascript/sentry-conventions/src/attributes.ts b/javascript/sentry-conventions/src/attributes.ts index b85ef07f3..6696e517c 100644 --- a/javascript/sentry-conventions/src/attributes.ts +++ b/javascript/sentry-conventions/src/attributes.ts @@ -15601,7 +15601,7 @@ export type RPC_RESPONSE_STATUS_CODE_TYPE = string; * * @example "myService.BestService" * @example "S3" - * @example "ApiGateway" + * @example "APIGateway" */ export const RPC_SERVICE = 'rpc.service'; @@ -33846,7 +33846,7 @@ export const ATTRIBUTE_METADATA: Record = { isInOtel: true, visibility: 'public', example: 'myService.BestService', - examples: ['myService.BestService', 'S3', 'ApiGateway'], + examples: ['myService.BestService', 'S3', 'APIGateway'], changelog: [ { version: 'next', description: 'Added AWS SDK examples and additional context' }, { version: '0.1.0', prs: [127] }, diff --git a/model/attributes/rpc/rpc__service.json b/model/attributes/rpc/rpc__service.json index db7372697..d01456b3b 100644 --- a/model/attributes/rpc/rpc__service.json +++ b/model/attributes/rpc/rpc__service.json @@ -9,7 +9,7 @@ "key": "manual" }, "is_in_otel": true, - "examples": ["myService.BestService", "S3", "ApiGateway"], + "examples": ["myService.BestService", "S3", "APIGateway"], "visibility": "public", "changelog": [ { diff --git a/python/src/sentry_conventions/attributes.py b/python/src/sentry_conventions/attributes.py index b29a769fe..e65d324d8 100644 --- a/python/src/sentry_conventions/attributes.py +++ b/python/src/sentry_conventions/attributes.py @@ -9278,7 +9278,7 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): Visibility: public Example: "myService.BestService" Example: "S3" - Example: "ApiGateway" + Example: "APIGateway" """ # Path: model/attributes/rpc/rpc__system.json @@ -25517,7 +25517,7 @@ class ATTRIBUTE_NAMES(metaclass=_AttributeNamesMeta): is_in_otel=True, visibility=Visibility.PUBLIC, example="myService.BestService", - examples=["myService.BestService", "S3", "ApiGateway"], + examples=["myService.BestService", "S3", "APIGateway"], changelog=[ ChangelogEntry( version="next",