From 64377a520e7dc3f42d2c476d5b64803814d5d0d3 Mon Sep 17 00:00:00 2001 From: blakeli Date: Mon, 16 Mar 2026 18:04:38 -0400 Subject: [PATCH 1/4] fix: Add method level ApiTracerContext to metrics. --- .../GoldenSignalsMetricsTracerFactory.java | 21 ++++++++++---- ...GoldenSignalsMetricsTracerFactoryTest.java | 28 +++++++++++++++++-- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/gax-java/gax/src/main/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactory.java b/gax-java/gax/src/main/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactory.java index 1ef4e1112f..53b8998a86 100644 --- a/gax-java/gax/src/main/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactory.java +++ b/gax-java/gax/src/main/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactory.java @@ -42,13 +42,13 @@ @InternalApi public class GoldenSignalsMetricsTracerFactory implements ApiTracerFactory { - private ApiTracerContext apiTracerContext; + private ApiTracerContext clientLevelTracerContext; private final OpenTelemetry openTelemetry; private GoldenSignalsMetricsRecorder metricsRecorder; public GoldenSignalsMetricsTracerFactory(OpenTelemetry openTelemetry) { this.openTelemetry = openTelemetry; - this.apiTracerContext = ApiTracerContext.empty(); + this.clientLevelTracerContext = ApiTracerContext.empty(); } @Override @@ -58,15 +58,26 @@ public ApiTracer newTracer(ApiTracer parent, SpanName spanName, OperationType op // regular requests. return new BaseApiTracer(); } - return new GoldenSignalsMetricsTracer(metricsRecorder, apiTracerContext); + return new GoldenSignalsMetricsTracer(metricsRecorder, clientLevelTracerContext); + } + + @Override + public ApiTracer newTracer(ApiTracer parent, ApiTracerContext methodLevelTracerContext) { + if (metricsRecorder == null) { + // This should never happen, in case it happens, create a no-op api tracer to not block + // regular requests. + return new BaseApiTracer(); + } + ApiTracerContext mergedTracerContext = clientLevelTracerContext.merge(methodLevelTracerContext); + return new GoldenSignalsMetricsTracer(metricsRecorder, mergedTracerContext); } @Override public ApiTracerFactory withContext(ApiTracerContext context) { - this.apiTracerContext = context; + this.clientLevelTracerContext = context; this.metricsRecorder = new GoldenSignalsMetricsRecorder( - openTelemetry, apiTracerContext.libraryMetadata().artifactName()); + openTelemetry, clientLevelTracerContext.libraryMetadata().artifactName()); return this; } } diff --git a/gax-java/gax/src/test/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java b/gax-java/gax/src/test/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java index 8a39ff27f1..0348fffe96 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java @@ -29,13 +29,15 @@ */ package com.google.api.gax.tracing; -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.mock; - import io.opentelemetry.api.OpenTelemetry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Answers.RETURNS_DEEP_STUBS; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + class GoldenSignalsMetricsTracerFactoryTest { private GoldenSignalsMetricsTracerFactory tracerFactory; @@ -61,4 +63,24 @@ void newTracer_createsBaseTracer_ifMetricsRecorderIsNull() { mock(ApiTracer.class), mock(SpanName.class), ApiTracerFactory.OperationType.Unary); assertThat(actual).isInstanceOf(BaseApiTracer.class); } + + @Test + void newTracer_shouldMergeApiTracerContext() { + ApiTracerContext clientLevelTracerContext = mock(ApiTracerContext.class, RETURNS_DEEP_STUBS); + ApiTracerContext methodLevelTracerContext = mock(ApiTracerContext.class); + when(clientLevelTracerContext.libraryMetadata().artifactName()).thenReturn("does not matter"); + when(clientLevelTracerContext.merge(methodLevelTracerContext)).thenReturn(clientLevelTracerContext); + + tracerFactory.withContext(clientLevelTracerContext); + ApiTracer actual = tracerFactory.newTracer(mock(ApiTracer.class), methodLevelTracerContext); + + assertThat(actual).isInstanceOf(GoldenSignalsMetricsTracer.class); + } + + @Test + void newTracer1_createsBaseTracer_ifMetricsRecorderIsNull() { + ApiTracer actual = tracerFactory.newTracer(mock(ApiTracer.class), mock(ApiTracerContext.class)); + + assertThat(actual).isInstanceOf(BaseApiTracer.class); + } } From 1440456147319fe8992cd1097018c5754f9889b8 Mon Sep 17 00:00:00 2001 From: blakeli Date: Mon, 16 Mar 2026 18:05:06 -0400 Subject: [PATCH 2/4] fix: format. --- .../GoldenSignalsMetricsTracerFactoryTest.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/gax-java/gax/src/test/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java b/gax-java/gax/src/test/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java index 0348fffe96..f648288c65 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java @@ -29,15 +29,15 @@ */ package com.google.api.gax.tracing; -import io.opentelemetry.api.OpenTelemetry; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - import static com.google.common.truth.Truth.assertThat; import static org.mockito.Answers.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import io.opentelemetry.api.OpenTelemetry; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + class GoldenSignalsMetricsTracerFactoryTest { private GoldenSignalsMetricsTracerFactory tracerFactory; @@ -69,7 +69,8 @@ void newTracer_shouldMergeApiTracerContext() { ApiTracerContext clientLevelTracerContext = mock(ApiTracerContext.class, RETURNS_DEEP_STUBS); ApiTracerContext methodLevelTracerContext = mock(ApiTracerContext.class); when(clientLevelTracerContext.libraryMetadata().artifactName()).thenReturn("does not matter"); - when(clientLevelTracerContext.merge(methodLevelTracerContext)).thenReturn(clientLevelTracerContext); + when(clientLevelTracerContext.merge(methodLevelTracerContext)) + .thenReturn(clientLevelTracerContext); tracerFactory.withContext(clientLevelTracerContext); ApiTracer actual = tracerFactory.newTracer(mock(ApiTracer.class), methodLevelTracerContext); From 427877e076eaab1376c05c9c1c0dd1901a9e22f5 Mon Sep 17 00:00:00 2001 From: blakeli Date: Mon, 16 Mar 2026 18:44:47 -0400 Subject: [PATCH 3/4] fix: rename tests. --- .../tracing/GoldenSignalsMetricsTracerFactoryTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gax-java/gax/src/test/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java b/gax-java/gax/src/test/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java index f648288c65..8e77f21240 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java @@ -48,7 +48,7 @@ void setUp() { } @Test - void newTracer_createsTracer_successfully() { + void newTracerWithSpanName_shouldCreateTracer_ifMetricsRecorderIsNotNull() { tracerFactory.withContext(ApiTracerContext.empty()); ApiTracer actual = tracerFactory.newTracer( @@ -57,7 +57,7 @@ void newTracer_createsTracer_successfully() { } @Test - void newTracer_createsBaseTracer_ifMetricsRecorderIsNull() { + void newTracerWithSpanName_shouldCreateBaseTracer_ifMetricsRecorderIsNull() { ApiTracer actual = tracerFactory.newTracer( mock(ApiTracer.class), mock(SpanName.class), ApiTracerFactory.OperationType.Unary); @@ -65,7 +65,7 @@ void newTracer_createsBaseTracer_ifMetricsRecorderIsNull() { } @Test - void newTracer_shouldMergeApiTracerContext() { + void newTracerWithApiTracerContext_shouldMergeApiTracerContext() { ApiTracerContext clientLevelTracerContext = mock(ApiTracerContext.class, RETURNS_DEEP_STUBS); ApiTracerContext methodLevelTracerContext = mock(ApiTracerContext.class); when(clientLevelTracerContext.libraryMetadata().artifactName()).thenReturn("does not matter"); @@ -79,7 +79,7 @@ void newTracer_shouldMergeApiTracerContext() { } @Test - void newTracer1_createsBaseTracer_ifMetricsRecorderIsNull() { + void newTracerWithApiTracerContext_shouldCreateBaseTracer_ifMetricsRecorderIsNull() { ApiTracer actual = tracerFactory.newTracer(mock(ApiTracer.class), mock(ApiTracerContext.class)); assertThat(actual).isInstanceOf(BaseApiTracer.class); From 054f8811ab36d68f908077cb9526914c500a102e Mon Sep 17 00:00:00 2001 From: blakeli Date: Tue, 17 Mar 2026 12:37:23 -0400 Subject: [PATCH 4/4] fix: Add verify in tests --- .../gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gax-java/gax/src/test/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java b/gax-java/gax/src/test/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java index 8e77f21240..9726101c07 100644 --- a/gax-java/gax/src/test/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java +++ b/gax-java/gax/src/test/java/com/google/api/gax/tracing/GoldenSignalsMetricsTracerFactoryTest.java @@ -31,8 +31,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Answers.RETURNS_DEEP_STUBS; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; import io.opentelemetry.api.OpenTelemetry; import org.junit.jupiter.api.BeforeEach; @@ -75,6 +74,7 @@ void newTracerWithApiTracerContext_shouldMergeApiTracerContext() { tracerFactory.withContext(clientLevelTracerContext); ApiTracer actual = tracerFactory.newTracer(mock(ApiTracer.class), methodLevelTracerContext); + verify(clientLevelTracerContext).merge(methodLevelTracerContext); assertThat(actual).isInstanceOf(GoldenSignalsMetricsTracer.class); }