Skip to content

Conversation

asweet-confluent
Copy link

Adds rpc.request.body.size and rpc.response.body.size attributes. This is just an updated version of #11833.

@asweet-confluent asweet-confluent requested a review from a team as a code owner July 28, 2025 05:46
Comment on lines 239 to 240
equalTo(RPC_RESPONSE_BODY_SIZE, requestSerializedSize),
equalTo(RPC_REQUEST_BODY_SIZE, requestSerializedSize),
Copy link
Author

Choose a reason for hiding this comment

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

Does anyone know why the server spans are using request size for rpc.response.body.size and response size for rpc.request.body.size? This is how the original PR was written.

CC @crossoverJie

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, I'm not really sure about the specific reasons, you can check the commit history of this repo.

However, the previous PR was blocked by this PR, maybe it can be re-pushed.

Copy link
Member

Choose a reason for hiding this comment

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

out of curiosity, are the two of you working together on this? I just want to understand why we have two PRs for the same thing and make sure we're all on the same page. I think the reason the other PR stalled is because there were some open questions about semantic conventions, and as @crossoverJie said we might need to revisit and push on that before we can move forward with this.

Copy link
Author

Choose a reason for hiding this comment

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

are the two of you working together on this?

No, the other PR is just very out of date I and I wanted to get this done so I rebased it myself. I assumed it was abandoned :)

I think the reason the other PR stalled is because there were some open questions about semantic conventions, and as @crossoverJie said we might need to revisit and push on that before we can move forward with this.

AFAIK these are already in the semantic conventions:

Copy link
Contributor

Choose a reason for hiding this comment

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

AFAIK these are already in the semantic conventions

What you have in the semantic conventions is rpc.server.request.size, rpc.server.response.size, rpc.client.request.size and rpc.client.response.size metrics. Semantic conventions don't seem to define the span attributes rpc.request.body.size and rpc.response.body.size. Either these attributes would need to be added to semantic conventions or the api that is used to produce the metrics would need to be changed so that it could include values that are not span attributes. Our convention is not to emit telemetry that is not in the spec in default configuration.
To me

                                    equalTo(RPC_RESPONSE_BODY_SIZE, requestSerializedSize),
                                    equalTo(RPC_REQUEST_BODY_SIZE, requestSerializedSize)

looks like a bug since both the request and response size are the same.

Copy link
Author

Choose a reason for hiding this comment

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

Got it - how about I rip out the code for trace attributes and just leave the metrics?

@asweet-confluent
Copy link
Author

@jaydeluca looks like the failing tests are dead links unrelated to these changes. I'm still unsure of this though.

@otelbot-java-instrumentation
Copy link
Contributor

🔧 The result from spotlessApply was committed to the PR branch.

@otelbot-java-instrumentation
Copy link
Contributor

🔧 The result from spotlessApply was committed to the PR branch.

@asweet-confluent
Copy link
Author

@laurit @jaydeluca I removed the payload size attributes from the traces so we're just left with the metrics. The original implementation worked by adding the attributes to the traces, then using those attributes to record the metrics. It looks like there's no straightforward way for a OperationMetrics to access the requests directly, so I ended up using a context customizer to store the payload size and access it in the Rpc*Metrics classes. Let me know if there's a better approach to this; I had a hard time understanding all the different abstractions at play.

point ->
point
.hasSum(20 /* bytes */)
.hasAttributesSatisfying(
Copy link
Member

Choose a reason for hiding this comment

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

Unless there is a reason not to (for example, many unrelated attributes we don't necessarily care about), we typically use the more stricter assertion

Suggested change
.hasAttributesSatisfying(
.hasAttributesSatisfyingExactly(

import io.opentelemetry.context.ImplicitContextKeyed;
import javax.annotation.Nullable;

public class RpcMetricsHolder implements ImplicitContextKeyed {
Copy link
Contributor

@laurit laurit Sep 4, 2025

Choose a reason for hiding this comment

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

@trask an alternative would be to introduce an OperationAttributeExtractor we could call into it in

UnsafeAttributes attributes = new UnsafeAttributes();
for (AttributesExtractor<? super REQUEST, ? super RESPONSE> extractor : attributesExtractors) {
extractor.onEnd(attributes, context, request, response, error);
}
span.setAllAttributes(attributes);
OperationListener[] operationListeners = context.get(START_OPERATION_LISTENERS);
after the span attributes. We could merge the attributes from onEnd with the ones from OperationAttributeExtractor and pass them to the OperationListener. WDYT?

@trask
Copy link
Member

trask commented Sep 5, 2025

@laurit @jaydeluca I removed the payload size attributes from the traces so we're just left with the metrics. The original implementation worked by adding the attributes to the traces, then using those attributes to record the metrics. It looks like there's no straightforward way for a OperationMetrics to access the requests directly, so I ended up using a context customizer to store the payload size and access it in the Rpc*Metrics classes. Let me know if there's a better approach to this; I had a hard time understanding all the different abstractions at play.

given the complexity this introduces, what about making both the body size span attributes and body size metrics opt-in?

the RPC semconv stability SIG just kicked off yesterday. I suspect we'll get the body size span attribute into RPC semconv, but I also suspect that both it and the body size metrics will remain experimental when RPC semconv initially goes stable (similar to the state of body size span attributes and metrics in HTTP). So both of them will probably need to be opt-in anyways at some point in the future when this repo adopts the first stable RPC semconv release.

@asweet-confluent
Copy link
Author

asweet-confluent commented Sep 11, 2025

given the complexity this introduces, what about making both the body size span attributes and body size metrics opt-in?

If you're suggesting going back to the original implementation:

adding the attributes to the traces, then using those attributes to record the metrics

Doesn't that mean that enabling the metrics will require enabling the span attributes? Or we'd have to add the span attributes, conditionally generate the metrics from the span attributes, then conditionally remove the span attributes after.

@laurit
Copy link
Contributor

laurit commented Sep 18, 2025

@asweet-confluent I update this PR to use an experimental API that allows adding attributes that are used just for operation listeners.

@laurit laurit added this to the v2.21.0 milestone Sep 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants