Skip to content

Commit 421abc9

Browse files
committed
chore: add resend_count
1 parent b501f2a commit 421abc9

5 files changed

Lines changed: 114 additions & 23 deletions

File tree

gax-java/gax/src/main/java/com/google/api/gax/rpc/ClientContext.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
import com.google.api.gax.rpc.internal.QuotaProjectIdHidingCredentials;
4444
import com.google.api.gax.tracing.ApiTracerFactory;
4545
import com.google.api.gax.tracing.BaseApiTracerFactory;
46-
import com.google.api.gax.tracing.OpenTelemetryTracingTracerFactory;
46+
import com.google.api.gax.tracing.OpenTelemetryTracingTracer;
4747
import com.google.auth.ApiKeyCredentials;
4848
import com.google.auth.CredentialTypeForMetrics;
4949
import com.google.auth.Credentials;
@@ -273,7 +273,6 @@ public static ClientContext create(StubSettings settings) throws IOException {
273273

274274
ApiTracerFactory tracerFactory = settings.getTracerFactory();
275275
if (tracerFactory != null) {
276-
;
277276
String rpcSystem = "";
278277
if ("grpc".equals(transportChannel.getTransportName())) {
279278
rpcSystem = "grpc";
@@ -285,11 +284,9 @@ public static ClientContext create(StubSettings settings) throws IOException {
285284
tracerFactory.withAttributes(
286285
ImmutableMap.of(),
287286
ImmutableMap.of(
288-
OpenTelemetryTracingTracerFactory.SERVICE_NAME_ATTRIBUTE,
289-
settings.getServiceName(),
290-
OpenTelemetryTracingTracerFactory.PORT_ATTRIBUTE,
291-
String.valueOf(settings.getPort()),
292-
OpenTelemetryTracingTracerFactory.RPC_SYSTEM_ATTRIBUTE, rpcSystem));
287+
OpenTelemetryTracingTracer.SERVICE_NAME_ATTRIBUTE, settings.getServiceName(),
288+
OpenTelemetryTracingTracer.PORT_ATTRIBUTE, String.valueOf(settings.getPort()),
289+
OpenTelemetryTracingTracer.RPC_SYSTEM_ATTRIBUTE, rpcSystem));
293290
}
294291

295292
return newBuilder()

gax-java/gax/src/main/java/com/google/api/gax/tracing/OpenTelemetryTracingTracer.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ public class OpenTelemetryTracingTracer extends BaseApiTracer {
4141
public static final String LANGUAGE_ATTRIBUTE = "gcp.client.language";
4242
public static final String DEFAULT_LANGUAGE = "Java";
4343
public static final String ERROR_TYPE_ATTRIBUTE = "error.type";
44+
public static final String SERVICE_NAME_ATTRIBUTE = "gcp.client.service";
45+
public static final String PORT_ATTRIBUTE = "server.port";
46+
public static final String RPC_SYSTEM_ATTRIBUTE = "rpc.system";
47+
public static final String GRPC_RESEND_COUNT_ATTRIBUTE = "gcp.grpc.resend_count";
48+
public static final String HTTP_RESEND_COUNT_ATTRIBUTE = "http.request.resend_count";
4449

4550
private final TracingRecorder recorder;
4651
private final Map<String, String> operationAttributes;
@@ -58,7 +63,8 @@ public OpenTelemetryTracingTracer(
5863
this.attemptAttributes.put(LANGUAGE_ATTRIBUTE, DEFAULT_LANGUAGE);
5964
this.operationAttributes.put("method", operationSpanName);
6065

61-
// Start the long-lived operation span
66+
// Start the long-lived operation span.
67+
// TODO(diegomarquezp): This conforms with T3 and is not fully implemented
6268
this.operationHandle = recorder.startSpan(operationSpanName, operationAttributes);
6369
}
6470

@@ -75,7 +81,12 @@ public Scope inScope() {
7581
@Override
7682
public void attemptStarted(Object request, int attemptNumber) {
7783
Map<String, String> attemptAttributes = new HashMap<>(this.attemptAttributes);
78-
attemptAttributes.put("attemptNumber", String.valueOf(attemptNumber));
84+
String rpcSystem = attemptAttributes.get(RPC_SYSTEM_ATTRIBUTE);
85+
if (attemptNumber > 0 && rpcSystem != null) {
86+
attemptAttributes.put(
87+
rpcSystem.equals("grpc") ? GRPC_RESEND_COUNT_ATTRIBUTE : HTTP_RESEND_COUNT_ATTRIBUTE,
88+
String.valueOf(attemptNumber));
89+
}
7990

8091
// Start the specific attempt span with the operation span as parent
8192
this.attemptHandle = recorder.startSpan(attemptSpanName, attemptAttributes, operationHandle);

gax-java/gax/src/main/java/com/google/api/gax/tracing/OpenTelemetryTracingTracerFactory.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,6 @@
4848
@BetaApi
4949
@InternalApi
5050
public class OpenTelemetryTracingTracerFactory implements ApiTracerFactory {
51-
public static final String SERVICE_NAME_ATTRIBUTE = "gcp.client.service";
52-
public static final String PORT_ATTRIBUTE = "server.port";
53-
public static final String RPC_SYSTEM_ATTRIBUTE = "rpc.system";
54-
5551
private final TracingRecorder tracingRecorder;
5652

5753
/** Mapping of client attributes that are set for every TracingTracer at operation level */

gax-java/gax/src/test/java/com/google/api/gax/tracing/OpenTelemetryTracingTracerTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ void testAttemptLifecycle_startsAndEndsAttemptSpan() {
8686
@Test
8787
void testAddAttemptAttributes_passedToAttemptSpan() {
8888
tracer.addAttemptAttributes(ImmutableMap.of("attempt-key", "attempt-value"));
89+
tracer.addAttemptAttributes(
90+
ImmutableMap.of(OpenTelemetryTracingTracer.RPC_SYSTEM_ATTRIBUTE, "grpc"));
8991

9092
when(recorder.startSpan(eq(ATTEMPT_SPAN_NAME), anyMap(), eq(operationHandle)))
9193
.thenReturn(attemptHandle);
@@ -97,7 +99,6 @@ void testAddAttemptAttributes_passedToAttemptSpan() {
9799

98100
Map<String, String> capturedAttributes = attributesCaptor.getValue();
99101
assertThat(capturedAttributes).containsEntry("attempt-key", "attempt-value");
100-
assertThat(capturedAttributes).containsEntry("attemptNumber", "1");
101102
assertThat(capturedAttributes)
102103
.containsEntry(
103104
OpenTelemetryTracingTracer.LANGUAGE_ATTRIBUTE,

java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITOtelTracing.java

Lines changed: 95 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
5252
import java.util.List;
5353
import java.util.Map;
54+
import java.util.Objects;
5455
import org.junit.jupiter.api.AfterEach;
5556
import org.junit.jupiter.api.Assertions;
5657
import org.junit.jupiter.api.BeforeEach;
@@ -101,8 +102,6 @@ void testTracing_successfulEcho_grpc() throws Exception {
101102
.filter(span -> span.getName().equals("Echo/Echo/attempt"))
102103
.findFirst()
103104
.orElseThrow(() -> new AssertionError("Attempt span 'Echo/Echo/attempt' not found"));
104-
assertThat(attemptSpan.getAttributes().get(AttributeKey.stringKey("attemptNumber")))
105-
.isEqualTo("0");
106105
assertThat(
107106
attemptSpan
108107
.getAttributes()
@@ -111,14 +110,12 @@ void testTracing_successfulEcho_grpc() throws Exception {
111110
assertThat(
112111
attemptSpan
113112
.getAttributes()
114-
.get(AttributeKey.stringKey(OpenTelemetryTracingTracerFactory.PORT_ATTRIBUTE)))
113+
.get(AttributeKey.stringKey(OpenTelemetryTracingTracer.PORT_ATTRIBUTE)))
115114
.isEqualTo(SHOWCASE_SERVER_PORT);
116115
assertThat(
117116
attemptSpan
118117
.getAttributes()
119-
.get(
120-
AttributeKey.stringKey(
121-
OpenTelemetryTracingTracerFactory.RPC_SYSTEM_ATTRIBUTE)))
118+
.get(AttributeKey.stringKey(OpenTelemetryTracingTracer.RPC_SYSTEM_ATTRIBUTE)))
122119
.isEqualTo("grpc");
123120
}
124121
}
@@ -144,9 +141,7 @@ void testTracing_successfulEcho_httpjson() throws Exception {
144141
assertThat(
145142
attemptSpan
146143
.getAttributes()
147-
.get(
148-
AttributeKey.stringKey(
149-
OpenTelemetryTracingTracerFactory.RPC_SYSTEM_ATTRIBUTE)))
144+
.get(AttributeKey.stringKey(OpenTelemetryTracingTracer.RPC_SYSTEM_ATTRIBUTE)))
150145
.isEqualTo("http");
151146
}
152147
}
@@ -201,6 +196,97 @@ void testTracing_errorRecording() throws Exception {
201196
}
202197
}
203198

199+
@Test
200+
void testTracing_resendCount_grpc() throws Exception {
201+
OpenTelemetryTracingTracerFactory tracingFactory =
202+
new OpenTelemetryTracingTracerFactory(new OpenTelemetryTracingRecorder(openTelemetrySdk));
203+
204+
try (EchoClient client =
205+
TestClientInitializer.createGrpcEchoClientOpentelemetry(tracingFactory)) {
206+
207+
// Simulate UNAVAILABLE to trigger retries
208+
Assertions.assertThrows(
209+
Exception.class,
210+
() ->
211+
client.echo(
212+
EchoRequest.newBuilder()
213+
.setContent("resend-test-grpc")
214+
.setError(
215+
Status.newBuilder()
216+
.setCode(StatusCode.Code.UNAVAILABLE.ordinal())
217+
.build())
218+
.build()));
219+
220+
List<SpanData> spans = spanExporter.getFinishedSpanItems();
221+
assertThat(spans).isNotEmpty();
222+
223+
// Verify that subsequent attempts have gcp.grpc.resend_count
224+
SpanData secondAttempt =
225+
spans.stream()
226+
.filter(
227+
span ->
228+
span.getName().equals("Echo/Echo/attempt")
229+
&& Objects.equals(
230+
span.getAttributes()
231+
.get(
232+
AttributeKey.stringKey(
233+
OpenTelemetryTracingTracer.GRPC_RESEND_COUNT_ATTRIBUTE)),
234+
"1"))
235+
.findFirst()
236+
.orElseThrow(() -> new AssertionError("Second attempt span not found"));
237+
238+
assertThat(secondAttempt.getAttributes().get(AttributeKey.stringKey("gcp.grpc.resend_count")))
239+
.isEqualTo("1");
240+
}
241+
}
242+
243+
@Test
244+
void testTracing_resendCount_httpjson() throws Exception {
245+
OpenTelemetryTracingTracerFactory tracingFactory =
246+
new OpenTelemetryTracingTracerFactory(new OpenTelemetryTracingRecorder(openTelemetrySdk));
247+
248+
try (EchoClient client =
249+
TestClientInitializer.createHttpJsonEchoClientOpentelemetry(tracingFactory)) {
250+
251+
// Simulate UNAVAILABLE to trigger retries
252+
Assertions.assertThrows(
253+
Exception.class,
254+
() ->
255+
client.echo(
256+
EchoRequest.newBuilder()
257+
.setContent("resend-test-http")
258+
.setError(
259+
Status.newBuilder()
260+
.setCode(StatusCode.Code.UNAVAILABLE.ordinal())
261+
.build())
262+
.build()));
263+
264+
List<SpanData> spans = spanExporter.getFinishedSpanItems();
265+
assertThat(spans).isNotEmpty();
266+
267+
// Verify that subsequent attempts have http.request.resend_count
268+
SpanData secondAttempt =
269+
spans.stream()
270+
.filter(
271+
span ->
272+
span.getName().equals("google.showcase.v1beta1/Echo/Echo/attempt")
273+
&& Objects.equals(
274+
span.getAttributes()
275+
.get(
276+
AttributeKey.stringKey(
277+
OpenTelemetryTracingTracer.HTTP_RESEND_COUNT_ATTRIBUTE)),
278+
"1"))
279+
.findFirst()
280+
.orElseThrow(() -> new AssertionError("Second attempt span not found"));
281+
282+
assertThat(
283+
secondAttempt
284+
.getAttributes()
285+
.get(AttributeKey.stringKey("http.request.resend_count")))
286+
.isEqualTo("1");
287+
}
288+
}
289+
204290
@Test
205291
void testTracing_withCustomAttributes() throws Exception {
206292
Map<String, String> opAttributes = ImmutableMap.of("op-key", "op-value");

0 commit comments

Comments
 (0)