Skip to content

Commit b4eef51

Browse files
committed
feat(bigquery): add url.full attribute to tracing span
1 parent 863d23b commit b4eef51

2 files changed

Lines changed: 73 additions & 7 deletions

File tree

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

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ public class HttpTracingRequestInitializer implements HttpRequestInitializer {
5252

5353
@VisibleForTesting static final String HTTP_RPC_SYSTEM_NAME = "http";
5454

55+
private static final java.util.Set<String> REDACTED_QUERY_PARAMETERS =
56+
com.google.common.collect.ImmutableSet.of(
57+
"AWSAccessKeyId", "Signature", "sig", "X-Goog-Signature", "upload_id");
58+
5559
private final HttpRequestInitializer delegate;
5660
private final Tracer tracer;
5761

@@ -74,9 +78,7 @@ public void initialize(HttpRequest request) throws IOException {
7478
// No active span to exists, skip instrumentation
7579
return;
7680
}
77-
String host = request.getUrl().getHost();
78-
int port = request.getUrl().getPort();
79-
addInitialHttpAttributesToSpan(span, host, port);
81+
addInitialHttpAttributesToSpan(span, request);
8082

8183
HttpResponseInterceptor originalInterceptor = request.getResponseInterceptor();
8284
request.setResponseInterceptor(
@@ -99,14 +101,16 @@ public void initialize(HttpRequest request) throws IOException {
99101
}
100102

101103
/** Add initial HTTP attributes to the existing active span */
102-
private void addInitialHttpAttributesToSpan(Span span, String host, Integer port) {
104+
private void addInitialHttpAttributesToSpan(Span span, HttpRequest request) {
103105
BigQueryTelemetryTracer.addCommonAttributeToSpan(span);
104106
span.setAttribute(BigQueryTelemetryTracer.RPC_SYSTEM_NAME, HTTP_RPC_SYSTEM_NAME);
107+
String host = request.getUrl().getHost();
105108
span.setAttribute(BigQueryTelemetryTracer.SERVER_ADDRESS, host);
106-
if (port != null && port > 0) {
107-
span.setAttribute(BigQueryTelemetryTracer.SERVER_PORT, port.longValue());
109+
int port = request.getUrl().getPort();
110+
if (port > 0) {
111+
span.setAttribute(BigQueryTelemetryTracer.SERVER_PORT, (long) port);
108112
}
109-
// TODO add full sanitized url, url domain, request method
113+
span.setAttribute(URL_FULL, getSanitizedUrl(request));
110114
}
111115

112116
private static void addCommonResponseAttributesToSpan(
@@ -136,4 +140,21 @@ static void addResponseBodySizeToSpan(HttpResponse response, Span span) {
136140
}
137141
// TODO handle chunked responses
138142
}
143+
144+
private static String getSanitizedUrl(HttpRequest request) {
145+
GenericUrl url = request.getUrl();
146+
if (url == null) {
147+
return null;
148+
}
149+
// redact credentials passes query params
150+
GenericUrl clone = url.clone();
151+
for (String key : clone.keySet()) {
152+
if (REDACTED_QUERY_PARAMETERS.contains(key)) {
153+
clone.put(key, "REDACTED");
154+
}
155+
}
156+
String urlString = clone.build();
157+
// redact credentials sent as part of the domain
158+
return urlString.replaceAll("^(https?://)[^@/]+@", "$1REDACTED:REDACTED@");
159+
}
139160
}

java-bigquery/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/telemetry/HttpTracingRequestInitializerTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
package com.google.cloud.bigquery.telemetry;
1818

1919
import static org.junit.jupiter.api.Assertions.assertEquals;
20+
import static org.junit.jupiter.api.Assertions.assertFalse;
2021
import static org.junit.jupiter.api.Assertions.assertNull;
22+
import static org.junit.jupiter.api.Assertions.assertTrue;
2123
import static org.mockito.ArgumentMatchers.any;
2224
import static org.mockito.ArgumentMatchers.anyBoolean;
2325
import static org.mockito.Mockito.mock;
@@ -201,6 +203,48 @@ public void testUnsuccessfulResponseHandlerSetsErrorIfNoOriginal() throws IOExce
201203
closeAndVerifySpanData(401, "GET", -1, -1);
202204
}
203205

206+
@Test
207+
public void testUrlQueryParametersAreRedacted() throws IOException {
208+
HttpTransport transport = createTransport();
209+
String urlWithQuery = BASE_URL + "?upload_id=secret_id&Signature=secret_sig&keep_me=ok";
210+
HttpRequest request = buildGetRequest(transport, initializer, urlWithQuery);
211+
212+
HttpResponse response = request.execute();
213+
response.disconnect();
214+
215+
spanScope.close();
216+
parentSpan.end();
217+
218+
List<SpanData> spans = spanExporter.getFinishedSpanItems();
219+
assertEquals(1, spans.size());
220+
SpanData span = spans.get(0);
221+
String urlFull = span.getAttributes().get(HttpTracingRequestInitializer.URL_FULL);
222+
223+
assertTrue(urlFull.contains("upload_id=REDACTED"));
224+
assertTrue(urlFull.contains("Signature=REDACTED"));
225+
assertTrue(urlFull.contains("keep_me=ok"));
226+
}
227+
228+
@Test
229+
public void testUrlCredentialsAreRedacted() throws IOException {
230+
HttpTransport transport = createTransport();
231+
String credUrl = "https://user:pass@bigquery.googleapis.com/bigquery/v2/projects/test/datasets";
232+
HttpRequest request = buildGetRequest(transport, initializer, credUrl);
233+
234+
HttpResponse response = request.execute();
235+
response.disconnect();
236+
237+
spanScope.close();
238+
parentSpan.end();
239+
240+
List<SpanData> spans = spanExporter.getFinishedSpanItems();
241+
assertEquals(1, spans.size());
242+
SpanData span = spans.get(0);
243+
String urlFull = span.getAttributes().get(HttpTracingRequestInitializer.URL_FULL);
244+
245+
assertFalse(urlFull.contains("user:pass"));
246+
}
247+
204248
@Test
205249
public void testAddRequestBodySizeToSpan_ExceptionHandled() throws IOException {
206250
HttpContent content = mock(HttpContent.class);
@@ -367,6 +411,7 @@ private void closeAndVerifySpanData(
367411
span.getAttributes().get(HttpTracingRequestInitializer.HTTP_RESPONSE_STATUS_CODE));
368412
assertEquals(
369413
method, span.getAttributes().get(HttpTracingRequestInitializer.HTTP_REQUEST_METHOD));
414+
assertEquals(BASE_URL, span.getAttributes().get(HttpTracingRequestInitializer.URL_FULL));
370415
if (requestBodySize >= 0) {
371416
assertEquals(
372417
requestBodySize,

0 commit comments

Comments
 (0)