Skip to content
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
4516222
grpc support request/response size
crossoverJie Jul 16, 2024
e8f6b0e
fix ci
crossoverJie Jul 16, 2024
01a1bb0
fix ci
crossoverJie Jul 16, 2024
6121b30
fix ci
crossoverJie Jul 16, 2024
9680219
fix test
crossoverJie Jul 17, 2024
cce97f1
fix ci
crossoverJie Jul 17, 2024
22a791f
fix muzzle
crossoverJie Jul 17, 2024
c5c46dd
fix muzzle
crossoverJie Jul 17, 2024
d17a36c
fix muzzle
crossoverJie Jul 17, 2024
9f6055d
fix ci
crossoverJie Jul 17, 2024
b9f6cee
fix ci
crossoverJie Jul 17, 2024
fcc4468
fix ci
crossoverJie Jul 18, 2024
6dc7346
revert ci
crossoverJie Jul 18, 2024
9b350b4
revert ci
crossoverJie Jul 18, 2024
69ee2bd
fix muzzle
crossoverJie Jul 18, 2024
a10ffca
fix muzzle
crossoverJie Jul 18, 2024
e45c225
fix muzzle
crossoverJie Jul 18, 2024
bfe9087
fix muzzle
crossoverJie Jul 20, 2024
43054ad
use static import asList
crossoverJie Jul 22, 2024
1438a0a
fix with cr
crossoverJie Jul 24, 2024
063160f
remove client&server prefix.
crossoverJie Jul 31, 2024
d16cccf
fix tests
asweet-confluent Jul 28, 2025
4387287
Fix tests
asweet-confluent Jul 28, 2025
3cbfa5a
Merge branch 'main' into grpc-req-res-size
asweet-confluent Jul 28, 2025
484f0e8
Remove newlines
asweet-confluent Jul 28, 2025
d89492f
Merge remote-tracking branch 'origin/main' into grpc-req-res-size
asweet-confluent Aug 21, 2025
c88ae14
Remove message size trace attributes
asweet-confluent Aug 22, 2025
bc2abb0
./gradlew spotlessApply
otelbot[bot] Aug 22, 2025
337ea9d
Fix metrics tests
asweet-confluent Aug 22, 2025
b37fd07
./gradlew spotlessApply
otelbot[bot] Aug 22, 2025
cac3159
PR feedback
asweet-confluent Aug 29, 2025
f168f5f
PR feedback
asweet-confluent Aug 30, 2025
eb617be
fix failing test
laurit Sep 5, 2025
e1ec0f3
Merge branch 'main' into grpc-req-res-size
laurit Sep 17, 2025
4d63ab1
Merge branch 'main' into grpc-req-res-size
laurit Sep 17, 2025
2b966ec
Merge branch 'main' into grpc-req-res-size
laurit Sep 18, 2025
fef2b4f
Rpc size metrics
laurit Sep 18, 2025
0e0e2e1
fix latest dep test
laurit Sep 18, 2025
db98e02
use reflection to read the message size
laurit Sep 26, 2025
8a7ef80
Merge branch 'main' into grpc-req-res-size
laurit Sep 26, 2025
5db036f
revert change
laurit Sep 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Comparing source compatibility of opentelemetry-instrumentation-annotations-2.19.0-SNAPSHOT.jar against opentelemetry-instrumentation-annotations-2.18.1.jar
No changes.
No changes.
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Comparing source compatibility of opentelemetry-instrumentation-api-2.19.0-SNAPSHOT.jar against opentelemetry-instrumentation-api-2.18.1.jar
No changes.
No changes.
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Comparing source compatibility of opentelemetry-spring-boot-autoconfigure-2.19.0-SNAPSHOT.jar against opentelemetry-spring-boot-autoconfigure-2.18.1.jar
No changes.
No changes.
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Comparing source compatibility of opentelemetry-spring-boot-starter-2.19.0-SNAPSHOT.jar against opentelemetry-spring-boot-starter-2.18.1.jar
No changes.
No changes.
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,12 @@ public interface RpcAttributesGetter<REQUEST> {

@Nullable
String getMethod(REQUEST request);

default Long getRequestSize(REQUEST request) {
return null;
}

default Long getResponseSize(REQUEST request) {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.DoubleHistogram;
import io.opentelemetry.api.metrics.DoubleHistogramBuilder;
import io.opentelemetry.api.metrics.LongHistogram;
import io.opentelemetry.api.metrics.LongHistogramBuilder;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.ContextKey;
Expand All @@ -35,6 +37,8 @@ public final class RpcClientMetrics implements OperationListener {
private static final Logger logger = Logger.getLogger(RpcClientMetrics.class.getName());

private final DoubleHistogram clientDurationHistogram;
private final LongHistogram clientRequestSize;
private final LongHistogram clientResponseSize;

private RpcClientMetrics(Meter meter) {
DoubleHistogramBuilder durationBuilder =
Expand All @@ -44,6 +48,24 @@ private RpcClientMetrics(Meter meter) {
.setUnit("ms");
RpcMetricsAdvice.applyClientDurationAdvice(durationBuilder);
clientDurationHistogram = durationBuilder.build();

LongHistogramBuilder requestSizeBuilder =
meter
.histogramBuilder("rpc.client.request.size")
.setUnit("By")
.setDescription("Measures the size of RPC request messages (uncompressed).")
.ofLongs();
RpcMetricsAdvice.applyClientRequestSizeAdvice(requestSizeBuilder);
clientRequestSize = requestSizeBuilder.build();

LongHistogramBuilder responseSizeBuilder =
meter
.histogramBuilder("rpc.client.response.size")
.setUnit("By")
.setDescription("Measures the size of RPC response messages (uncompressed).")
.ofLongs();
RpcMetricsAdvice.applyClientRequestSizeAdvice(responseSizeBuilder);
clientResponseSize = responseSizeBuilder.build();
}

/**
Expand Down Expand Up @@ -72,10 +94,21 @@ public void onEnd(Context context, Attributes endAttributes, long endNanos) {
context);
return;
}
Attributes attributes = state.startAttributes().toBuilder().putAll(endAttributes).build();
clientDurationHistogram.record(
(endNanos - state.startTimeNanos()) / NANOS_PER_MS,
state.startAttributes().toBuilder().putAll(endAttributes).build(),
context);
(endNanos - state.startTimeNanos()) / NANOS_PER_MS, attributes, context);

Long rpcClientRequestBodySize =
RpcMessageBodySizeUtil.getRpcRequestBodySize(endAttributes, state.startAttributes());
if (rpcClientRequestBodySize != null) {
clientRequestSize.record(rpcClientRequestBodySize, attributes, context);
}

Long rpcClientResponseBodySize =
RpcMessageBodySizeUtil.getRpcResponseBodySize(endAttributes, state.startAttributes());
if (rpcClientResponseBodySize != null) {
clientResponseSize.record(rpcClientResponseBodySize, attributes, context);
}
}

@AutoValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ abstract class RpcCommonAttributesExtractor<REQUEST, RESPONSE>
static final AttributeKey<String> RPC_METHOD = AttributeKey.stringKey("rpc.method");
static final AttributeKey<String> RPC_SERVICE = AttributeKey.stringKey("rpc.service");
static final AttributeKey<String> RPC_SYSTEM = AttributeKey.stringKey("rpc.system");
static final AttributeKey<Long> RPC_REQUEST_BODY_SIZE =
AttributeKey.longKey("rpc.request.body.size");
static final AttributeKey<Long> RPC_RESPONSE_BODY_SIZE =
AttributeKey.longKey("rpc.response.body.size");

private final RpcAttributesGetter<REQUEST> getter;

Expand All @@ -41,6 +45,24 @@ public final void onEnd(
REQUEST request,
@Nullable RESPONSE response,
@Nullable Throwable error) {
// No response attributes
Long requestSize = getter.getRequestSize(request);
Long responseSize = getter.getResponseSize(request);
if (this instanceof RpcClientAttributesExtractor) {
if (requestSize != null) {
internalSet(attributes, RPC_REQUEST_BODY_SIZE, requestSize);
}
if (responseSize != null) {
internalSet(attributes, RPC_RESPONSE_BODY_SIZE, responseSize);
}
}

if (this instanceof RpcServerAttributesExtractor) {
if (requestSize != null) {
internalSet(attributes, RPC_REQUEST_BODY_SIZE, requestSize);
}
if (responseSize != null) {
internalSet(attributes, RPC_RESPONSE_BODY_SIZE, responseSize);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.api.incubator.semconv.rpc;

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import javax.annotation.Nullable;

final class RpcMessageBodySizeUtil {

@Nullable
static Long getRpcRequestBodySize(Attributes... attributesList) {
return getAttribute(RpcCommonAttributesExtractor.RPC_REQUEST_BODY_SIZE, attributesList);
}

@Nullable
static Long getRpcResponseBodySize(Attributes... attributesList) {
return getAttribute(RpcCommonAttributesExtractor.RPC_RESPONSE_BODY_SIZE, attributesList);
}

@Nullable
private static <T> T getAttribute(AttributeKey<T> key, Attributes... attributesList) {
for (Attributes attributes : attributesList) {
T value = attributes.get(key);
if (value != null) {
return value;
}
}
return null;
}

private RpcMessageBodySizeUtil() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,40 @@

package io.opentelemetry.instrumentation.api.incubator.semconv.rpc;

import static java.util.Arrays.asList;

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.incubator.metrics.ExtendedDoubleHistogramBuilder;
import io.opentelemetry.api.incubator.metrics.ExtendedLongHistogramBuilder;
import io.opentelemetry.api.metrics.DoubleHistogramBuilder;
import io.opentelemetry.api.metrics.LongHistogramBuilder;
import io.opentelemetry.semconv.NetworkAttributes;
import io.opentelemetry.semconv.ServerAttributes;
import java.util.Arrays;
import java.util.List;

final class RpcMetricsAdvice {

// copied from RpcIncubatingAttributes
private static final AttributeKey<Long> RPC_GRPC_STATUS_CODE =
AttributeKey.longKey("rpc.grpc.status_code");
private static final List<AttributeKey<?>> RPC_METRICS_ATTRIBUTE_KEYS =
asList(
RpcCommonAttributesExtractor.RPC_SYSTEM,
RpcCommonAttributesExtractor.RPC_SERVICE,
RpcCommonAttributesExtractor.RPC_METHOD,
RPC_GRPC_STATUS_CODE,
NetworkAttributes.NETWORK_TYPE,
NetworkAttributes.NETWORK_TRANSPORT,
ServerAttributes.SERVER_ADDRESS,
ServerAttributes.SERVER_PORT);

static void applyClientDurationAdvice(DoubleHistogramBuilder builder) {
if (!(builder instanceof ExtendedDoubleHistogramBuilder)) {
return;
}
// the list of recommended metrics attributes is from
// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/rpc-metrics.md
((ExtendedDoubleHistogramBuilder) builder)
.setAttributesAdvice(
Arrays.asList(
RpcCommonAttributesExtractor.RPC_SYSTEM,
RpcCommonAttributesExtractor.RPC_SERVICE,
RpcCommonAttributesExtractor.RPC_METHOD,
RPC_GRPC_STATUS_CODE,
NetworkAttributes.NETWORK_TYPE,
NetworkAttributes.NETWORK_TRANSPORT,
ServerAttributes.SERVER_ADDRESS,
ServerAttributes.SERVER_PORT));
((ExtendedDoubleHistogramBuilder) builder).setAttributesAdvice(RPC_METRICS_ATTRIBUTE_KEYS);
}

static void applyServerDurationAdvice(DoubleHistogramBuilder builder) {
Expand All @@ -43,17 +47,25 @@ static void applyServerDurationAdvice(DoubleHistogramBuilder builder) {
}
// the list of recommended metrics attributes is from
// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/rpc-metrics.md
((ExtendedDoubleHistogramBuilder) builder)
.setAttributesAdvice(
Arrays.asList(
RpcCommonAttributesExtractor.RPC_SYSTEM,
RpcCommonAttributesExtractor.RPC_SERVICE,
RpcCommonAttributesExtractor.RPC_METHOD,
RPC_GRPC_STATUS_CODE,
NetworkAttributes.NETWORK_TYPE,
NetworkAttributes.NETWORK_TRANSPORT,
ServerAttributes.SERVER_ADDRESS,
ServerAttributes.SERVER_PORT));
((ExtendedDoubleHistogramBuilder) builder).setAttributesAdvice(RPC_METRICS_ATTRIBUTE_KEYS);
}

static void applyClientRequestSizeAdvice(LongHistogramBuilder builder) {
if (!(builder instanceof ExtendedLongHistogramBuilder)) {
return;
}
// the list of recommended metrics attributes is from
// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/rpc-metrics.md
((ExtendedLongHistogramBuilder) builder).setAttributesAdvice(RPC_METRICS_ATTRIBUTE_KEYS);
}

static void applyServerRequestSizeAdvice(LongHistogramBuilder builder) {
if (!(builder instanceof ExtendedLongHistogramBuilder)) {
return;
}
// the list of recommended metrics attributes is from
// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/rpc-metrics.md
((ExtendedLongHistogramBuilder) builder).setAttributesAdvice(RPC_METRICS_ATTRIBUTE_KEYS);
}

private RpcMetricsAdvice() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.DoubleHistogram;
import io.opentelemetry.api.metrics.DoubleHistogramBuilder;
import io.opentelemetry.api.metrics.LongHistogram;
import io.opentelemetry.api.metrics.LongHistogramBuilder;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.ContextKey;
Expand All @@ -35,6 +37,8 @@ public final class RpcServerMetrics implements OperationListener {
private static final Logger logger = Logger.getLogger(RpcServerMetrics.class.getName());

private final DoubleHistogram serverDurationHistogram;
private final LongHistogram serverRequestSize;
private final LongHistogram serverResponseSize;

private RpcServerMetrics(Meter meter) {
DoubleHistogramBuilder durationBuilder =
Expand All @@ -44,6 +48,24 @@ private RpcServerMetrics(Meter meter) {
.setUnit("ms");
RpcMetricsAdvice.applyServerDurationAdvice(durationBuilder);
serverDurationHistogram = durationBuilder.build();

LongHistogramBuilder requestSizeBuilder =
meter
.histogramBuilder("rpc.server.request.size")
.setUnit("By")
.setDescription("Measures the size of RPC request messages (uncompressed).")
.ofLongs();
RpcMetricsAdvice.applyServerRequestSizeAdvice(requestSizeBuilder);
serverRequestSize = requestSizeBuilder.build();

LongHistogramBuilder responseSizeBuilder =
meter
.histogramBuilder("rpc.server.response.size")
.setUnit("By")
.setDescription("Measures the size of RPC response messages (uncompressed).")
.ofLongs();
RpcMetricsAdvice.applyServerRequestSizeAdvice(responseSizeBuilder);
serverResponseSize = responseSizeBuilder.build();
}

/**
Expand Down Expand Up @@ -72,10 +94,21 @@ public void onEnd(Context context, Attributes endAttributes, long endNanos) {
context);
return;
}
Attributes attributes = state.startAttributes().toBuilder().putAll(endAttributes).build();
serverDurationHistogram.record(
(endNanos - state.startTimeNanos()) / NANOS_PER_MS,
state.startAttributes().toBuilder().putAll(endAttributes).build(),
context);
(endNanos - state.startTimeNanos()) / NANOS_PER_MS, attributes, context);

Long rpcServerRequestBodySize =
RpcMessageBodySizeUtil.getRpcRequestBodySize(endAttributes, state.startAttributes());
if (rpcServerRequestBodySize != null) {
serverRequestSize.record(rpcServerRequestBodySize, attributes, context);
}

Long rpcServerResponseBodySize =
RpcMessageBodySizeUtil.getRpcResponseBodySize(endAttributes, state.startAttributes());
if (rpcServerResponseBodySize != null) {
serverResponseSize.record(rpcServerResponseBodySize, attributes, context);
}
}

@AutoValue
Expand Down
Loading
Loading