Skip to content

Commit 26a1cfb

Browse files
committed
feat(bigquery): Add OpenTelemetry Samples
1 parent 0e971b8 commit 26a1cfb

File tree

3 files changed

+254
-0
lines changed

3 files changed

+254
-0
lines changed

samples/snippets/pom.xml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,33 @@
5151
<type>pom</type>
5252
<scope>import</scope>
5353
</dependency>
54+
55+
<dependency>
56+
<groupId>io.opentelemetry</groupId>
57+
<artifactId>opentelemetry-api</artifactId>
58+
<version>1.46.0</version>
59+
</dependency>
60+
<dependency>
61+
<groupId>io.opentelemetry</groupId>
62+
<artifactId>opentelemetry-context</artifactId>
63+
<version>1.46.0</version>
64+
</dependency>
65+
<dependency>
66+
<groupId>io.opentelemetry</groupId>
67+
<artifactId>opentelemetry-sdk</artifactId>
68+
<version>1.46.0</version>
69+
</dependency>
70+
<dependency>
71+
<groupId>io.opentelemetry</groupId>
72+
<artifactId>opentelemetry-sdk-common</artifactId>
73+
<version>1.46.0</version>
74+
</dependency>
75+
<dependency>
76+
<groupId>io.opentelemetry</groupId>
77+
<artifactId>opentelemetry-sdk-trace</artifactId>
78+
<version>1.46.0</version>
79+
</dependency>
80+
5481
</dependencies>
5582
</dependencyManagement>
5683

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.bigquery;
18+
19+
// [START bigquery_enable_otel_tracing_with_parent_span]
20+
import com.google.cloud.bigquery.BigQuery;
21+
import com.google.cloud.bigquery.BigQueryOptions;
22+
import com.google.cloud.bigquery.Dataset;
23+
import com.google.cloud.bigquery.DatasetId;
24+
import com.google.cloud.bigquery.DatasetInfo;
25+
import io.opentelemetry.api.OpenTelemetry;
26+
import io.opentelemetry.api.common.AttributeKey;
27+
import io.opentelemetry.api.trace.Span;
28+
import io.opentelemetry.api.trace.Tracer;
29+
import io.opentelemetry.context.Scope;
30+
import java.util.HashMap;
31+
import java.util.Map;
32+
import java.util.Collection;
33+
import io.opentelemetry.sdk.OpenTelemetrySdk;
34+
import io.opentelemetry.sdk.common.CompletableResultCode;
35+
import io.opentelemetry.sdk.trace.SdkTracerProvider;
36+
import io.opentelemetry.sdk.trace.data.SpanData;
37+
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
38+
import io.opentelemetry.sdk.trace.samplers.Sampler;
39+
40+
public class EnableOpenTelemetryTracingWithParentSpan {
41+
42+
// Data structures for captured Span data
43+
private static final Map<String, Map<AttributeKey<?>, Object>> OTEL_ATTRIBUTES =
44+
new HashMap<String, Map<AttributeKey<?>, Object>>();
45+
private static final Map<String, String> OTEL_PARENT_SPAN_IDS = new HashMap<>();
46+
private static final Map<String, String> OTEL_SPAN_IDS_TO_NAMES = new HashMap<>();
47+
48+
// Create a SpanExporter to determine how to handle captured Span data.
49+
// See more at https://opentelemetry.io/docs/languages/java/sdk/#spanexporter
50+
private static class SampleSpanExporter implements io.opentelemetry.sdk.trace.export.SpanExporter {
51+
@Override
52+
public CompletableResultCode export(Collection<SpanData> collection) {
53+
// Export data. This data can be sent out of process via netowork calls, though
54+
// for this example a local map is used.
55+
if (collection.isEmpty()) {
56+
// No span data was collected.
57+
return CompletableResultCode.ofFailure();
58+
}
59+
// TODO(developer): Replace export output before running the sample.
60+
for (SpanData data : collection) {
61+
OTEL_ATTRIBUTES.put(data.getName(), data.getAttributes().asMap());
62+
OTEL_PARENT_SPAN_IDS.put(data.getName(), data.getParentSpanId());
63+
OTEL_SPAN_IDS_TO_NAMES.put(data.getSpanId(), data.getName());
64+
}
65+
return CompletableResultCode.ofSuccess();
66+
}
67+
68+
// TODO(developer): Replace these functions to suit your needs.
69+
@Override
70+
public CompletableResultCode flush() {
71+
// Export any data that has been queued up but not yet exported.
72+
return CompletableResultCode.ofSuccess();
73+
}
74+
75+
@Override
76+
public CompletableResultCode shutdown() {
77+
// Shut down the exporter and clean up any resources.
78+
return CompletableResultCode.ofSuccess();
79+
}
80+
}
81+
82+
public static void main(String[] args) {
83+
enableOpenTelemetryWithParentSpan("Sample Tracer");
84+
}
85+
86+
public static void enableOpenTelemetryWithParentSpan(String tracerName) {
87+
// Create TracerProvider using the custom SpanExporter.
88+
SdkTracerProvider tracerProvider =
89+
SdkTracerProvider.builder()
90+
.addSpanProcessor(SimpleSpanProcessor.create(new SampleSpanExporter()))
91+
.setSampler(Sampler.alwaysOn())
92+
.build();
93+
94+
// Create global OpenTelemetry instance using the TracerProvider.
95+
OpenTelemetry otel = OpenTelemetrySdk.builder()
96+
.setTracerProvider(tracerProvider)
97+
.buildAndRegisterGlobal();
98+
99+
// Create Tracer instance from the global OpenTelemetry object. Tracers are used to create
100+
// Spans. There can be multiple Tracers in a global OpenTelemetry instance.
101+
// TODO(developer): Replace Tracer name
102+
Tracer tracer = otel.getTracer(tracerName);
103+
104+
// Create BigQuery client to trace. EnableOpenTelemetryTracing and OpenTelemetryTracer must
105+
// be set to enable tracing.
106+
BigQueryOptions otelOptions =
107+
BigQueryOptions.newBuilder()
108+
.setEnableOpenTelemetryTracing(true)
109+
.setOpenTelemetryTracer(tracer)
110+
.build();
111+
BigQuery bigquery = otelOptions.getService();
112+
113+
// Create the root parent Span. setNoParent() ensures that it is a parent Span.
114+
// TODO(developer): Replace Span and attribute names.
115+
Span parentSpan =
116+
tracer
117+
.spanBuilder("Sample Parent Span")
118+
.setNoParent()
119+
.setAttribute("sample-parent-attribute", "sample-parent-value")
120+
.startSpan();
121+
122+
// Wrap nested functions in try-catch-finally block to pass on the Span Context.
123+
try (Scope parentScope = parentSpan.makeCurrent()) {
124+
createDataset(bigquery, tracer, "sample-dataset-id");
125+
} finally {
126+
// finally block ensures that Spans are cleaned up properly.
127+
parentSpan.end();
128+
129+
if (OTEL_ATTRIBUTES.get("Sample Parent Span").get(AttributeKey.stringKey("sample-parent-attribute")) == "sample-parent-value") {
130+
System.out.println("Parent Span was captured!");
131+
} else {
132+
System.out.println("Parent Span was not captured!");
133+
}
134+
if (OTEL_ATTRIBUTES.get("Sample Child Span").get(AttributeKey.stringKey("sample-child-attribute")) == "sample-child-value") {
135+
System.out.println("Child Span was captured!");
136+
} else {
137+
System.out.println("Child Span was not captured!");
138+
}
139+
if (OTEL_ATTRIBUTES.get("Sample Child Span").get(AttributeKey.stringKey("sample-child-attribute")) == "sample-child-value") {
140+
System.out.println("Child Span was captured!");
141+
} else {
142+
System.out.println("Child Span was not captured!");
143+
}
144+
String childSpanParentId = OTEL_PARENT_SPAN_IDS.get("Sample Child Span");
145+
String parentSpanId = OTEL_SPAN_IDS_TO_NAMES.get(childSpanParentId);
146+
if (parentSpanId == "Sample Parent Span") {
147+
System.out.println("Sample Child Span is the child of Sample Parent Span!");
148+
}
149+
}
150+
}
151+
152+
public static void createDataset(BigQuery bigquery, Tracer tracer, String datasetId) {
153+
// Parent Span Context is passed on here.
154+
Span childSpan =
155+
tracer
156+
.spanBuilder("Sample Child Span")
157+
.setNoParent()
158+
.setAttribute("sample-child-attribute", "sample-child-value")
159+
.startSpan();
160+
161+
DatasetInfo info =
162+
DatasetInfo.newBuilder(datasetId)
163+
.build();
164+
165+
Dataset dataset = bigquery.create(info);
166+
}
167+
}
168+
// [END bigquery_enable_otel_tracing_with_parent_span]
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.bigquery;
18+
19+
import static com.google.common.truth.Truth.assertThat;
20+
21+
import java.io.ByteArrayOutputStream;
22+
import java.io.PrintStream;
23+
import java.util.logging.Level;
24+
import java.util.logging.Logger;
25+
import org.junit.After;
26+
import org.junit.Before;
27+
import org.junit.Test;
28+
29+
public class EnableOpenTelemetryTracingWithParentSpanIT {
30+
private final Logger log = Logger.getLogger(this.getClass().getName());
31+
private ByteArrayOutputStream bout;
32+
private PrintStream out;
33+
private PrintStream originalPrintStream;
34+
35+
@Before
36+
public void setUp() {
37+
bout = new ByteArrayOutputStream();
38+
out = new PrintStream(bout);
39+
originalPrintStream = System.out;
40+
System.setOut(out);
41+
}
42+
43+
@After
44+
public void tearDown() {
45+
// restores print statements in the original method
46+
System.out.flush();
47+
System.setOut(originalPrintStream);
48+
log.log(Level.INFO, "\n" + bout.toString());
49+
}
50+
51+
@Test
52+
public void testCreateJob() {
53+
EnableOpenTelemetryTracingWithParentSpan.enableOpenTelemetryWithParentSpan("Sample Test Tracer");
54+
55+
assertThat(bout.toString()).contains("Parent Span was captured!");
56+
assertThat(bout.toString()).contains("Child Span was captured!");
57+
assertThat(bout.toString()).contains("Sample Child Span is the child of Sample Parent Span!");
58+
}
59+
}

0 commit comments

Comments
 (0)