Skip to content
This repository was archived by the owner on Mar 23, 2026. It is now read-only.

Commit 4202fb3

Browse files
committed
cleaned up code + added suggestions from gemini
1 parent 4faaa82 commit 4202fb3

5 files changed

Lines changed: 298 additions & 290 deletions

File tree

google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/spi/v2/HttpBigQueryRpc.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,16 +107,19 @@ public HttpBigQueryRpc(BigQueryOptions options) {
107107
HttpTransportOptions transportOptions = (HttpTransportOptions) options.getTransportOptions();
108108
HttpTransport transport = transportOptions.getHttpTransportFactory().create();
109109
HttpRequestInitializer initializer = transportOptions.getHttpRequestInitializer(options);
110-
110+
111+
String resolvedBigQueryRootUrl = options.getResolvedApiaryHost("bigquery");
111112
// Wrap with tracing initializer if OpenTelemetry is enabled
112113
if (options.isOpenTelemetryTracingEnabled() && options.getOpenTelemetryTracer() != null) {
113-
initializer = new HttpTracingRequestInitializer(initializer, options.getOpenTelemetryTracer());
114+
initializer =
115+
new HttpTracingRequestInitializer(
116+
initializer, options.getOpenTelemetryTracer(), resolvedBigQueryRootUrl);
114117
}
115-
118+
116119
this.options = options;
117120
bigquery =
118121
new Bigquery.Builder(transport, new GsonFactory(), initializer)
119-
.setRootUrl(options.getResolvedApiaryHost("bigquery"))
122+
.setRootUrl(resolvedBigQueryRootUrl)
120123
.setApplicationName(options.getApplicationName())
121124
.build();
122125
}

google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/spi/v2/HttpTracingRequestInitializer.java

Lines changed: 103 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@
1919
import com.google.api.client.http.*;
2020
import com.google.api.core.InternalApi;
2121
import com.google.cloud.bigquery.telemetry.BigQueryTelemetryTracer;
22+
import com.google.common.annotations.VisibleForTesting;
2223
import io.opentelemetry.api.common.AttributeKey;
2324
import io.opentelemetry.api.trace.Span;
2425
import io.opentelemetry.api.trace.StatusCode;
2526
import io.opentelemetry.api.trace.Tracer;
26-
import org.checkerframework.checker.nullness.qual.Nullable;
27-
2827
import java.io.IOException;
28+
import org.jspecify.annotations.Nullable;
2929

3030
/**
3131
* HttpRequestInitializer that wraps a delegate initializer, intercepts all HTTP requests, adds
@@ -49,13 +49,17 @@ public class HttpTracingRequestInitializer implements HttpRequestInitializer {
4949
public static final AttributeKey<Long> HTTP_RESPONSE_BODY_SIZE =
5050
AttributeKey.longKey("http.response.body.size");
5151

52+
@VisibleForTesting static final String HTTP_RPC_SYSTEM_NAME = "http";
53+
5254
private final HttpRequestInitializer delegate;
5355
private final Tracer tracer;
54-
private static final String BIGQUERY_DOMAIN = "bigquery.googleapis.com";
56+
private final @Nullable String clientRootUrl;
5557

56-
public HttpTracingRequestInitializer(HttpRequestInitializer delegate, Tracer tracer) {
58+
public HttpTracingRequestInitializer(
59+
HttpRequestInitializer delegate, Tracer tracer, @Nullable String clientRootUrl) {
5760
this.delegate = delegate;
5861
this.tracer = tracer;
62+
this.clientRootUrl = clientRootUrl;
5963
}
6064

6165
@Override
@@ -73,29 +77,35 @@ public void initialize(HttpRequest request) throws IOException {
7377
String host = request.getUrl().getHost();
7478
Integer port = request.getUrl().getPort();
7579

76-
Long requestBodySize = getRequestBodySize(request);
77-
78-
Span span = getSpan(httpMethod, url, host, port, requestBodySize);
80+
Span span = createHttpTraceSpan(httpMethod, url, host, port);
7981

8082
// Wrap the existing response interceptor
8183
HttpResponseInterceptor originalInterceptor = request.getResponseInterceptor();
8284
request.setResponseInterceptor(
8385
response -> {
84-
try {
85-
addSuccessResponseToSpan(response, httpMethod, span);
86-
if (originalInterceptor != null) {
87-
originalInterceptor.interceptResponse(response);
86+
if (span.isRecording()) {
87+
try {
88+
int statusCode = response.getStatusCode();
89+
addCommonResponseAttributesToSpan(request, response, span, httpMethod, statusCode);
90+
addSuccessResponseToSpan(response, span, statusCode);
91+
if (originalInterceptor != null) {
92+
originalInterceptor.interceptResponse(response);
93+
}
94+
} finally {
95+
span.end();
8896
}
89-
} finally {
90-
span.end();
97+
} else if (originalInterceptor != null) {
98+
originalInterceptor.interceptResponse(response);
9199
}
92100
});
93101

94102
// Wrap the existing unsuccessful response handler
95103
HttpUnsuccessfulResponseHandler originalHandler = request.getUnsuccessfulResponseHandler();
96104
request.setUnsuccessfulResponseHandler(
97105
(request1, response, supportsRetry) -> {
98-
addErrorResponseToSpan(response, span);
106+
int statusCode = response.getStatusCode();
107+
addCommonResponseAttributesToSpan(request, response, span, httpMethod, statusCode);
108+
addErrorResponseToSpan(response, span, statusCode);
99109
try {
100110
if (originalHandler != null) {
101111
return originalHandler.handleResponse(request1, response, supportsRetry);
@@ -105,24 +115,75 @@ public void initialize(HttpRequest request) throws IOException {
105115
addExceptionToSpan(e, span);
106116
throw e;
107117
} finally {
108-
span.end();
118+
if (span.isRecording()) {
119+
span.end();
120+
}
109121
}
110122
});
111123
}
112124

125+
/** Initial HTTP trace span creation with basic attributes from request */
126+
private Span createHttpTraceSpan(String httpMethod, String url, String host, Integer port) {
127+
// TODO: Determine span name: {method} {url.template} or {method}
128+
Span span =
129+
BigQueryTelemetryTracer.newSpanBuilder(tracer, httpMethod)
130+
.setAttribute(HTTP_REQUEST_METHOD, httpMethod)
131+
.setAttribute(URL_FULL, url)
132+
.setAttribute(BigQueryTelemetryTracer.SERVER_ADDRESS, host)
133+
.setAttribute(URL_DOMAIN, resolveUrlDomain(host))
134+
.setAttribute(BigQueryTelemetryTracer.RPC_SYSTEM_NAME, HTTP_RPC_SYSTEM_NAME)
135+
.startSpan();
136+
137+
// TODO: add url template && resource name
138+
if (port != null && port > 0) {
139+
span.setAttribute(BigQueryTelemetryTracer.SERVER_PORT, port.longValue());
140+
}
141+
return span;
142+
}
143+
144+
private String resolveUrlDomain(String requestHost) {
145+
if (clientRootUrl != null) {
146+
try {
147+
String configuredHost = new GenericUrl(clientRootUrl).getHost();
148+
if (configuredHost != null && !configuredHost.isEmpty()) {
149+
return configuredHost;
150+
}
151+
} catch (IllegalArgumentException ex) {
152+
// Ignore malformed configured root URL and fall back to request host.
153+
}
154+
}
155+
return requestHost;
156+
}
157+
158+
private static void addCommonResponseAttributesToSpan(
159+
HttpRequest request, HttpResponse response, Span span, String httpMethod, int statusCode) {
160+
// This is called after we get a response as sometimes the request body size isn't available
161+
// before the response is received.
162+
addRequestBodySizeToSpan(request, span);
163+
checkForUpdatedRequestMethod(response, httpMethod, span);
164+
setResponseBodySize(response, span);
165+
span.setAttribute(HTTP_RESPONSE_STATUS_CODE, statusCode);
166+
}
167+
168+
private static void addSuccessResponseToSpan(HttpResponse response, Span span, int statusCode) {
169+
if (statusCode >= 400) {
170+
addErrorResponseToSpan(response, span, statusCode);
171+
} else {
172+
span.setStatus(StatusCode.OK);
173+
}
174+
}
175+
113176
private static void addExceptionToSpan(IOException e, Span span) {
114177
span.recordException(e);
178+
String message = e.getMessage();
179+
String statusMessage = message != null ? message : e.getClass().getName();
115180
span.setAttribute(BigQueryTelemetryTracer.EXCEPTION_TYPE, e.getClass().getName());
116181
span.setAttribute(BigQueryTelemetryTracer.ERROR_TYPE, e.getClass().getSimpleName());
117-
span.setAttribute(
118-
BigQueryTelemetryTracer.STATUS_MESSAGE,
119-
e.getMessage() != null ? e.getMessage() : e.getClass().getName());
120-
span.setStatus(StatusCode.ERROR, e.getMessage());
182+
span.setAttribute(BigQueryTelemetryTracer.STATUS_MESSAGE, statusMessage);
183+
span.setStatus(StatusCode.ERROR, statusMessage);
121184
}
122185

123-
private static void addErrorResponseToSpan(HttpResponse response, Span span) {
124-
int statusCode = response.getStatusCode();
125-
span.setAttribute(HTTP_RESPONSE_STATUS_CODE, statusCode);
186+
private static void addErrorResponseToSpan(HttpResponse response, Span span, int statusCode) {
126187
String errorMessage = "HTTP " + statusCode;
127188
try {
128189
String statusMessage = response.getStatusMessage();
@@ -137,63 +198,39 @@ private static void addErrorResponseToSpan(HttpResponse response, Span span) {
137198
span.setStatus(StatusCode.ERROR, errorMessage);
138199
}
139200

140-
private static void addSuccessResponseToSpan(
141-
HttpResponse response, String httpMethod, Span span) {
142-
String actualMethod = response.getRequest().getRequestMethod();
143-
if (actualMethod != null && httpMethod == null) {
144-
span.updateName(actualMethod);
145-
span.setAttribute(HTTP_REQUEST_METHOD, actualMethod);
146-
}
147-
int statusCode = response.getStatusCode();
148-
span.setAttribute(HTTP_RESPONSE_STATUS_CODE, statusCode);
201+
private static void addRequestBodySizeToSpan(HttpRequest request, Span span) {
202+
Long requestBodySize = null;
149203
try {
150-
long contentLength = response.getHeaders().getContentLength();
151-
if (contentLength > 0) {
152-
span.setAttribute(HTTP_RESPONSE_BODY_SIZE, contentLength);
204+
HttpContent content = request.getContent();
205+
206+
if (content != null) {
207+
requestBodySize = content.getLength();
153208
}
154209
} catch (Exception e) {
155210
// Ignore - body size not available
156211
}
157-
if (statusCode >= 400) {
158-
addErrorResponseToSpan(response, span);
159-
} else {
160-
span.setStatus(StatusCode.OK);
161-
}
162-
}
163-
164-
private Span getSpan(
165-
String httpMethod, String url, String host, Integer port, Long requestBodySize) {
166-
// TODO: Determine span name: {method} {url.template} or {method}
167-
Span span =
168-
BigQueryTelemetryTracer.newSpanBuilder(tracer, httpMethod)
169-
// OpenTelemetry semantic convention attributes
170-
.setAttribute(HTTP_REQUEST_METHOD, httpMethod)
171-
.setAttribute(URL_FULL, url)
172-
.setAttribute(BigQueryTelemetryTracer.SERVER_ADDRESS, host)
173-
.setAttribute(URL_DOMAIN, BIGQUERY_DOMAIN)
174-
.setAttribute(BigQueryTelemetryTracer.RPC_SYSTEM_NAME, "http")
175-
.startSpan();
176-
177-
// TODO: add url template && resource name
178-
if (port != null && port > 0) {
179-
span.setAttribute(BigQueryTelemetryTracer.SERVER_PORT, port.longValue());
180-
}
181-
if (requestBodySize != null && requestBodySize > 0) {
212+
if (requestBodySize != null) {
182213
span.setAttribute(HTTP_REQUEST_BODY_SIZE, requestBodySize);
183214
}
184-
return span;
185215
}
186216

187-
private static @Nullable Long getRequestBodySize(HttpRequest request) {
188-
Long requestBodySize = null;
217+
private static void setResponseBodySize(HttpResponse response, Span span) {
189218
try {
190-
HttpContent content = request.getContent();
191-
if (content != null) {
192-
requestBodySize = content.getLength();
219+
long contentLength = response.getHeaders().getContentLength();
220+
if (contentLength > 0) {
221+
span.setAttribute(HTTP_RESPONSE_BODY_SIZE, contentLength);
193222
}
194223
} catch (Exception e) {
195224
// Ignore - body size not available
196225
}
197-
return requestBodySize;
226+
}
227+
228+
private static void checkForUpdatedRequestMethod(
229+
HttpResponse response, String httpMethod, Span span) {
230+
String actualMethod = response.getRequest().getRequestMethod();
231+
if (actualMethod != null && httpMethod == null) {
232+
span.updateName(actualMethod);
233+
span.setAttribute(HTTP_REQUEST_METHOD, actualMethod);
234+
}
198235
}
199236
}

google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/telemetry/BigQueryTelemetryTracer.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ public final class BigQueryTelemetryTracer {
3131

3232
private BigQueryTelemetryTracer() {}
3333

34+
public static final String BQ_GCP_CLIENT_SERVICE = "bigquery";
35+
public static final String BQ_GCP_CLIENT_REPO = "googleapis/java-bigquery";
36+
public static final String BQ_GCP_CLIENT_ARTIFACT = "google-cloud-bigquery";
37+
public static final String BQ_GCP_CLIENT_LANGUAGE = "java";
38+
3439
// Common GCP Attributes
3540
public static final AttributeKey<String> GCP_CLIENT_SERVICE =
3641
AttributeKey.stringKey("gcp.client.service");
@@ -63,10 +68,10 @@ public static SpanBuilder newSpanBuilder(Tracer tracer, String spanName) {
6368
return tracer
6469
.spanBuilder(spanName)
6570
.setSpanKind(SpanKind.CLIENT)
66-
.setAttribute(GCP_CLIENT_SERVICE, "bigquery")
67-
.setAttribute(GCP_CLIENT_REPO, "googleapis/java-bigquery")
68-
.setAttribute(GCP_CLIENT_ARTIFACT, "google-cloud-bigquery")
69-
.setAttribute(GCP_CLIENT_LANGUAGE, "java");
71+
.setAttribute(GCP_CLIENT_SERVICE, BQ_GCP_CLIENT_SERVICE)
72+
.setAttribute(GCP_CLIENT_REPO, BQ_GCP_CLIENT_REPO)
73+
.setAttribute(GCP_CLIENT_ARTIFACT, BQ_GCP_CLIENT_ARTIFACT)
74+
.setAttribute(GCP_CLIENT_LANGUAGE, BQ_GCP_CLIENT_LANGUAGE);
7075
// TODO: add version
7176
}
7277
}

0 commit comments

Comments
 (0)