Skip to content

Commit e0a33f2

Browse files
refactor(o11y): merge SpanTracer and SpanManager (#4158)
1 parent 8a9a719 commit e0a33f2

File tree

8 files changed

+176
-369
lines changed

8 files changed

+176
-369
lines changed

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

Lines changed: 0 additions & 79 deletions
This file was deleted.

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

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,52 +32,87 @@
3232

3333
import com.google.api.core.BetaApi;
3434
import com.google.api.core.InternalApi;
35+
import io.opentelemetry.api.trace.Span;
36+
import io.opentelemetry.api.trace.SpanBuilder;
37+
import io.opentelemetry.api.trace.SpanKind;
38+
import io.opentelemetry.api.trace.Tracer;
3539
import java.util.HashMap;
3640
import java.util.Map;
3741

38-
/**
39-
* An implementation of {@link ApiTracer} that uses a {@link TraceManager} to record traces. This
40-
* implementation is agnostic to the specific {@link TraceManager} in order to allow extensions that
41-
* interact with other backends.
42-
*/
42+
/** An implementation of {@link ApiTracer} that uses OpenTelemetry to record traces. */
4343
@BetaApi
4444
@InternalApi
4545
public class SpanTracer implements ApiTracer {
4646
public static final String LANGUAGE_ATTRIBUTE = "gcp.client.language";
4747

4848
public static final String DEFAULT_LANGUAGE = "Java";
4949

50-
private final TraceManager traceManager;
50+
private final Tracer tracer;
5151
private final Map<String, Object> attemptAttributes;
5252
private final String attemptSpanName;
5353
private final ApiTracerContext apiTracerContext;
54-
private TraceManager.Span attemptHandle;
54+
private Span attemptSpan;
5555

5656
/**
5757
* Creates a new instance of {@code SpanTracer}.
5858
*
59-
* @param traceManager the {@link TraceManager} to use for recording spans
59+
* @param tracer the {@link Tracer} to use for recording spans
60+
* @param apiTracerContext the {@link ApiTracerContext} to use for recording spans
61+
*/
62+
public SpanTracer(Tracer tracer, ApiTracerContext apiTracerContext) {
63+
this.tracer = tracer;
64+
this.apiTracerContext = apiTracerContext;
65+
this.attemptSpanName = resolveAttemptSpanName(apiTracerContext);
66+
this.attemptAttributes = new HashMap<>();
67+
buildAttributes();
68+
}
69+
70+
/**
71+
* Creates a new instance of {@code SpanTracer} with an explicitly provided span name.
72+
*
73+
* @param tracer the {@link Tracer} to use for recording spans
74+
* @param apiTracerContext the {@link ApiTracerContext} to use for recording spans
6075
* @param attemptSpanName the name of the individual attempt spans
6176
*/
62-
public SpanTracer(
63-
TraceManager traceManager, ApiTracerContext apiTracerContext, String attemptSpanName) {
64-
this.traceManager = traceManager;
77+
@InternalApi
78+
SpanTracer(Tracer tracer, ApiTracerContext apiTracerContext, String attemptSpanName) {
79+
this.tracer = tracer;
6580
this.attemptSpanName = attemptSpanName;
6681
this.apiTracerContext = apiTracerContext;
6782
this.attemptAttributes = new HashMap<>();
6883
buildAttributes();
6984
}
7085

86+
private static String resolveAttemptSpanName(ApiTracerContext apiTracerContext) {
87+
if (apiTracerContext.transport() == ApiTracerContext.Transport.GRPC) {
88+
// gRPC Uses the full method name as span name.
89+
return apiTracerContext.fullMethodName();
90+
} else if (apiTracerContext.httpMethod() == null
91+
|| apiTracerContext.httpPathTemplate() == null) {
92+
// HTTP method name without necessary components defaults to the full method name
93+
return apiTracerContext.fullMethodName();
94+
} else {
95+
// We construct the span name with HTTP method and path template.
96+
return String.format(
97+
"%s %s", apiTracerContext.httpMethod(), apiTracerContext.httpPathTemplate());
98+
}
99+
}
100+
71101
private void buildAttributes() {
72102
this.attemptAttributes.put(LANGUAGE_ATTRIBUTE, DEFAULT_LANGUAGE);
73103
this.attemptAttributes.putAll(this.apiTracerContext.getAttemptAttributes());
74104
}
75105

76106
@Override
77107
public void attemptStarted(Object request, int attemptNumber) {
78-
Map<String, Object> attemptAttributes = new HashMap<>(this.attemptAttributes);
79-
// Start the specific attempt span with the operation span as parent
80-
this.attemptHandle = traceManager.createSpan(attemptSpanName, attemptAttributes);
108+
SpanBuilder spanBuilder = tracer.spanBuilder(attemptSpanName);
109+
110+
// Attempt spans are of the CLIENT kind
111+
spanBuilder.setSpanKind(SpanKind.CLIENT);
112+
113+
spanBuilder.setAllAttributes(ObservabilityUtils.toOtelAttributes(this.attemptAttributes));
114+
115+
this.attemptSpan = spanBuilder.startSpan();
81116
}
82117

83118
@Override
@@ -86,9 +121,9 @@ public void attemptSucceeded() {
86121
}
87122

88123
private void endAttempt() {
89-
if (attemptHandle != null) {
90-
attemptHandle.end();
91-
attemptHandle = null;
124+
if (attemptSpan != null) {
125+
attemptSpan.end();
126+
attemptSpan = null;
92127
}
93128
}
94129
}

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

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,27 @@
3333
import com.google.api.core.BetaApi;
3434
import com.google.api.core.InternalApi;
3535
import com.google.common.annotations.VisibleForTesting;
36+
import io.opentelemetry.api.OpenTelemetry;
37+
import io.opentelemetry.api.trace.Tracer;
3638

3739
/**
3840
* A {@link ApiTracerFactory} to build instances of {@link SpanTracer}.
3941
*
40-
* <p>This class wraps the {@link TraceManager} and pass it to {@link SpanTracer}. It will be used
41-
* to record traces in {@link SpanTracer}.
42+
* <p>This class wraps the {@link Tracer} and pass it to {@link SpanTracer}. It will be used to
43+
* record traces in {@link SpanTracer}.
4244
*
4345
* <p>This class is expected to be initialized once during client initialization.
4446
*/
4547
@BetaApi
4648
@InternalApi
4749
public class SpanTracerFactory implements ApiTracerFactory {
48-
private final TraceManager traceManager;
50+
private final Tracer tracer;
4951

5052
private final ApiTracerContext apiTracerContext;
5153

5254
/** Creates a SpanTracerFactory */
53-
public SpanTracerFactory(TraceManager traceManager) {
54-
this(traceManager, ApiTracerContext.empty());
55+
public SpanTracerFactory(OpenTelemetry openTelemetry) {
56+
this(openTelemetry.getTracer("gax-java"), ApiTracerContext.empty());
5557
}
5658

5759
/**
@@ -60,8 +62,8 @@ public SpanTracerFactory(TraceManager traceManager) {
6062
* internally.
6163
*/
6264
@VisibleForTesting
63-
SpanTracerFactory(TraceManager traceManager, ApiTracerContext apiTracerContext) {
64-
this.traceManager = traceManager;
65+
SpanTracerFactory(Tracer tracer, ApiTracerContext apiTracerContext) {
66+
this.tracer = tracer;
6567
this.apiTracerContext = apiTracerContext;
6668
}
6769

@@ -71,28 +73,13 @@ public ApiTracer newTracer(ApiTracer parent, SpanName spanName, OperationType op
7173
// feature is developed.
7274
String attemptSpanName = spanName.getClientName() + "/" + spanName.getMethodName() + "/attempt";
7375

74-
SpanTracer spanTracer = new SpanTracer(traceManager, this.apiTracerContext, attemptSpanName);
75-
return spanTracer;
76+
return new SpanTracer(tracer, this.apiTracerContext, attemptSpanName);
7677
}
7778

7879
@Override
7980
public ApiTracer newTracer(ApiTracer parent, ApiTracerContext apiTracerContext) {
8081
ApiTracerContext mergedContext = this.apiTracerContext.merge(apiTracerContext);
81-
82-
String attemptSpanName;
83-
if (mergedContext.transport() == ApiTracerContext.Transport.GRPC) {
84-
// gRPC Uses the full method name as span name.
85-
attemptSpanName = mergedContext.fullMethodName();
86-
} else if (mergedContext.httpMethod() == null || mergedContext.httpPathTemplate() == null) {
87-
// HTTP method name without necessary components defaults to the full method name
88-
attemptSpanName = mergedContext.fullMethodName();
89-
} else {
90-
// We construct the span name with HTTP method and path template.
91-
attemptSpanName =
92-
String.format("%s %s", mergedContext.httpMethod(), mergedContext.httpPathTemplate());
93-
}
94-
95-
return new SpanTracer(traceManager, mergedContext, attemptSpanName);
82+
return new SpanTracer(tracer, mergedContext);
9683
}
9784

9885
@Override
@@ -102,6 +89,6 @@ public ApiTracerContext getApiTracerContext() {
10289

10390
@Override
10491
public ApiTracerFactory withContext(ApiTracerContext context) {
105-
return new SpanTracerFactory(traceManager, apiTracerContext.merge(context));
92+
return new SpanTracerFactory(tracer, apiTracerContext.merge(context));
10693
}
10794
}

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

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)