Skip to content

botocore: trace presigned URL generation#4096

Open
rite7sh wants to merge 6 commits intoopen-telemetry:mainfrom
rite7sh:botocore-presigned-url
Open

botocore: trace presigned URL generation#4096
rite7sh wants to merge 6 commits intoopen-telemetry:mainfrom
rite7sh:botocore-presigned-url

Conversation

@rite7sh
Copy link
Contributor

@rite7sh rite7sh commented Jan 10, 2026

Fixes #4040

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

  • Added a new unit test test_presigned_url_is_traced
  • Verified that a span named botocore.presigned_url is emitted when
    botocore.signers.RequestSigner.generate_presigned_url is invoked
    (e.g. via rds.generate_db_auth_token)

To reproduce:

pytest instrumentation/opentelemetry-instrumentation-botocore/tests/test_botocore_instrumentation.py -k presigned

@rite7sh
Copy link
Contributor Author

rite7sh commented Jan 11, 2026

Hey @xrmx , this PR implements tracing for RequestSigner.generate_presigned_url (incl. RDS IAM auth) as discussed in #4040.
Would love your review when you have a moment, thanks :)

@xrmx xrmx moved this to Ready for review in @xrmx's Python PR digest Jan 13, 2026
wrapped(*args, **kwargs)

try:
original = instance.generate_presigned_url
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be using hasattr or getattr here.

Comment on lines 187 to 191
wrap_function_wrapper(
"botocore.signers",
"RequestSigner.__init__",
self._patched_signer_init,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we not just do:

Suggested change
wrap_function_wrapper(
"botocore.signers",
"RequestSigner.__init__",
self._patched_signer_init,
)
wrap_function_wrapper(
"botocore.signers",
"RequestSigner.generate_presigned_url",
self._patched_generate_presigned_url,
)

tracer = get_tracer(__name__, __version__, self.tracer_provider)

with tracer.start_as_current_span("botocore.presigned_url") as span:
try:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This try-catch is unnecessary.

except Exception:
pass

return wrapped(*args, **kwargs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're just doing a direct pass through with this wrapper. I'd imagine we'd at least want to know the operation name and maybe the expiration time and region name.

@rite7sh
Copy link
Contributor Author

rite7sh commented Jan 13, 2026

gosh that makes sense :')
I’ll update this to wrap RequestSigner.generate_presigned_url directly, remove the try/except, and use getattr instead.
I’ll also add a few useful span attributes (like operation, expiry, region, etc.) so it’s not just a pass-through span. Will push a follow-up shortly.

@rite7sh
Copy link
Contributor Author

rite7sh commented Jan 14, 2026

@herin049 Addressed the review comments and pushed an update, hope this looks good now.

RPC_SYSTEM: "aws-api",
RPC_SERVICE: call_context.service_id,
RPC_METHOD: call_context.operation,
rpc_attributes.RPC_SYSTEM: "aws-api",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we touching this section of code at all in this PR, can we just revert these changes?

with tracer.start_as_current_span("botocore.presigned_url") as span:
if service := getattr(instance, "_service_id", None):
service = service.lower()
span.set_attribute(rpc_attributes.RPC_SERVICE, service)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove rpc_attributes. prefix

set_global_textmap(previous_propagator)

@mock_aws
@pytest.mark.skipif(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we adding this, the tests seemed to have been working fine before this change.

SERVER_ADDRESS,
SERVER_PORT,
)
from opentelemetry.semconv.trace import SpanAttributes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to make sure we don't reintroduce these deprecated attributes even in unit tests.

Copy link
Contributor Author

@rite7sh rite7sh Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@herin049 Thanks for the review I’ve reverted the unrelated changes, tightened the scope to just presigned URL tracing, and all tests pass locally now. Let me know if anything else needs tweaking , my bad for 'extra changes'.
let me know if anything else seems broken :).

@rite7sh rite7sh force-pushed the botocore-presigned-url branch from 83dfc96 to 6f45c4e Compare January 28, 2026 18:33
@rite7sh rite7sh requested a review from herin049 January 28, 2026 19:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Ready for review

Development

Successfully merging this pull request may close these issues.

Instrument botocore.signers.RequestSigner.generate_presigned_url

2 participants

Comments