Skip to content

Implement otel retry metrics #12064

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
32 changes: 29 additions & 3 deletions api/src/main/java/io/grpc/ClientStreamTracer.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,15 @@
private final CallOptions callOptions;
private final int previousAttempts;
private final boolean isTransparentRetry;
private final boolean isHedging;

StreamInfo(
CallOptions callOptions, int previousAttempts, boolean isTransparentRetry) {
CallOptions callOptions, int previousAttempts, boolean isTransparentRetry,
boolean isHedging) {
this.callOptions = checkNotNull(callOptions, "callOptions");
this.previousAttempts = previousAttempts;
this.isTransparentRetry = isTransparentRetry;
this.isHedging = isHedging;
}

/**
Expand Down Expand Up @@ -165,6 +168,15 @@
return isTransparentRetry;
}

/**
* Whether the stream is hedging.
*
* @since 1.74.0
*/
public boolean isHedging() {
return isHedging;
}

/**
* Converts this StreamInfo into a new Builder.
*
Expand All @@ -174,7 +186,9 @@
return new Builder()
.setCallOptions(callOptions)
.setPreviousAttempts(previousAttempts)
.setIsTransparentRetry(isTransparentRetry);
.setIsTransparentRetry(isTransparentRetry)
.setIsHedging(isHedging);

}

/**
Expand All @@ -192,6 +206,7 @@
.add("callOptions", callOptions)
.add("previousAttempts", previousAttempts)
.add("isTransparentRetry", isTransparentRetry)
.add("isHedging", isHedging)

Check warning on line 209 in api/src/main/java/io/grpc/ClientStreamTracer.java

View check run for this annotation

Codecov / codecov/patch

api/src/main/java/io/grpc/ClientStreamTracer.java#L209

Added line #L209 was not covered by tests
.toString();
}

Expand All @@ -204,6 +219,7 @@
private CallOptions callOptions = CallOptions.DEFAULT;
private int previousAttempts;
private boolean isTransparentRetry;
private boolean isHedging;

Builder() {
}
Expand Down Expand Up @@ -236,11 +252,21 @@
return this;
}

/**
* Sets whether the stream is hedging.
*
* @since 1.74.0
*/
public Builder setIsHedging(boolean isHedging) {
this.isHedging = isHedging;
return this;
}

/**
* Builds a new StreamInfo.
*/
public StreamInfo build() {
return new StreamInfo(callOptions, previousAttempts, isTransparentRetry);
return new StreamInfo(callOptions, previousAttempts, isTransparentRetry, isHedging);
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/io/grpc/internal/ClientCallImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ public void runInContext() {
stream = clientStreamProvider.newStream(method, callOptions, headers, context);
} else {
ClientStreamTracer[] tracers =
GrpcUtil.getClientStreamTracers(callOptions, headers, 0, false);
GrpcUtil.getClientStreamTracers(callOptions, headers, 0,
false, false);
String deadlineName = contextIsDeadlineSource ? "Context" : "CallOptions";
Long nameResolutionDelay = callOptions.getOption(NAME_RESOLUTION_DELAYED);
String description = String.format(
Expand Down
4 changes: 3 additions & 1 deletion core/src/main/java/io/grpc/internal/GrpcUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -757,13 +757,15 @@ public ListenableFuture<SocketStats> getStats() {

/** Gets stream tracers based on CallOptions. */
public static ClientStreamTracer[] getClientStreamTracers(
CallOptions callOptions, Metadata headers, int previousAttempts, boolean isTransparentRetry) {
CallOptions callOptions, Metadata headers, int previousAttempts, boolean isTransparentRetry,
boolean isHedging) {
List<ClientStreamTracer.Factory> factories = callOptions.getStreamTracerFactories();
ClientStreamTracer[] tracers = new ClientStreamTracer[factories.size() + 1];
StreamInfo streamInfo = StreamInfo.newBuilder()
.setCallOptions(callOptions)
.setPreviousAttempts(previousAttempts)
.setIsTransparentRetry(isTransparentRetry)
.setIsHedging(isHedging)
.build();
for (int i = 0; i < factories.size(); i++) {
tracers[i] = factories.get(i).newClientStreamTracer(streamInfo, headers);
Expand Down
7 changes: 4 additions & 3 deletions core/src/main/java/io/grpc/internal/ManagedChannelImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,8 @@ public ClientStream newStream(
// the delayed transport or a real transport will go in-use and cancel the idle timer.
if (!retryEnabled) {
ClientStreamTracer[] tracers = GrpcUtil.getClientStreamTracers(
callOptions, headers, 0, /* isTransparentRetry= */ false);
callOptions, headers, 0, /* isTransparentRetry= */ false,
/* isHedging= */false);
Context origContext = context.attach();
try {
return delayedTransport.newStream(method, headers, callOptions, tracers);
Expand Down Expand Up @@ -520,10 +521,10 @@ void postCommit() {
@Override
ClientStream newSubstream(
Metadata newHeaders, ClientStreamTracer.Factory factory, int previousAttempts,
boolean isTransparentRetry) {
boolean isTransparentRetry, boolean isHedging) {
CallOptions newOptions = callOptions.withStreamTracerFactory(factory);
ClientStreamTracer[] tracers = GrpcUtil.getClientStreamTracers(
newOptions, newHeaders, previousAttempts, isTransparentRetry);
newOptions, newHeaders, previousAttempts, isTransparentRetry, isHedging);
Context origContext = context.attach();
try {
return delayedTransport.newStream(method, newHeaders, newOptions, tracers);
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/io/grpc/internal/OobChannel.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ final class OobChannel extends ManagedChannel implements InternalInstrumented<Ch
public ClientStream newStream(MethodDescriptor<?, ?> method,
CallOptions callOptions, Metadata headers, Context context) {
ClientStreamTracer[] tracers = GrpcUtil.getClientStreamTracers(
callOptions, headers, 0, /* isTransparentRetry= */ false);
callOptions, headers, 0, /* isTransparentRetry= */ false,
/* isHedging= */ false);
Context origContext = context.attach();
// delayed transport's newStream() always acquires a lock, but concurrent performance doesn't
// matter here because OOB communication should be sparse, and it's not on application RPC's
Expand Down
5 changes: 3 additions & 2 deletions core/src/main/java/io/grpc/internal/RetriableStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,8 @@ public ClientStreamTracer newClientStreamTracer(

Metadata newHeaders = updateHeaders(headers, previousAttemptCount);
// NOTICE: This set _must_ be done before stream.start() and it actually is.
sub.stream = newSubstream(newHeaders, tracerFactory, previousAttemptCount, isTransparentRetry);
sub.stream = newSubstream(newHeaders, tracerFactory, previousAttemptCount, isTransparentRetry,
isHedging);
return sub;
}

Expand All @@ -276,7 +277,7 @@ public ClientStreamTracer newClientStreamTracer(
*/
abstract ClientStream newSubstream(
Metadata headers, ClientStreamTracer.Factory tracerFactory, int previousAttempts,
boolean isTransparentRetry);
boolean isTransparentRetry, boolean isHedging);

/** Adds grpc-previous-rpc-attempts in the headers of a retry/hedging RPC. */
@VisibleForTesting
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/io/grpc/internal/SubchannelChannel.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ public ClientStream newStream(MethodDescriptor<?, ?> method,
transport = notReadyTransport;
}
ClientStreamTracer[] tracers = GrpcUtil.getClientStreamTracers(
callOptions, headers, 0, /* isTransparentRetry= */ false);
callOptions, headers, 0, /* isTransparentRetry= */ false,
/* isHedging= */ false);
Context origContext = context.attach();
try {
return transport.newStream(method, headers, callOptions, tracers);
Expand Down
3 changes: 2 additions & 1 deletion core/src/test/java/io/grpc/internal/RetriableStreamTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ ClientStream newSubstream(
Metadata metadata,
ClientStreamTracer.Factory tracerFactory,
int previousAttempts,
boolean isTransparentRetry) {
boolean isTransparentRetry,
boolean isHedging) {
bufferSizeTracer =
tracerFactory.newClientStreamTracer(STREAM_INFO, metadata);
int actualPreviousRpcAttemptsInHeader = metadata.get(GRPC_PREVIOUS_RPC_ATTEMPTS) == null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@

import static com.google.common.base.Preconditions.checkNotNull;
import static io.grpc.internal.GrpcUtil.IMPLEMENTATION_VERSION;
import static io.grpc.opentelemetry.internal.OpenTelemetryConstants.HEDGE_BUCKETS;
import static io.grpc.opentelemetry.internal.OpenTelemetryConstants.LATENCY_BUCKETS;
import static io.grpc.opentelemetry.internal.OpenTelemetryConstants.RETRY_BUCKETS;
import static io.grpc.opentelemetry.internal.OpenTelemetryConstants.SIZE_BUCKETS;
import static io.grpc.opentelemetry.internal.OpenTelemetryConstants.TRANSPARENT_RETRY_BUCKETS;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Stopwatch;
Expand Down Expand Up @@ -64,8 +67,8 @@
};

Copy link
Contributor

Choose a reason for hiding this comment

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

Add unit tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the gRFC has had recent updates, waiting for it to get merged before doing further changes...

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, there had been discussions yesterday about the recent changes to the retry metrics and whether they helped and such. The implementation should be mostly the same, but it isn't probably worth chasing the gRFC for the moment.

@VisibleForTesting
static boolean ENABLE_OTEL_TRACING = GrpcUtil.getFlag("GRPC_EXPERIMENTAL_ENABLE_OTEL_TRACING",
false);
static boolean ENABLE_OTEL_TRACING =
GrpcUtil.getFlag("GRPC_EXPERIMENTAL_ENABLE_OTEL_TRACING", false);

private final OpenTelemetry openTelemetrySdk;
private final MeterProvider meterProvider;
Expand Down Expand Up @@ -241,6 +244,53 @@
.build());
}

if (isMetricEnabled("grpc.client.call.retries", enableMetrics, disableDefault)) {
builder.clientCallRetriesCounter(
meter.histogramBuilder(

Check warning on line 249 in opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java#L248-L249

Added lines #L248 - L249 were not covered by tests
"grpc.client.call.retries")
.setUnit("{retry}")
.setDescription("Number of retries during the client call. "

Check warning on line 252 in opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java#L251-L252

Added lines #L251 - L252 were not covered by tests
+ "If there were no retries, 0 is not reported.")
.ofLongs()
.setExplicitBucketBoundariesAdvice(RETRY_BUCKETS)
.build());

Check warning on line 256 in opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java#L254-L256

Added lines #L254 - L256 were not covered by tests
}

if (isMetricEnabled("grpc.client.call.transparent_retries", enableMetrics, disableDefault)) {
builder.clientCallRetriesCounter(
meter.histogramBuilder(

Check warning on line 261 in opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java#L260-L261

Added lines #L260 - L261 were not covered by tests
"grpc.client.call.transparent_retries")
.setUnit("{transparent_retry}")
.setDescription("Number of transparent retries during the client call. "

Check warning on line 264 in opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java#L263-L264

Added lines #L263 - L264 were not covered by tests
+ "If there were no transparent retries, 0 is not reported.")
.ofLongs()
.setExplicitBucketBoundariesAdvice(TRANSPARENT_RETRY_BUCKETS)
.build());

Check warning on line 268 in opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java#L266-L268

Added lines #L266 - L268 were not covered by tests
}

if (isMetricEnabled("grpc.client.call.hedges", enableMetrics, disableDefault)) {
builder.clientCallRetriesCounter(
meter.histogramBuilder(

Check warning on line 273 in opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java#L272-L273

Added lines #L272 - L273 were not covered by tests
"grpc.client.call.hedges")
.setUnit("{hedge}")
.setDescription("Number of hedges during the client call. "

Check warning on line 276 in opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java#L275-L276

Added lines #L275 - L276 were not covered by tests
+ "If there were no hedges, 0 is not reported.")
.ofLongs()
.setExplicitBucketBoundariesAdvice(HEDGE_BUCKETS)
.build());

Check warning on line 280 in opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java#L278-L280

Added lines #L278 - L280 were not covered by tests
}

if (isMetricEnabled("grpc.client.call.retry_delay", enableMetrics, disableDefault)) {
builder.clientCallRetryDelayCounter(
meter.histogramBuilder(

Check warning on line 285 in opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java#L284-L285

Added lines #L284 - L285 were not covered by tests
"grpc.client.call.retry_delay")
.setUnit("s")
.setDescription("Total time of delay while there is no active attempt during the "

Check warning on line 288 in opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java#L287-L288

Added lines #L287 - L288 were not covered by tests
+ "client call")
.setExplicitBucketBoundariesAdvice(LATENCY_BUCKETS)
.build());

Check warning on line 291 in opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/GrpcOpenTelemetry.java#L290-L291

Added lines #L290 - L291 were not covered by tests
}

if (isMetricEnabled("grpc.server.call.started", enableMetrics, disableDefault)) {
builder.serverCallCountCounter(
meter.counterBuilder("grpc.server.call.started")
Expand All @@ -259,8 +309,8 @@
.build());
}

if (isMetricEnabled("grpc.server.call.sent_total_compressed_message_size", enableMetrics,
disableDefault)) {
if (isMetricEnabled("grpc.server.call.sent_total_compressed_message_size",
enableMetrics, disableDefault)) {
builder.serverTotalSentCompressedMessageSizeCounter(
meter.histogramBuilder(
"grpc.server.call.sent_total_compressed_message_size")
Expand All @@ -271,8 +321,8 @@
.build());
}

if (isMetricEnabled("grpc.server.call.rcvd_total_compressed_message_size", enableMetrics,
disableDefault)) {
if (isMetricEnabled("grpc.server.call.rcvd_total_compressed_message_size",
enableMetrics, disableDefault)) {
builder.serverTotalReceivedCompressedMessageSizeCounter(
meter.histogramBuilder(
"grpc.server.call.rcvd_total_compressed_message_size")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
*/
final class OpenTelemetryMetricsModule {
private static final Logger logger = Logger.getLogger(OpenTelemetryMetricsModule.class.getName());
private static final double NANOS_PER_SEC = 1_000_000_000.0;
public static final ImmutableSet<String> DEFAULT_PER_CALL_METRICS_SET =
ImmutableSet.of(
"grpc.client.attempt.started",
Expand Down Expand Up @@ -292,9 +293,12 @@
private final String fullMethodName;
private final List<OpenTelemetryPlugin.ClientCallPlugin> callPlugins;
private Status status;
private long retryDelayNanos;
private long callLatencyNanos;
private final Object lock = new Object();
private final AtomicLong attemptsPerCall = new AtomicLong();
private final AtomicLong hedgedAttemptsPerCall = new AtomicLong();
private final AtomicLong transparentRetriesPerCall = new AtomicLong();
@GuardedBy("lock")
private int activeStreams;
@GuardedBy("lock")
Expand Down Expand Up @@ -331,6 +335,7 @@
}
if (++activeStreams == 1 && attemptStopwatch.isRunning()) {
attemptStopwatch.stop();
retryDelayNanos = attemptStopwatch.elapsed(TimeUnit.NANOSECONDS);
}
}
// Skip recording for the first time, since it is already recorded in
Expand All @@ -344,7 +349,12 @@
module.resource.clientAttemptCountCounter().add(1, attribute);
}
}
if (!info.isTransparentRetry()) {
if (info.isTransparentRetry()) {
transparentRetriesPerCall.incrementAndGet();
} else if (info.isHedging()) {
hedgedAttemptsPerCall.incrementAndGet();

Check warning on line 355 in opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java#L355

Added line #L355 was not covered by tests
}
else {
attemptsPerCall.incrementAndGet();
}
return newClientTracer(info);
Expand Down Expand Up @@ -407,14 +417,65 @@
tracer.recordFinishedAttempt();
}
callLatencyNanos = callStopWatch.elapsed(TimeUnit.NANOSECONDS);
io.opentelemetry.api.common.Attributes attribute =
io.opentelemetry.api.common.Attributes.of(METHOD_KEY, fullMethodName,
TARGET_KEY, target,
STATUS_KEY, status.getCode().toString());

// Base attributes
io.opentelemetry.api.common.Attributes baseAttributes =
io.opentelemetry.api.common.Attributes.of(
METHOD_KEY, fullMethodName,
TARGET_KEY, target
);

// Duration
if (module.resource.clientCallDurationCounter() != null) {
module.resource.clientCallDurationCounter()
.record(callLatencyNanos * SECONDS_PER_NANO, attribute);
module.resource.clientCallDurationCounter().record(
callLatencyNanos * SECONDS_PER_NANO,
baseAttributes.toBuilder()
.put(STATUS_KEY, status.getCode().toString())
.build()
);
}

// Retry counts
if (module.resource.clientCallRetriesCounter() != null) {

long retriesPerCall = 0;
long attempts = attemptsPerCall.get();

Check warning on line 442 in opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java#L441-L442

Added lines #L441 - L442 were not covered by tests
if (attempts > 0) {
retriesPerCall = attempts - 1;

Check warning on line 444 in opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java#L444

Added line #L444 was not covered by tests
}

if (retriesPerCall > 0) {
module.resource.clientCallRetriesCounter().record(retriesPerCall, baseAttributes);

Check warning on line 448 in opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java#L448

Added line #L448 was not covered by tests
}
}

// Hedge counts
if (module.resource.clientCallHedgesCounter() != null) {

long hedgesPerCall = 0;
long attempts = hedgedAttemptsPerCall.get();

Check warning on line 456 in opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java#L455-L456

Added lines #L455 - L456 were not covered by tests
if (attempts > 0) {
hedgesPerCall = attempts - 1;

Check warning on line 458 in opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java#L458

Added line #L458 was not covered by tests
}

if (hedgesPerCall > 0) {
module.resource.clientCallHedgesCounter().record(hedgesPerCall, baseAttributes);

Check warning on line 462 in opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java#L462

Added line #L462 was not covered by tests
}
}

// Transparent Retry counts
if (module.resource.clientCallTransparentRetriesCounter() != null
&& transparentRetriesPerCall.get() > 0) {
module.resource.clientCallRetriesCounter().record(
transparentRetriesPerCall.get(), baseAttributes);

Check warning on line 470 in opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java#L469-L470

Added lines #L469 - L470 were not covered by tests
}

// Retry delay
if (module.resource.clientCallRetryDelayCounter() != null) {
module.resource.clientCallRetryDelayCounter().record(

Check warning on line 475 in opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java

View check run for this annotation

Codecov / codecov/patch

opentelemetry/src/main/java/io/grpc/opentelemetry/OpenTelemetryMetricsModule.java#L475

Added line #L475 was not covered by tests
retryDelayNanos / NANOS_PER_SEC,
baseAttributes
);
}
}
}
Expand Down
Loading