Skip to content
1 change: 1 addition & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ endif::[]
* Implement instrumentation of Azure Functions {pull}1766[#1766]
* Add support for Django to wrapper script {pull}1780[#1780]
* Add `transport_json_serializer` configuration option {pull}1777[#1777]
* Add S3 bucket and key name to OTel attributes {pull}1790[#1790]

[float]
===== Bug fixes
Expand Down
12 changes: 10 additions & 2 deletions elasticapm/instrumentation/packages/botocore.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,19 @@ def handle_s3(operation_name, service, instance, args, kwargs, context):
span_type = "storage"
span_subtype = "s3"
span_action = operation_name
if len(args) > 1 and "Bucket" in args[1]:
bucket = args[1]["Bucket"]
if len(args) > 1:
bucket = args[1].get("Bucket", "")
key = args[1].get("Key", "")
else:
# TODO handle Access Points
bucket = ""
key = ""
if bucket or key:
context["otel_attributes"] = {}
if bucket:
context["otel_attributes"]["aws.s3.bucket"] = bucket
if key:
context["otel_attributes"]["aws.s3.key"] = key
signature = f"S3 {operation_name} {bucket}"

context["destination"]["service"] = {"name": span_subtype, "resource": f"s3/{bucket}", "type": span_type}
Expand Down
2 changes: 2 additions & 0 deletions tests/instrumentation/botocore_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ def test_s3(instrument, elasticapm_client):
assert spans[0]["action"] == "CreateBucket"
assert spans[1]["name"] == "S3 PutObject xyz"
assert spans[1]["action"] == "PutObject"
assert spans[1]["otel"]["attributes"]["aws.s3.bucket"] == "xyz"
assert spans[1]["otel"]["attributes"]["aws.s3.key"] == "abc"
assert spans[2]["name"] == "S3 ListObjects xyz"
assert spans[2]["action"] == "ListObjects"

Expand Down