Skip to content

AWS SDK instrumentation: HTTP POST body included in Span http.url #8956

@semonte

Description

@semonte

AWS SDK may use query parameters to populate an AWS SDK request's data. For example, the SesAsyncClient's sendEmail method adds various email attributes as query parameters (e.g. email subject and email body) using the QueryProtocolMarshaller. Before dispatching the actual HTTP request the AWS SDK moves the query parameters to HTTP body using the QueryParametersToBodyInterceptor. Thus, the initial query parameter data is included in the POST body instead of the URL in the end.

This has an undesirable side effect with the OpenTelementry agent. The instrumented AWS SDK calls the SdkHttpRequest getUri method, which returns the initial query parameters, to populate a Span's http.url attribute. This results in Spans that include email content and other POST body data in the http.url attribute.

Steps to reproduce
The issue can be reproduced by running the following code with OpenTelemetry Java agent.

final SesAsyncClient sesAsyncClient = SesAsyncClient.builder().build();

final SendEmailRequest request = SendEmailRequest
    .builder()
    .message(
        Message
            .builder()
            .subject(Content.builder().data("test subject").build())
            .body(Body.builder().text(Content.builder().data("test text").build()).build())
            .build()
    )
    .build();

sesAsyncClient.sendEmail(request).get();

Observe that the http.url attribute has the following value:

https://email.us-east-1.amazonaws.com?Action=SendEmail&Version=2010-12-01&Message.Subject.Data=test%20subject&Message.Body.Text.Data=test%20text

What did you expect to see?
The span to contain http.url with value https://email.us-east-1.amazonaws.com.

What did you see instead?
The Span's http.url containing value https://email.us-east-1.amazonaws.com?Action=SendEmail&Version=2010-12-01&Message.Subject.Data=test%20subject&Message.Body.Text.Data=test%20text

I propose that an additional check is added in AWS SDK instrumentation when the request URL is resolved.

@Override
public String getUrl(ExecutionAttributes request) {
    SdkHttpRequest httpRequest = request.getAttribute(TracingExecutionInterceptor.SDK_HTTP_REQUEST_ATTRIBUTE);
    
    if (queryParametersMovedToBody(request)) {
        return stripQueryParameters(httpRequest.getUri()).toString();
    }
    
    return httpRequest.getUri().toString();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions