From d8d3bc72b4288907337109d4ab5dd821788ebe4f Mon Sep 17 00:00:00 2001 From: ldetmer Date: Tue, 24 Mar 2026 14:57:09 -0400 Subject: [PATCH 1/4] feat: add resend attribute to span tracing --- .../bigquery/BigQueryRetryAlgorithm.java | 15 ++++ .../HttpTracingRequestInitializer.java | 7 ++ .../bigquery/spi/v2/HttpBigQueryRpcTest.java | 73 +++++++++++++++++++ .../HttpTracingRequestInitializerTest.java | 22 ++++++ 4 files changed, 117 insertions(+) diff --git a/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryRetryAlgorithm.java b/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryRetryAlgorithm.java index 140f2c6eba3c..927f87641a9e 100644 --- a/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryRetryAlgorithm.java +++ b/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryRetryAlgorithm.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.api.core.InternalApi; import com.google.api.gax.retrying.ResultRetryAlgorithm; import com.google.api.gax.retrying.ResultRetryAlgorithmWithContext; import com.google.api.gax.retrying.RetryAlgorithm; @@ -44,6 +45,17 @@ public class BigQueryRetryAlgorithm extends RetryAlgorithm private static final Logger LOG = Logger.getLogger(BigQueryRetryAlgorithm.class.getName()); private static final UUID RETRY_UUID = UUID.randomUUID(); + private static final ThreadLocal currentAttempt = ThreadLocal.withInitial(() -> 0); + + @InternalApi("internal to java-bigquery") + public static int getCurrentAttempt() { + return currentAttempt.get(); + } + + @InternalApi("internal to java-bigquery") + public static void setCurrentAttempt(int attempt) { + currentAttempt.set(attempt); + } public BigQueryRetryAlgorithm( ResultRetryAlgorithm resultAlgorithm, @@ -78,6 +90,9 @@ public boolean shouldRetry( previousThrowable, bigQueryRetryConfig, previousResponse)) && shouldRetryBasedOnTiming(context, nextAttemptSettings); + // Store retry attempt count in thread-local storage for tracing + setCurrentAttempt(attemptCount); + if (LOG.isLoggable(Level.FINEST)) { LOG.log( Level.FINEST, diff --git a/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializer.java b/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializer.java index 76f664df1069..1809d14b18e9 100644 --- a/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializer.java +++ b/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializer.java @@ -19,6 +19,7 @@ import com.google.api.client.http.*; import com.google.api.core.BetaApi; import com.google.api.core.InternalApi; +import com.google.cloud.bigquery.BigQueryRetryAlgorithm; import com.google.common.annotations.VisibleForTesting; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.trace.Span; @@ -111,6 +112,12 @@ private void addInitialHttpAttributesToSpan(Span span, HttpRequest request) { span.setAttribute(BigQueryTelemetryTracer.SERVER_PORT, (long) port); } span.setAttribute(URL_FULL, getSanitizedUrl(request)); + int retryAttempt = BigQueryRetryAlgorithm.getCurrentAttempt(); + if (retryAttempt > 0) { + span.setAttribute(HTTP_REQUEST_RESEND_COUNT, (long) retryAttempt); + } + // Reset attempt count to 0 to avoid carrying over state across requests on the same thread + BigQueryRetryAlgorithm.setCurrentAttempt(0); } private static void addCommonResponseAttributesToSpan( diff --git a/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpcTest.java b/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpcTest.java index bafc92b63e99..01b6141997b7 100644 --- a/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpcTest.java +++ b/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpcTest.java @@ -1101,6 +1101,43 @@ public void testHttpTracingEnabled_JsonResponseException_SetsAttributes() throws "Invalid request", rpcSpan.getAttributes().get(BigQueryTelemetryTracer.STATUS_MESSAGE)); assertNull(rpcSpan.getAttributes().get(BigQueryTelemetryTracer.EXCEPTION_TYPE)); } + + @Test + public void testResendCountOnRetry() throws Exception { + // Manually set attempt count to simulate being inside a retry loop + com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(2); + + setMockResponse( + "{\"kind\":\"bigquery#dataset\",\"id\":\"" + + PROJECT_ID + + ":" + + DATASET_ID + + "\",\"datasetReference\":{\"projectId\":\"" + + PROJECT_ID + + "\",\"datasetId\":\"" + + DATASET_ID + + "\"}}"); + + rpc.getDatasetSkipExceptionTranslation(PROJECT_ID, DATASET_ID, new HashMap<>()); + + List spans = spanExporter.getFinishedSpanItems(); + assertThat(spans).isNotEmpty(); + io.opentelemetry.sdk.trace.data.SpanData rpcSpan = + spans.stream() + .filter(s -> s.getName().equals("com.google.cloud.bigquery.BigQueryRpc.getDataset")) + .findFirst() + .orElse(null); + assertNotNull(rpcSpan); + assertEquals( + 2L, + rpcSpan + .getAttributes() + .get( + com.google.cloud.bigquery.telemetry.HttpTracingRequestInitializer + .HTTP_REQUEST_RESEND_COUNT)); + + com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(0); + } } @Nested @@ -1199,6 +1236,42 @@ public void testHttpTracingDisabled_GoogleJsonResponseException_DoesNotSetAttrib assertNull(rpcSpan.getAttributes().get(BigQueryTelemetryTracer.ERROR_TYPE)); assertNull(rpcSpan.getAttributes().get(BigQueryTelemetryTracer.STATUS_MESSAGE)); } + + @Test + public void testResendCountNotSetWhenDisabled() throws Exception { + // Manually set attempt count to simulate being inside a retry loop + com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(2); + + setMockResponse( + "{\"kind\":\"bigquery#dataset\",\"id\":\"" + + PROJECT_ID + + ":" + + DATASET_ID + + "\",\"datasetReference\":{\"projectId\":\"" + + PROJECT_ID + + "\",\"datasetId\":\"" + + DATASET_ID + + "\"}}"); + + rpc.getDatasetSkipExceptionTranslation(PROJECT_ID, DATASET_ID, new HashMap<>()); + + List spans = spanExporter.getFinishedSpanItems(); + assertThat(spans).isNotEmpty(); + io.opentelemetry.sdk.trace.data.SpanData rpcSpan = + spans.stream() + .filter(s -> s.getName().equals("com.google.cloud.bigquery.BigQueryRpc.getDataset")) + .findFirst() + .orElse(null); + assertNotNull(rpcSpan); + assertNull( + rpcSpan + .getAttributes() + .get( + com.google.cloud.bigquery.telemetry.HttpTracingRequestInitializer + .HTTP_REQUEST_RESEND_COUNT)); + + com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(0); + } } @Nested diff --git a/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializerTest.java b/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializerTest.java index 0bf0012be30e..9a06326fdb35 100644 --- a/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializerTest.java +++ b/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializerTest.java @@ -335,6 +335,27 @@ public void testAddResponseBodySizeToSpan_NullLength() throws IOException { assertNull(span.getAttributes().get(HttpTracingRequestInitializer.HTTP_RESPONSE_BODY_SIZE)); } + @Test + public void testResendCountIsSetFromBigQueryRetryAlgorithm() throws IOException { + com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(3); + HttpTransport transport = createTransport(); + HttpRequest request = buildGetRequest(transport, initializer, BASE_URL); + + HttpResponse response = request.execute(); + response.disconnect(); + + spanScope.close(); + parentSpan.end(); + + List spans = spanExporter.getFinishedSpanItems(); + assertEquals(1, spans.size()); + SpanData span = spans.get(0); + assertEquals( + 3L, span.getAttributes().get(HttpTracingRequestInitializer.HTTP_REQUEST_RESEND_COUNT)); + + com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(0); + } + private static HttpTransport createTransport() { return createTransport(200, null); } @@ -429,5 +450,6 @@ private void closeAndVerifySpanData( } else { assertNull(span.getAttributes().get(HttpTracingRequestInitializer.HTTP_RESPONSE_BODY_SIZE)); } + assertNull(span.getAttributes().get(HttpTracingRequestInitializer.HTTP_REQUEST_RESEND_COUNT)); } } From c40063e4351f0339c306e559549c1793a61fb45c Mon Sep 17 00:00:00 2001 From: ldetmer Date: Tue, 24 Mar 2026 16:33:43 -0400 Subject: [PATCH 2/4] cleanup after test in case of failure --- .../bigquery/spi/v2/HttpBigQueryRpcTest.java | 118 +++++++++--------- .../HttpTracingRequestInitializerTest.java | 28 +++-- 2 files changed, 75 insertions(+), 71 deletions(-) diff --git a/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpcTest.java b/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpcTest.java index 655a3437a413..ff9e1f4fdd7c 100644 --- a/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpcTest.java +++ b/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpcTest.java @@ -1111,7 +1111,7 @@ public void testHttpTracingEnabled_JsonResponseException_SetsAttributes() throws "Invalid request", rpcSpan.getAttributes().get(BigQueryTelemetryTracer.STATUS_MESSAGE)); assertNull(rpcSpan.getAttributes().get(BigQueryTelemetryTracer.EXCEPTION_TYPE)); } - + @Test public void testGetUriTemplateValueTelemetry() throws Exception { setMockResponse( @@ -1145,37 +1145,38 @@ public void testGetUriTemplateValueTelemetry() throws Exception { public void testResendCountOnRetry() throws Exception { // Manually set attempt count to simulate being inside a retry loop com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(2); + try { + setMockResponse( + "{\"kind\":\"bigquery#dataset\",\"id\":\"" + + PROJECT_ID + + ":" + + DATASET_ID + + "\",\"datasetReference\":{\"projectId\":\"" + + PROJECT_ID + + "\",\"datasetId\":\"" + + DATASET_ID + + "\"}}"); - setMockResponse( - "{\"kind\":\"bigquery#dataset\",\"id\":\"" - + PROJECT_ID - + ":" - + DATASET_ID - + "\",\"datasetReference\":{\"projectId\":\"" - + PROJECT_ID - + "\",\"datasetId\":\"" - + DATASET_ID - + "\"}}"); - - rpc.getDatasetSkipExceptionTranslation(PROJECT_ID, DATASET_ID, new HashMap<>()); - - List spans = spanExporter.getFinishedSpanItems(); - assertThat(spans).isNotEmpty(); - io.opentelemetry.sdk.trace.data.SpanData rpcSpan = - spans.stream() - .filter(s -> s.getName().equals("com.google.cloud.bigquery.BigQueryRpc.getDataset")) - .findFirst() - .orElse(null); - assertNotNull(rpcSpan); - assertEquals( - 2L, - rpcSpan - .getAttributes() - .get( - com.google.cloud.bigquery.telemetry.HttpTracingRequestInitializer - .HTTP_REQUEST_RESEND_COUNT)); + rpc.getDatasetSkipExceptionTranslation(PROJECT_ID, DATASET_ID, new HashMap<>()); - com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(0); + List spans = spanExporter.getFinishedSpanItems(); + assertThat(spans).isNotEmpty(); + io.opentelemetry.sdk.trace.data.SpanData rpcSpan = + spans.stream() + .filter(s -> s.getName().equals("com.google.cloud.bigquery.BigQueryRpc.getDataset")) + .findFirst() + .orElse(null); + assertNotNull(rpcSpan); + assertEquals( + 2L, + rpcSpan + .getAttributes() + .get( + com.google.cloud.bigquery.telemetry.HttpTracingRequestInitializer + .HTTP_REQUEST_RESEND_COUNT)); + } finally { + com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(0); + } } } @@ -1285,36 +1286,37 @@ public void testHttpTracingDisabled_GoogleJsonResponseException_DoesNotSetAttrib public void testResendCountNotSetWhenDisabled() throws Exception { // Manually set attempt count to simulate being inside a retry loop com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(2); + try { + setMockResponse( + "{\"kind\":\"bigquery#dataset\",\"id\":\"" + + PROJECT_ID + + ":" + + DATASET_ID + + "\",\"datasetReference\":{\"projectId\":\"" + + PROJECT_ID + + "\",\"datasetId\":\"" + + DATASET_ID + + "\"}}"); - setMockResponse( - "{\"kind\":\"bigquery#dataset\",\"id\":\"" - + PROJECT_ID - + ":" - + DATASET_ID - + "\",\"datasetReference\":{\"projectId\":\"" - + PROJECT_ID - + "\",\"datasetId\":\"" - + DATASET_ID - + "\"}}"); - - rpc.getDatasetSkipExceptionTranslation(PROJECT_ID, DATASET_ID, new HashMap<>()); - - List spans = spanExporter.getFinishedSpanItems(); - assertThat(spans).isNotEmpty(); - io.opentelemetry.sdk.trace.data.SpanData rpcSpan = - spans.stream() - .filter(s -> s.getName().equals("com.google.cloud.bigquery.BigQueryRpc.getDataset")) - .findFirst() - .orElse(null); - assertNotNull(rpcSpan); - assertNull( - rpcSpan - .getAttributes() - .get( - com.google.cloud.bigquery.telemetry.HttpTracingRequestInitializer - .HTTP_REQUEST_RESEND_COUNT)); + rpc.getDatasetSkipExceptionTranslation(PROJECT_ID, DATASET_ID, new HashMap<>()); - com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(0); + List spans = spanExporter.getFinishedSpanItems(); + assertThat(spans).isNotEmpty(); + io.opentelemetry.sdk.trace.data.SpanData rpcSpan = + spans.stream() + .filter(s -> s.getName().equals("com.google.cloud.bigquery.BigQueryRpc.getDataset")) + .findFirst() + .orElse(null); + assertNotNull(rpcSpan); + assertNull( + rpcSpan + .getAttributes() + .get( + com.google.cloud.bigquery.telemetry.HttpTracingRequestInitializer + .HTTP_REQUEST_RESEND_COUNT)); + } finally { + com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(0); + } } } diff --git a/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializerTest.java b/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializerTest.java index 9a06326fdb35..10275c0e1d79 100644 --- a/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializerTest.java +++ b/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializerTest.java @@ -338,22 +338,24 @@ public void testAddResponseBodySizeToSpan_NullLength() throws IOException { @Test public void testResendCountIsSetFromBigQueryRetryAlgorithm() throws IOException { com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(3); - HttpTransport transport = createTransport(); - HttpRequest request = buildGetRequest(transport, initializer, BASE_URL); - - HttpResponse response = request.execute(); - response.disconnect(); + try { + HttpTransport transport = createTransport(); + HttpRequest request = buildGetRequest(transport, initializer, BASE_URL); - spanScope.close(); - parentSpan.end(); + HttpResponse response = request.execute(); + response.disconnect(); - List spans = spanExporter.getFinishedSpanItems(); - assertEquals(1, spans.size()); - SpanData span = spans.get(0); - assertEquals( - 3L, span.getAttributes().get(HttpTracingRequestInitializer.HTTP_REQUEST_RESEND_COUNT)); + spanScope.close(); + parentSpan.end(); - com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(0); + List spans = spanExporter.getFinishedSpanItems(); + assertEquals(1, spans.size()); + SpanData span = spans.get(0); + assertEquals( + 3L, span.getAttributes().get(HttpTracingRequestInitializer.HTTP_REQUEST_RESEND_COUNT)); + } finally { + com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(0); + } } private static HttpTransport createTransport() { From 5b5dbafeb151324aee9f62cf41ad4de1d4d8bf6b Mon Sep 17 00:00:00 2001 From: ldetmer Date: Tue, 24 Mar 2026 16:44:05 -0400 Subject: [PATCH 3/4] refactor to move attribute to HttpBigQueryRpc to easily handle reset the retry count in case of error --- .../bigquery/spi/v2/HttpBigQueryRpc.java | 8 +++++++ .../telemetry/BigQueryTelemetryTracer.java | 2 ++ .../HttpTracingRequestInitializer.java | 9 ------- .../bigquery/spi/v2/HttpBigQueryRpcTest.java | 4 ++-- .../HttpTracingRequestInitializerTest.java | 24 ------------------- 5 files changed, 12 insertions(+), 35 deletions(-) diff --git a/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpc.java b/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpc.java index 8eede5a0937b..575241da8524 100644 --- a/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpc.java +++ b/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpc.java @@ -66,6 +66,7 @@ import com.google.cloud.Tuple; import com.google.cloud.bigquery.BigQueryException; import com.google.cloud.bigquery.BigQueryOptions; +import com.google.cloud.bigquery.BigQueryRetryAlgorithm; import com.google.cloud.bigquery.telemetry.BigQueryTelemetryTracer; import com.google.cloud.bigquery.telemetry.HttpTracingRequestInitializer; import com.google.cloud.http.HttpTransportOptions; @@ -2150,6 +2151,11 @@ private Span createRpcTracingSpan( .setAttribute( BigQueryTelemetryTracer.GCP_RESOURCE_DESTINATION_ID, gcpResourceDestinationId) .setAttribute(BigQueryTelemetryTracer.URL_TEMPLATE, urlTemplate); + int retryAttempt = BigQueryRetryAlgorithm.getCurrentAttempt(); + if (retryAttempt > 0) { + builder.setAttribute( + BigQueryTelemetryTracer.HTTP_REQUEST_RESEND_COUNT, (long) retryAttempt); + } } if (options != null) { @@ -2182,6 +2188,8 @@ private T executeWithSpan(Span span, SpanOperation operation) throws IOEx } throw e; } finally { + // Reset attempt count to 0 to avoid carrying over state across requests on the same thread + BigQueryRetryAlgorithm.setCurrentAttempt(0); span.end(); } } diff --git a/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/telemetry/BigQueryTelemetryTracer.java b/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/telemetry/BigQueryTelemetryTracer.java index 82c354ef5446..e368867c052b 100644 --- a/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/telemetry/BigQueryTelemetryTracer.java +++ b/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/telemetry/BigQueryTelemetryTracer.java @@ -66,6 +66,8 @@ private BigQueryTelemetryTracer() {} AttributeKey.stringKey("server.address"); public static final AttributeKey SERVER_PORT = AttributeKey.longKey("server.port"); public static final AttributeKey URL_TEMPLATE = AttributeKey.stringKey("url.template"); + public static final AttributeKey HTTP_REQUEST_RESEND_COUNT = + AttributeKey.longKey("http.request.resend_count"); public static void addCommonAttributeToSpan(Span span) { span.setAttribute(GCP_CLIENT_SERVICE, BQ_GCP_CLIENT_SERVICE) diff --git a/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializer.java b/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializer.java index 2c33a8b9c548..3c9302a3e3a3 100644 --- a/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializer.java +++ b/java-bigquery/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializer.java @@ -19,7 +19,6 @@ import com.google.api.client.http.*; import com.google.api.core.BetaApi; import com.google.api.core.InternalApi; -import com.google.cloud.bigquery.BigQueryRetryAlgorithm; import com.google.common.annotations.VisibleForTesting; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.trace.Span; @@ -43,8 +42,6 @@ public class HttpTracingRequestInitializer implements HttpRequestInitializer { public static final AttributeKey URL_DOMAIN = AttributeKey.stringKey("url.domain"); public static final AttributeKey HTTP_RESPONSE_STATUS_CODE = AttributeKey.longKey("http.response.status_code"); - public static final AttributeKey HTTP_REQUEST_RESEND_COUNT = - AttributeKey.longKey("http.request.resend_count"); public static final AttributeKey HTTP_REQUEST_BODY_SIZE = AttributeKey.longKey("http.request.body.size"); public static final AttributeKey HTTP_RESPONSE_BODY_SIZE = @@ -111,12 +108,6 @@ private void addInitialHttpAttributesToSpan(Span span, HttpRequest request) { span.setAttribute(BigQueryTelemetryTracer.SERVER_PORT, (long) port); } span.setAttribute(URL_FULL, getSanitizedUrl(request)); - int retryAttempt = BigQueryRetryAlgorithm.getCurrentAttempt(); - if (retryAttempt > 0) { - span.setAttribute(HTTP_REQUEST_RESEND_COUNT, (long) retryAttempt); - } - // Reset attempt count to 0 to avoid carrying over state across requests on the same thread - BigQueryRetryAlgorithm.setCurrentAttempt(0); } private static void addCommonResponseAttributesToSpan( diff --git a/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpcTest.java b/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpcTest.java index ff9e1f4fdd7c..d6fa08f99d04 100644 --- a/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpcTest.java +++ b/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpcTest.java @@ -1172,7 +1172,7 @@ public void testResendCountOnRetry() throws Exception { rpcSpan .getAttributes() .get( - com.google.cloud.bigquery.telemetry.HttpTracingRequestInitializer + BigQueryTelemetryTracer .HTTP_REQUEST_RESEND_COUNT)); } finally { com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(0); @@ -1312,7 +1312,7 @@ public void testResendCountNotSetWhenDisabled() throws Exception { rpcSpan .getAttributes() .get( - com.google.cloud.bigquery.telemetry.HttpTracingRequestInitializer + BigQueryTelemetryTracer .HTTP_REQUEST_RESEND_COUNT)); } finally { com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(0); diff --git a/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializerTest.java b/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializerTest.java index 10275c0e1d79..0bf0012be30e 100644 --- a/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializerTest.java +++ b/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializerTest.java @@ -335,29 +335,6 @@ public void testAddResponseBodySizeToSpan_NullLength() throws IOException { assertNull(span.getAttributes().get(HttpTracingRequestInitializer.HTTP_RESPONSE_BODY_SIZE)); } - @Test - public void testResendCountIsSetFromBigQueryRetryAlgorithm() throws IOException { - com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(3); - try { - HttpTransport transport = createTransport(); - HttpRequest request = buildGetRequest(transport, initializer, BASE_URL); - - HttpResponse response = request.execute(); - response.disconnect(); - - spanScope.close(); - parentSpan.end(); - - List spans = spanExporter.getFinishedSpanItems(); - assertEquals(1, spans.size()); - SpanData span = spans.get(0); - assertEquals( - 3L, span.getAttributes().get(HttpTracingRequestInitializer.HTTP_REQUEST_RESEND_COUNT)); - } finally { - com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(0); - } - } - private static HttpTransport createTransport() { return createTransport(200, null); } @@ -452,6 +429,5 @@ private void closeAndVerifySpanData( } else { assertNull(span.getAttributes().get(HttpTracingRequestInitializer.HTTP_RESPONSE_BODY_SIZE)); } - assertNull(span.getAttributes().get(HttpTracingRequestInitializer.HTTP_REQUEST_RESEND_COUNT)); } } From dd81d258bad14845eb470921574037bfe94964cc Mon Sep 17 00:00:00 2001 From: ldetmer Date: Tue, 24 Mar 2026 16:49:41 -0400 Subject: [PATCH 4/4] add test to confirm resend attribute does not get set on success flow --- .../bigquery/spi/v2/HttpBigQueryRpcTest.java | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpcTest.java b/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpcTest.java index d6fa08f99d04..5e9c3f23ac8e 100644 --- a/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpcTest.java +++ b/java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpcTest.java @@ -160,6 +160,9 @@ private void verifySpan( assertEquals( gcpResourceDestinationId, rpcSpan.getAttributes().get(BigQueryTelemetryTracer.GCP_RESOURCE_DESTINATION_ID)); + + // this attribute should never get set in a normal success flow + assertNull(rpcSpan.getAttributes().get(BigQueryTelemetryTracer.HTTP_REQUEST_RESEND_COUNT)); } private void verifySpanProductionAttributes( @@ -1168,12 +1171,7 @@ public void testResendCountOnRetry() throws Exception { .orElse(null); assertNotNull(rpcSpan); assertEquals( - 2L, - rpcSpan - .getAttributes() - .get( - BigQueryTelemetryTracer - .HTTP_REQUEST_RESEND_COUNT)); + 2L, rpcSpan.getAttributes().get(BigQueryTelemetryTracer.HTTP_REQUEST_RESEND_COUNT)); } finally { com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(0); } @@ -1308,12 +1306,7 @@ public void testResendCountNotSetWhenDisabled() throws Exception { .findFirst() .orElse(null); assertNotNull(rpcSpan); - assertNull( - rpcSpan - .getAttributes() - .get( - BigQueryTelemetryTracer - .HTTP_REQUEST_RESEND_COUNT)); + assertNull(rpcSpan.getAttributes().get(BigQueryTelemetryTracer.HTTP_REQUEST_RESEND_COUNT)); } finally { com.google.cloud.bigquery.BigQueryRetryAlgorithm.setCurrentAttempt(0); }