diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index 87e8e13c4..1524dc8d2 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -37,7 +37,7 @@ jobs:
persist-credentials: false
- name: "Run analysis"
- uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
+ uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
with:
results_file: results.sarif
results_format: sarif
diff --git a/.github/workflows/unmanaged_dependency_check.yaml b/.github/workflows/unmanaged_dependency_check.yaml
index 3f2945215..63543a40f 100644
--- a/.github/workflows/unmanaged_dependency_check.yaml
+++ b/.github/workflows/unmanaged_dependency_check.yaml
@@ -17,7 +17,7 @@ jobs:
# repository
.kokoro/build.sh
- name: Unmanaged dependency check
- uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.49.0
+ uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v3.50.0
with:
# java-bigquery does not produce a BOM. Fortunately the root pom.xml
# defines google-cloud-bigquery in dependencyManagement section. So
diff --git a/.kokoro/continuous/graalvm-native-a.cfg b/.kokoro/continuous/graalvm-native-a.cfg
index 54d873dc1..dfa34060b 100644
--- a/.kokoro/continuous/graalvm-native-a.cfg
+++ b/.kokoro/continuous/graalvm-native-a.cfg
@@ -3,7 +3,7 @@
# Configure the docker image for kokoro-trampoline.
env_vars: {
key: "TRAMPOLINE_IMAGE"
- value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.49.0"
+ value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.50.0"
}
env_vars: {
diff --git a/.kokoro/continuous/graalvm-native-b.cfg b/.kokoro/continuous/graalvm-native-b.cfg
index b7bd7ed2f..37dda4ab5 100644
--- a/.kokoro/continuous/graalvm-native-b.cfg
+++ b/.kokoro/continuous/graalvm-native-b.cfg
@@ -3,7 +3,7 @@
# Configure the docker image for kokoro-trampoline.
env_vars: {
key: "TRAMPOLINE_IMAGE"
- value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.49.0"
+ value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.50.0"
}
env_vars: {
diff --git a/.kokoro/continuous/graalvm-native-c.cfg b/.kokoro/continuous/graalvm-native-c.cfg
index 7090b33d1..a8ab97784 100644
--- a/.kokoro/continuous/graalvm-native-c.cfg
+++ b/.kokoro/continuous/graalvm-native-c.cfg
@@ -3,7 +3,7 @@
# Configure the docker image for kokoro-trampoline.
env_vars: {
key: "TRAMPOLINE_IMAGE"
- value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_c:3.49.0"
+ value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_c:3.50.0"
}
env_vars: {
diff --git a/.kokoro/presubmit/graalvm-native-a.cfg b/.kokoro/presubmit/graalvm-native-a.cfg
index 54d873dc1..dfa34060b 100644
--- a/.kokoro/presubmit/graalvm-native-a.cfg
+++ b/.kokoro/presubmit/graalvm-native-a.cfg
@@ -3,7 +3,7 @@
# Configure the docker image for kokoro-trampoline.
env_vars: {
key: "TRAMPOLINE_IMAGE"
- value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.49.0"
+ value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_a:3.50.0"
}
env_vars: {
diff --git a/.kokoro/presubmit/graalvm-native-b.cfg b/.kokoro/presubmit/graalvm-native-b.cfg
index b7bd7ed2f..37dda4ab5 100644
--- a/.kokoro/presubmit/graalvm-native-b.cfg
+++ b/.kokoro/presubmit/graalvm-native-b.cfg
@@ -3,7 +3,7 @@
# Configure the docker image for kokoro-trampoline.
env_vars: {
key: "TRAMPOLINE_IMAGE"
- value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.49.0"
+ value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_b:3.50.0"
}
env_vars: {
diff --git a/.kokoro/presubmit/graalvm-native-c.cfg b/.kokoro/presubmit/graalvm-native-c.cfg
index 7090b33d1..a8ab97784 100644
--- a/.kokoro/presubmit/graalvm-native-c.cfg
+++ b/.kokoro/presubmit/graalvm-native-c.cfg
@@ -3,7 +3,7 @@
# Configure the docker image for kokoro-trampoline.
env_vars: {
key: "TRAMPOLINE_IMAGE"
- value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_c:3.49.0"
+ value: "gcr.io/cloud-devrel-public-resources/graalvm_sdk_platform_c:3.50.0"
}
env_vars: {
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e9fe4fdd3..71577758b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,29 @@
# Changelog
+## [2.52.0](https://github.com/googleapis/java-bigquery/compare/v2.51.0...v2.52.0) (2025-06-25)
+
+
+### Features
+
+* **bigquery:** Integrate Otel in client lib ([#3747](https://github.com/googleapis/java-bigquery/issues/3747)) ([6e3e07a](https://github.com/googleapis/java-bigquery/commit/6e3e07a22b8397e1e9d5b567589e44abc55961f2))
+* **bigquery:** Integrate Otel into retries, jobs, and more ([#3842](https://github.com/googleapis/java-bigquery/issues/3842)) ([4b28c47](https://github.com/googleapis/java-bigquery/commit/4b28c479c1bc22326c8d2501354fb86ec2ce1744))
+
+
+### Bug Fixes
+
+* **bigquery:** Add MY_VIEW_DATASET_NAME_TEST_ to resource clean up sample ([#3838](https://github.com/googleapis/java-bigquery/issues/3838)) ([b1962a7](https://github.com/googleapis/java-bigquery/commit/b1962a7f0084ee4c3e248266b50406cf575cd657))
+
+
+### Dependencies
+
+* Remove version declaration of open-telemetry-bom ([#3855](https://github.com/googleapis/java-bigquery/issues/3855)) ([6f9f77d](https://github.com/googleapis/java-bigquery/commit/6f9f77d47596b00b7317c8a0d4a10c3d849ad57b))
+* Update dependency com.google.api.grpc:proto-google-cloud-bigqueryconnection-v1 to v2.66.0 ([#3835](https://github.com/googleapis/java-bigquery/issues/3835)) ([69be5e7](https://github.com/googleapis/java-bigquery/commit/69be5e7345fb8ca69d633d9dc99cf6c15fa5227b))
+* Update dependency com.google.api.grpc:proto-google-cloud-bigqueryconnection-v1 to v2.68.0 ([#3858](https://github.com/googleapis/java-bigquery/issues/3858)) ([d4ca353](https://github.com/googleapis/java-bigquery/commit/d4ca3535f54f3282aec133337103bbfa2c9a3653))
+* Update dependency com.google.cloud:sdk-platform-java-config to v3.49.2 ([#3853](https://github.com/googleapis/java-bigquery/issues/3853)) ([cf864df](https://github.com/googleapis/java-bigquery/commit/cf864df739bbb820e99999b7c1592a3635fea4ec))
+* Update dependency com.google.cloud:sdk-platform-java-config to v3.50.0 ([#3861](https://github.com/googleapis/java-bigquery/issues/3861)) ([eb26dee](https://github.com/googleapis/java-bigquery/commit/eb26deee37119389aee3962eea5ad67d63f26c70))
+* Update dependency io.opentelemetry:opentelemetry-bom to v1.51.0 ([#3840](https://github.com/googleapis/java-bigquery/issues/3840)) ([51321c2](https://github.com/googleapis/java-bigquery/commit/51321c22778fd41134cc0cdfc70bdc47f05883f1))
+* Update ossf/scorecard-action action to v2.4.2 ([#3810](https://github.com/googleapis/java-bigquery/issues/3810)) ([414f61d](https://github.com/googleapis/java-bigquery/commit/414f61d7efcfa568c1446bd41945d7a8e2450649))
+
## [2.51.0](https://github.com/googleapis/java-bigquery/compare/v2.50.1...v2.51.0) (2025-06-06)
diff --git a/README.md b/README.md
index 42b0b9f7e..d8f6c46d8 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ See https://github.com/GoogleCloudPlatform/cloud-opensource-java/wiki/The-Google
com.google.cloud
libraries-bom
- 26.43.0
+ 26.62.0
pom
import
diff --git a/benchmark/pom.xml b/benchmark/pom.xml
index 6285defb6..bb58ca1e1 100644
--- a/benchmark/pom.xml
+++ b/benchmark/pom.xml
@@ -6,7 +6,7 @@
google-cloud-bigquery-parent
com.google.cloud
- 2.51.0
+ 2.52.0
diff --git a/google-cloud-bigquery-bom/pom.xml b/google-cloud-bigquery-bom/pom.xml
index 66387cf2e..836073eb4 100644
--- a/google-cloud-bigquery-bom/pom.xml
+++ b/google-cloud-bigquery-bom/pom.xml
@@ -3,12 +3,12 @@
4.0.0
com.google.cloud
google-cloud-bigquery-bom
- 2.51.0
+ 2.52.0
pom
com.google.cloud
sdk-platform-java-config
- 3.49.0
+ 3.50.0
@@ -54,7 +54,7 @@
com.google.cloud
google-cloud-bigquery
- 2.51.0
+ 2.52.0
diff --git a/google-cloud-bigquery/clirr-ignored-differences.xml b/google-cloud-bigquery/clirr-ignored-differences.xml
index 37e349413..e048f4ce8 100644
--- a/google-cloud-bigquery/clirr-ignored-differences.xml
+++ b/google-cloud-bigquery/clirr-ignored-differences.xml
@@ -2,6 +2,12 @@
+
+ 7004
+ com/google/cloud/bigquery/BigQueryRetryHelper
+ java.lang.Object runWithRetries(java.util.concurrent.Callable, com.google.api.gax.retrying.RetrySettings, com.google.api.gax.retrying.ResultRetryAlgorithm, com.google.api.core.ApiClock, com.google.cloud.bigquery.BigQueryRetryConfig)
+ A Tracer object is needed to use Otel and runWithRetries is only called in a few files, so it should be fine to update the signature
+
7004
com/google/cloud/bigquery/spi/v2/BigQueryRpc
diff --git a/google-cloud-bigquery/pom.xml b/google-cloud-bigquery/pom.xml
index 07cc6b0fb..644fe0ef5 100644
--- a/google-cloud-bigquery/pom.xml
+++ b/google-cloud-bigquery/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.google.cloud
google-cloud-bigquery
- 2.51.0
+ 2.52.0
jar
BigQuery
https://github.com/googleapis/java-bigquery
@@ -11,7 +11,7 @@
com.google.cloud
google-cloud-bigquery-parent
- 2.51.0
+ 2.52.0
google-cloud-bigquery
@@ -156,6 +156,16 @@
error_prone_annotations
+
+
+ io.opentelemetry
+ opentelemetry-api
+
+
+ io.opentelemetry
+ opentelemetry-context
+
+
com.google.api
@@ -208,6 +218,23 @@
proto-google-cloud-datacatalog-v1
test
+
+
+
+ io.opentelemetry
+ opentelemetry-sdk
+ test
+
+
+ io.opentelemetry
+ opentelemetry-sdk-common
+ test
+
+
+ io.opentelemetry
+ opentelemetry-sdk-trace
+ test
+
@@ -224,7 +251,7 @@
org.codehaus.mojo
build-helper-maven-plugin
- 3.6.0
+ 3.6.1
add-source
@@ -248,6 +275,27 @@
+
+ arrow-config
+
+ [9,)
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ UTF-8
+ true
+
+ -J--add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED
+
+
+
+
+
+
java17
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java
index 9ede02838..a32a600c3 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java
@@ -51,6 +51,9 @@
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.context.Scope;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -268,7 +271,18 @@ public Dataset create(DatasetInfo datasetInfo, DatasetOption... options) {
: datasetInfo.getDatasetId().getProject())
.toPb();
final Map optionsMap = optionMap(options);
- try {
+ Span datasetCreate = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ datasetCreate =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.createDataset")
+ .setAllAttributes(datasetInfo.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope datasetCreateScope = datasetCreate != null ? datasetCreate.makeCurrent() : null) {
return Dataset.fromPb(
this,
BigQueryRetryHelper.runWithRetries(
@@ -281,9 +295,15 @@ public com.google.api.services.bigquery.model.Dataset call() throws IOException
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG));
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer()));
} catch (BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (datasetCreate != null) {
+ datasetCreate.end();
+ }
}
}
@@ -298,7 +318,18 @@ public Table create(TableInfo tableInfo, TableOption... options) {
.toPb();
handleExternalTableSchema(tablePb);
final Map optionsMap = optionMap(options);
- try {
+ Span tableCreate = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ tableCreate =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.createTable")
+ .setAllAttributes(tableInfo.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope tableCreateScope = tableCreate != null ? tableCreate.makeCurrent() : null) {
return Table.fromPb(
this,
BigQueryRetryHelper.runWithRetries(
@@ -311,9 +342,15 @@ public com.google.api.services.bigquery.model.Table call() throws IOException {
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG));
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer()));
} catch (BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (tableCreate != null) {
+ tableCreate.end();
+ }
}
}
@@ -337,7 +374,18 @@ public Routine create(RoutineInfo routineInfo, RoutineOption... options) {
: routineInfo.getRoutineId().getProject())
.toPb();
final Map optionsMap = optionMap(options);
- try {
+ Span routineCreate = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ routineCreate =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.createRoutine")
+ .setAllAttributes(routineInfo.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope createRoutineScope = routineCreate != null ? routineCreate.makeCurrent() : null) {
return Routine.fromPb(
this,
BigQueryRetryHelper.runWithRetries(
@@ -350,9 +398,15 @@ public com.google.api.services.bigquery.model.Routine call() throws IOException
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG));
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer()));
} catch (BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (routineCreate != null) {
+ routineCreate.end();
+ }
}
}
@@ -388,6 +442,17 @@ Job create(JobInfo jobInfo, Supplier idProvider, JobOption... options) {
final boolean idRandom = (jobInfo.getJobId() == null);
final Map optionsMap = optionMap(options);
+ Span jobCreate = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ jobCreate =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.createJob")
+ .setAllAttributes(jobInfo.getJobId().getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
BigQueryException createException;
// NOTE(pongad): This double-try structure is admittedly odd.
// translateAndThrow itself throws, and pretends to return an exception only
@@ -396,90 +461,98 @@ Job create(JobInfo jobInfo, Supplier idProvider, JobOption... options) {
// Fixing this entails some work on BaseServiceException.translate.
// Since that affects a bunch of APIs, we should fix this as a separate change.
final JobId[] finalJobId = new JobId[1];
- try {
+ try (Scope jobCreateScope = jobCreate != null ? jobCreate.makeCurrent() : null) {
try {
- return Job.fromPb(
- this,
- BigQueryRetryHelper.runWithRetries(
- new Callable() {
- @Override
- public com.google.api.services.bigquery.model.Job call() throws IOException {
- if (idRandom) {
- // re-generate a new random job with the same jobInfo when jobId is not
- // provided by the user
- JobInfo recreatedJobInfo =
- jobInfo.toBuilder().setJobId(idProvider.get()).build();
- com.google.api.services.bigquery.model.Job newJobPb =
- recreatedJobInfo.setProjectId(getOptions().getProjectId()).toPb();
- finalJobId[0] = recreatedJobInfo.getJobId();
- return bigQueryRpc.createSkipExceptionTranslation(newJobPb, optionsMap);
- } else {
- com.google.api.services.bigquery.model.Job jobPb =
- jobInfo.setProjectId(getOptions().getProjectId()).toPb();
- return bigQueryRpc.createSkipExceptionTranslation(jobPb, optionsMap);
+ try {
+ return Job.fromPb(
+ this,
+ BigQueryRetryHelper.runWithRetries(
+ new Callable() {
+ @Override
+ public com.google.api.services.bigquery.model.Job call() throws IOException {
+ if (idRandom) {
+ // re-generate a new random job with the same jobInfo when jobId is not
+ // provided by the user
+ JobInfo recreatedJobInfo =
+ jobInfo.toBuilder().setJobId(idProvider.get()).build();
+ com.google.api.services.bigquery.model.Job newJobPb =
+ recreatedJobInfo.setProjectId(getOptions().getProjectId()).toPb();
+ finalJobId[0] = recreatedJobInfo.getJobId();
+ return bigQueryRpc.createSkipExceptionTranslation(newJobPb, optionsMap);
+ } else {
+ com.google.api.services.bigquery.model.Job jobPb =
+ jobInfo.setProjectId(getOptions().getProjectId()).toPb();
+ return bigQueryRpc.createSkipExceptionTranslation(jobPb, optionsMap);
+ }
}
- }
- },
- getRetryOptions(optionsMap) != null
- ? RetryOption.mergeToSettings(
- getOptions().getRetrySettings(), getRetryOptions(optionsMap))
- : getOptions().getRetrySettings(),
- BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
- getOptions().getClock(),
- getBigQueryRetryConfig(optionsMap) != null
- ? getBigQueryRetryConfig(optionsMap)
- : DEFAULT_RETRY_CONFIG));
- } catch (BigQueryRetryHelperException e) {
- throw BigQueryException.translateAndThrow(e);
+ },
+ getRetryOptions(optionsMap) != null
+ ? RetryOption.mergeToSettings(
+ getOptions().getRetrySettings(), getRetryOptions(optionsMap))
+ : getOptions().getRetrySettings(),
+ BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
+ getOptions().getClock(),
+ getBigQueryRetryConfig(optionsMap) != null
+ ? getBigQueryRetryConfig(optionsMap)
+ : DEFAULT_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer()));
+ } catch (BigQueryRetryHelperException e) {
+ throw BigQueryException.translateAndThrow(e);
+ }
+ } catch (BigQueryException e) {
+ createException = e;
}
- } catch (BigQueryException e) {
- createException = e;
- }
-
- if (!idRandom) {
- if (createException instanceof BigQueryException
- && createException.getCause() != null
- && createException.getCause().getMessage() != null) {
-
- Pattern pattern = Pattern.compile(".*Already.*Exists:.*Job.*", Pattern.CASE_INSENSITIVE);
- Matcher matcher = pattern.matcher(createException.getCause().getMessage());
-
- if (matcher.find()) {
- // If the Job ALREADY EXISTS, retrieve it.
- Job job = this.getJob(jobInfo.getJobId(), JobOption.fields(JobField.STATISTICS));
-
- long jobCreationTime = job.getStatistics().getCreationTime();
- long jobMinStaleTime = System.currentTimeMillis();
- long jobMaxStaleTime =
- java.time.Instant.ofEpochMilli(jobMinStaleTime)
- .minus(1, java.time.temporal.ChronoUnit.DAYS)
- .toEpochMilli();
-
- // Only return the job if it has been created in the past 24 hours.
- // This is assuming any job older than 24 hours is a valid duplicate JobID
- // and not a false positive like b/290419183
- if (jobCreationTime >= jobMaxStaleTime && jobCreationTime <= jobMinStaleTime) {
- return job;
+
+ if (!idRandom) {
+ if (createException instanceof BigQueryException
+ && createException.getCause() != null
+ && createException.getCause().getMessage() != null) {
+
+ Pattern pattern = Pattern.compile(".*Already.*Exists:.*Job.*", Pattern.CASE_INSENSITIVE);
+ Matcher matcher = pattern.matcher(createException.getCause().getMessage());
+
+ if (matcher.find()) {
+ // If the Job ALREADY EXISTS, retrieve it.
+ Job job = this.getJob(jobInfo.getJobId(), JobOption.fields(JobField.STATISTICS));
+
+ long jobCreationTime = job.getStatistics().getCreationTime();
+ long jobMinStaleTime = System.currentTimeMillis();
+ long jobMaxStaleTime =
+ java.time.Instant.ofEpochMilli(jobMinStaleTime)
+ .minus(1, java.time.temporal.ChronoUnit.DAYS)
+ .toEpochMilli();
+
+ // Only return the job if it has been created in the past 24 hours.
+ // This is assuming any job older than 24 hours is a valid duplicate JobID
+ // and not a false positive like b/290419183
+ if (jobCreationTime >= jobMaxStaleTime && jobCreationTime <= jobMinStaleTime) {
+ return job;
+ }
}
}
+ throw createException;
}
- throw createException;
- }
- // If create RPC fails, it's still possible that the job has been successfully
- // created, and get might work.
- // We can only do this if we randomly generated the ID. Otherwise we might
- // mistakenly fetch a job created by someone else.
- Job job;
- try {
- job = getJob(finalJobId[0]);
- } catch (BigQueryException e) {
- throw createException;
- }
- if (job == null) {
- throw createException;
+ // If create RPC fails, it's still possible that the job has been successfully
+ // created, and get might work.
+ // We can only do this if we randomly generated the ID. Otherwise we might
+ // mistakenly fetch a job created by someone else.
+ Job job;
+ try {
+ job = getJob(finalJobId[0]);
+ } catch (BigQueryException e) {
+ throw createException;
+ }
+ if (job == null) {
+ throw createException;
+ }
+ return job;
+ } finally {
+ if (jobCreate != null) {
+ jobCreate.end();
+ }
}
- return job;
}
@Override
@@ -491,7 +564,18 @@ public Dataset getDataset(String datasetId, DatasetOption... options) {
public Dataset getDataset(final DatasetId datasetId, DatasetOption... options) {
final DatasetId completeDatasetId = datasetId.setProjectId(getOptions().getProjectId());
final Map optionsMap = optionMap(options);
- try {
+ Span datasetGet = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ datasetGet =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.getDataset")
+ .setAllAttributes(completeDatasetId.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope datasetGetScope = datasetGet != null ? datasetGet.makeCurrent() : null) {
com.google.api.services.bigquery.model.Dataset answer =
BigQueryRetryHelper.runWithRetries(
new Callable() {
@@ -504,7 +588,9 @@ public com.google.api.services.bigquery.model.Dataset call() throws IOException
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer());
return Dataset.fromPb(this, answer);
} catch (BigQueryRetryHelperException e) {
if (isRetryErrorCodeHttpNotFound(e)) {
@@ -514,6 +600,10 @@ public com.google.api.services.bigquery.model.Dataset call() throws IOException
return null;
}
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (datasetGet != null) {
+ datasetGet.end();
+ }
}
}
@@ -524,7 +614,24 @@ public Page listDatasets(DatasetListOption... options) {
@Override
public Page listDatasets(String projectId, DatasetListOption... options) {
- return listDatasets(projectId, getOptions(), optionMap(options));
+ Span datasetsList = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ datasetsList =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.listDatasets")
+ .setAttribute("bq.dataset.project_id", projectId)
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope datasetsListScope = datasetsList != null ? datasetsList.makeCurrent() : null) {
+ return listDatasets(projectId, getOptions(), optionMap(options));
+ } finally {
+ if (datasetsList != null) {
+ datasetsList.end();
+ }
+ }
}
private static Page listDatasets(
@@ -547,7 +654,9 @@ private static Page listDatasets(
serviceOptions.getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
serviceOptions.getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ serviceOptions.isOpenTelemetryTracingEnabled(),
+ serviceOptions.getOpenTelemetryTracer());
String cursor = result.x();
return new PageImpl<>(
new DatasetPageFetcher(projectId, serviceOptions, cursor, optionsMap),
@@ -574,7 +683,18 @@ public boolean delete(String datasetId, DatasetDeleteOption... options) {
public boolean delete(DatasetId datasetId, DatasetDeleteOption... options) {
final DatasetId completeDatasetId = datasetId.setProjectId(getOptions().getProjectId());
final Map optionsMap = optionMap(options);
- try {
+ Span datasetDelete = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ datasetDelete =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.deleteDataset")
+ .setAllAttributes(datasetId.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope datasetDeleteScope = datasetDelete != null ? datasetDelete.makeCurrent() : null) {
return BigQueryRetryHelper.runWithRetries(
new Callable() {
@Override
@@ -586,12 +706,18 @@ public Boolean call() throws IOException {
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer());
} catch (BigQueryRetryHelperException e) {
if (isRetryErrorCodeHttpNotFound(e)) {
return false;
}
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (datasetDelete != null) {
+ datasetDelete.end();
+ }
}
}
@@ -607,7 +733,17 @@ public boolean delete(TableId tableId) {
Strings.isNullOrEmpty(tableId.getProject())
? getOptions().getProjectId()
: tableId.getProject());
- try {
+ Span tableDelete = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ tableDelete =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.deleteTable")
+ .setAllAttributes(tableId.getOtelAttributes())
+ .startSpan();
+ }
+ try (Scope tableDeleteScope = tableDelete != null ? tableDelete.makeCurrent() : null) {
return BigQueryRetryHelper.runWithRetries(
new Callable() {
@Override
@@ -621,12 +757,18 @@ public Boolean call() throws IOException {
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer());
} catch (BigQueryRetryHelperException e) {
if (isRetryErrorCodeHttpNotFound(e)) {
return false;
}
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (tableDelete != null) {
+ tableDelete.end();
+ }
}
}
@@ -637,7 +779,17 @@ public boolean delete(ModelId modelId) {
Strings.isNullOrEmpty(modelId.getProject())
? getOptions().getProjectId()
: modelId.getProject());
- try {
+ Span modelDelete = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ modelDelete =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.deleteModel")
+ .setAllAttributes(modelId.getOtelAttributes())
+ .startSpan();
+ }
+ try (Scope modelDeleteScope = modelDelete != null ? modelDelete.makeCurrent() : null) {
return BigQueryRetryHelper.runWithRetries(
new Callable() {
@Override
@@ -651,12 +803,18 @@ public Boolean call() throws IOException {
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer());
} catch (BigQueryRetryHelperException e) {
if (isRetryErrorCodeHttpNotFound(e)) {
return false;
}
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (modelDelete != null) {
+ modelDelete.end();
+ }
}
}
@@ -667,7 +825,17 @@ public boolean delete(RoutineId routineId) {
Strings.isNullOrEmpty(routineId.getProject())
? getOptions().getProjectId()
: routineId.getProject());
- try {
+ Span routineDelete = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ routineDelete =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.deleteRoutine")
+ .setAllAttributes(routineId.getOtelAttributes())
+ .startSpan();
+ }
+ try (Scope routineDeleteScope = routineDelete != null ? routineDelete.makeCurrent() : null) {
return BigQueryRetryHelper.runWithRetries(
new Callable() {
@Override
@@ -681,12 +849,18 @@ public Boolean call() throws IOException {
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer());
} catch (BigQueryRetryHelperException e) {
if (isRetryErrorCodeHttpNotFound(e)) {
return false;
}
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (routineDelete != null) {
+ routineDelete.end();
+ }
}
}
@@ -697,6 +871,16 @@ public boolean delete(JobId jobId) {
Strings.isNullOrEmpty(jobId.getProject())
? getOptions().getProjectId()
: jobId.getProject());
+ Span jobDelete = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ jobDelete =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.deleteJob")
+ .setAllAttributes(completeJobId.getOtelAttributes())
+ .startSpan();
+ }
try {
return BigQueryRetryHelper.runWithRetries(
new Callable() {
@@ -709,9 +893,15 @@ public Boolean call() throws IOException {
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer());
} catch (BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (jobDelete != null) {
+ jobDelete.end();
+ }
}
}
@@ -720,7 +910,18 @@ public Dataset update(DatasetInfo datasetInfo, DatasetOption... options) {
final com.google.api.services.bigquery.model.Dataset datasetPb =
datasetInfo.setProjectId(getOptions().getProjectId()).toPb();
final Map optionsMap = optionMap(options);
- try {
+ Span datasetUpdate = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ datasetUpdate =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.updateDataset")
+ .setAllAttributes(datasetInfo.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope datasetUpdateScope = datasetUpdate != null ? datasetUpdate.makeCurrent() : null) {
return Dataset.fromPb(
this,
BigQueryRetryHelper.runWithRetries(
@@ -733,9 +934,15 @@ public com.google.api.services.bigquery.model.Dataset call() throws IOException
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG));
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer()));
} catch (BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (datasetUpdate != null) {
+ datasetUpdate.end();
+ }
}
}
@@ -750,7 +957,18 @@ public Table update(TableInfo tableInfo, TableOption... options) {
.toPb();
handleExternalTableSchema(tablePb);
final Map optionsMap = optionMap(options);
- try {
+ Span tableUpdate = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ tableUpdate =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.updateTable")
+ .setAllAttributes(tableInfo.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope tableUpdateScope = tableUpdate != null ? tableUpdate.makeCurrent() : null) {
return Table.fromPb(
this,
BigQueryRetryHelper.runWithRetries(
@@ -763,9 +981,15 @@ public com.google.api.services.bigquery.model.Table call() throws IOException {
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG));
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer()));
} catch (BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (tableUpdate != null) {
+ tableUpdate.end();
+ }
}
}
@@ -779,7 +1003,18 @@ public Model update(ModelInfo modelInfo, ModelOption... options) {
: modelInfo.getModelId().getProject())
.toPb();
final Map optionsMap = optionMap(options);
- try {
+ Span modelUpdate = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ modelUpdate =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.updateModel")
+ .setAllAttributes(modelInfo.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope modelUpdateScope = modelUpdate != null ? modelUpdate.makeCurrent() : null) {
return Model.fromPb(
this,
BigQueryRetryHelper.runWithRetries(
@@ -792,9 +1027,15 @@ public com.google.api.services.bigquery.model.Model call() throws IOException {
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG));
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer()));
} catch (BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (modelUpdate != null) {
+ modelUpdate.end();
+ }
}
}
@@ -808,7 +1049,18 @@ public Routine update(RoutineInfo routineInfo, RoutineOption... options) {
: routineInfo.getRoutineId().getProject())
.toPb();
final Map optionsMap = optionMap(options);
- try {
+ Span routineUpdate = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ routineUpdate =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.updateRoutine")
+ .setAllAttributes(routineInfo.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope routineUpdateScope = routineUpdate != null ? routineUpdate.makeCurrent() : null) {
return Routine.fromPb(
this,
BigQueryRetryHelper.runWithRetries(
@@ -821,9 +1073,15 @@ public com.google.api.services.bigquery.model.Routine call() throws IOException
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG));
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer()));
} catch (BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (routineUpdate != null) {
+ routineUpdate.end();
+ }
}
}
@@ -842,7 +1100,18 @@ public Table getTable(TableId tableId, TableOption... options) {
? getOptions().getProjectId()
: tableId.getProject());
final Map optionsMap = optionMap(options);
- try {
+ Span tableGet = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ tableGet =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.getTable")
+ .setAllAttributes(tableId.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope tableGetScope = tableGet != null ? tableGet.makeCurrent() : null) {
com.google.api.services.bigquery.model.Table answer =
BigQueryRetryHelper.runWithRetries(
new Callable() {
@@ -858,7 +1127,9 @@ public com.google.api.services.bigquery.model.Table call() throws IOException {
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer());
return Table.fromPb(this, answer);
} catch (BigQueryRetryHelperException e) {
if (isRetryErrorCodeHttpNotFound(e)) {
@@ -868,6 +1139,10 @@ public com.google.api.services.bigquery.model.Table call() throws IOException {
return null;
}
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (tableGet != null) {
+ tableGet.end();
+ }
}
}
@@ -884,7 +1159,18 @@ public Model getModel(ModelId modelId, ModelOption... options) {
? getOptions().getProjectId()
: modelId.getProject());
final Map optionsMap = optionMap(options);
- try {
+ Span modelGet = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ modelGet =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.getModel")
+ .setAllAttributes(modelId.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope modelGetScope = modelGet != null ? modelGet.makeCurrent() : null) {
com.google.api.services.bigquery.model.Model answer =
BigQueryRetryHelper.runWithRetries(
new Callable() {
@@ -900,7 +1186,9 @@ public com.google.api.services.bigquery.model.Model call() throws IOException {
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer());
return Model.fromPb(this, answer);
} catch (BigQueryRetryHelperException e) {
if (isRetryErrorCodeHttpNotFound(e)) {
@@ -910,6 +1198,10 @@ public com.google.api.services.bigquery.model.Model call() throws IOException {
return null;
}
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (modelGet != null) {
+ modelGet.end();
+ }
}
}
@@ -926,7 +1218,18 @@ public Routine getRoutine(RoutineId routineId, RoutineOption... options) {
? getOptions().getProjectId()
: routineId.getProject());
final Map optionsMap = optionMap(options);
- try {
+ Span routineGet = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ routineGet =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.getRoutine")
+ .setAllAttributes(routineId.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope routineGetScope = routineGet != null ? routineGet.makeCurrent() : null) {
com.google.api.services.bigquery.model.Routine answer =
BigQueryRetryHelper.runWithRetries(
new Callable() {
@@ -942,7 +1245,9 @@ public com.google.api.services.bigquery.model.Routine call() throws IOException
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer());
return Routine.fromPb(this, answer);
} catch (BigQueryRetryHelperException e) {
if (isRetryErrorCodeHttpNotFound(e)) {
@@ -952,67 +1257,189 @@ public com.google.api.services.bigquery.model.Routine call() throws IOException
return null;
}
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (routineGet != null) {
+ routineGet.end();
+ }
}
}
@Override
public Page listTables(String datasetId, TableListOption... options) {
- return listTables(
- DatasetId.of(getOptions().getProjectId(), datasetId), getOptions(), optionMap(options));
+ Span tablesList = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ tablesList =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.listTables")
+ .setAllAttributes(DatasetId.of(datasetId).getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope tablesListScope = tablesList != null ? tablesList.makeCurrent() : null) {
+ return listTables(
+ DatasetId.of(getOptions().getProjectId(), datasetId), getOptions(), optionMap(options));
+ } finally {
+ if (tablesList != null) {
+ tablesList.end();
+ }
+ }
}
@Override
public Page listTables(DatasetId datasetId, TableListOption... options) {
DatasetId completeDatasetId = datasetId.setProjectId(getOptions().getProjectId());
- return listTables(completeDatasetId, getOptions(), optionMap(options));
+ Span tablesList = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ tablesList =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.listTables")
+ .setAllAttributes(completeDatasetId.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope tablesListScope = tablesList != null ? tablesList.makeCurrent() : null) {
+ return listTables(completeDatasetId, getOptions(), optionMap(options));
+ } finally {
+ if (tablesList != null) {
+ tablesList.end();
+ }
+ }
}
@Override
public Page listModels(String datasetId, ModelListOption... options) {
- return listModels(
- DatasetId.of(getOptions().getProjectId(), datasetId), getOptions(), optionMap(options));
+ Span modelsList = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ modelsList =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.listModels")
+ .setAllAttributes(DatasetId.of(datasetId).getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope modelsListScope = modelsList != null ? modelsList.makeCurrent() : null) {
+ return listModels(
+ DatasetId.of(getOptions().getProjectId(), datasetId), getOptions(), optionMap(options));
+ } finally {
+ if (modelsList != null) {
+ modelsList.end();
+ }
+ }
}
@Override
public Page listModels(DatasetId datasetId, ModelListOption... options) {
DatasetId completeDatasetId = datasetId.setProjectId(getOptions().getProjectId());
- return listModels(completeDatasetId, getOptions(), optionMap(options));
+ Span modelsList = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ modelsList =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.listModels")
+ .setAllAttributes(datasetId.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope modelsListScope = modelsList != null ? modelsList.makeCurrent() : null) {
+ return listModels(completeDatasetId, getOptions(), optionMap(options));
+ } finally {
+ if (modelsList != null) {
+ modelsList.end();
+ }
+ }
}
@Override
public Page listRoutines(String datasetId, RoutineListOption... options) {
- return listRoutines(
- DatasetId.of(getOptions().getProjectId(), datasetId), getOptions(), optionMap(options));
+ Span routinesList = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ routinesList =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.listRoutines")
+ .setAllAttributes(DatasetId.of(datasetId).getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope routinesListScope = routinesList != null ? routinesList.makeCurrent() : null) {
+ return listRoutines(
+ DatasetId.of(getOptions().getProjectId(), datasetId), getOptions(), optionMap(options));
+ } finally {
+ if (routinesList != null) {
+ routinesList.end();
+ }
+ }
}
@Override
public Page listRoutines(DatasetId datasetId, RoutineListOption... options) {
DatasetId completeDatasetId = datasetId.setProjectId(getOptions().getProjectId());
- return listRoutines(completeDatasetId, getOptions(), optionMap(options));
+ Span routinesList = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ routinesList =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.listRoutines")
+ .setAllAttributes(datasetId.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope routinesListScope = routinesList != null ? routinesList.makeCurrent() : null) {
+ return listRoutines(completeDatasetId, getOptions(), optionMap(options));
+ } finally {
+ if (routinesList != null) {
+ routinesList.end();
+ }
+ }
}
@Override
public List listPartitions(TableId tableId) {
- List partitions = new ArrayList();
- String partitionsTable = tableId.getTable() + "$__PARTITIONS_SUMMARY__";
- TableId metaTableId =
- tableId.getProject() == null
- ? TableId.of(tableId.getDataset(), partitionsTable)
- : TableId.of(tableId.getProject(), tableId.getDataset(), partitionsTable);
- Table metaTable = getTable(metaTableId);
- Schema metaSchema = metaTable.getDefinition().getSchema();
- String partition_id = null;
- for (Field field : metaSchema.getFields()) {
- if (field.getName().equals("partition_id")) {
- partition_id = field.getName();
- break;
- }
+ Span listPartitions = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ listPartitions =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.listPartitions")
+ .setAllAttributes(tableId.getOtelAttributes())
+ .startSpan();
}
- TableResult result = metaTable.list(metaSchema);
- for (FieldValueList list : result.iterateAll()) {
- partitions.add(list.get(partition_id).getStringValue());
+ try (Scope listPartitionsScope = listPartitions != null ? listPartitions.makeCurrent() : null) {
+ List partitions = new ArrayList();
+ String partitionsTable = tableId.getTable() + "$__PARTITIONS_SUMMARY__";
+ TableId metaTableId =
+ tableId.getProject() == null
+ ? TableId.of(tableId.getDataset(), partitionsTable)
+ : TableId.of(tableId.getProject(), tableId.getDataset(), partitionsTable);
+ Table metaTable = getTable(metaTableId);
+ Schema metaSchema = metaTable.getDefinition().getSchema();
+ String partition_id = null;
+ for (Field field : metaSchema.getFields()) {
+ if (field.getName().equals("partition_id")) {
+ partition_id = field.getName();
+ break;
+ }
+ }
+ TableResult result = metaTable.list(metaSchema);
+ for (FieldValueList list : result.iterateAll()) {
+ partitions.add(list.get(partition_id).getStringValue());
+ }
+ return partitions;
+ } finally {
+ if (listPartitions != null) {
+ listPartitions.end();
+ }
}
- return partitions;
}
private static Page listTables(
@@ -1036,7 +1463,9 @@ public Tuple> cal
serviceOptions.getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
serviceOptions.getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ serviceOptions.isOpenTelemetryTracingEnabled(),
+ serviceOptions.getOpenTelemetryTracer());
String cursor = result.x();
Iterable tables =
Iterables.transform(
@@ -1075,7 +1504,9 @@ public Tuple> cal
serviceOptions.getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
serviceOptions.getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ serviceOptions.isOpenTelemetryTracingEnabled(),
+ serviceOptions.getOpenTelemetryTracer());
String cursor = result.x();
Iterable models =
Iterables.transform(
@@ -1114,7 +1545,9 @@ private static Page listRoutines(
serviceOptions.getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
serviceOptions.getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ serviceOptions.isOpenTelemetryTracingEnabled(),
+ serviceOptions.getOpenTelemetryTracer());
String cursor = result.x();
Iterable routines =
Iterables.transform(
@@ -1165,33 +1598,54 @@ public Rows apply(RowToInsert rowToInsert) {
requestPb.setRows(rowsPb);
TableDataInsertAllResponse responsePb;
- if (allInsertIdsSet[0]) {
- // allowing retries only if all row insertIds are set (used for deduplication)
- try {
+ Span insertAll = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ insertAll =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.insertAll")
+ .setAllAttributes(request.getOtelAttributes())
+ .startSpan();
+ }
+ try (Scope insertAllScope = insertAll != null ? insertAll.makeCurrent() : null) {
+ if (allInsertIdsSet[0]) {
+ // allowing retries only if all row insertIds are set (used for deduplication)
+ try {
+ responsePb =
+ BigQueryRetryHelper.runWithRetries(
+ new Callable() {
+ @Override
+ public TableDataInsertAllResponse call() throws Exception {
+ return bigQueryRpc.insertAllSkipExceptionTranslation(
+ tableId.getProject(),
+ tableId.getDataset(),
+ tableId.getTable(),
+ requestPb);
+ }
+ },
+ getOptions().getRetrySettings(),
+ BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
+ getOptions().getClock(),
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer());
+ } catch (BigQueryRetryHelperException e) {
+ throw BigQueryException.translateAndThrow(e);
+ }
+ } else {
+ // Use insertAll that translate the exception as we are not retrying.
responsePb =
- BigQueryRetryHelper.runWithRetries(
- new Callable() {
- @Override
- public TableDataInsertAllResponse call() throws Exception {
- return bigQueryRpc.insertAllSkipExceptionTranslation(
- tableId.getProject(), tableId.getDataset(), tableId.getTable(), requestPb);
- }
- },
- getOptions().getRetrySettings(),
- BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
- getOptions().getClock(),
- EMPTY_RETRY_CONFIG);
- } catch (BigQueryRetryHelperException e) {
- throw BigQueryException.translateAndThrow(e);
+ bigQueryRpc.insertAll(
+ tableId.getProject(), tableId.getDataset(), tableId.getTable(), requestPb);
}
- } else {
- // Use insertAll that translate the exception as we are not retrying.
- responsePb =
- bigQueryRpc.insertAll(
- tableId.getProject(), tableId.getDataset(), tableId.getTable(), requestPb);
- }
- return InsertAllResponse.fromPb(responsePb);
+ return InsertAllResponse.fromPb(responsePb);
+ } finally {
+ if (insertAll != null) {
+ insertAll.end();
+ }
+ }
}
@Override
@@ -1215,11 +1669,28 @@ public TableResult listTableData(
public TableResult listTableData(TableId tableId, Schema schema, TableDataListOption... options) {
Tuple extends Page, Long> data =
listTableData(tableId, schema, getOptions(), optionMap(options));
- return TableResult.newBuilder()
- .setSchema(schema)
- .setTotalRows(data.y())
- .setPageNoSchema(data.x())
- .build();
+ Span tableDataList = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ tableDataList =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.listTableData")
+ .setAllAttributes(tableId.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope tableDataListScope = tableDataList != null ? tableDataList.makeCurrent() : null) {
+ return TableResult.newBuilder()
+ .setSchema(schema)
+ .setTotalRows(data.y())
+ .setPageNoSchema(data.x())
+ .build();
+ } finally {
+ if (tableDataList != null) {
+ tableDataList.end();
+ }
+ }
}
private static Tuple extends Page, Long> listTableData(
@@ -1250,7 +1721,9 @@ public TableDataList call() throws IOException {
serviceOptions.getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
serviceOptions.getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ serviceOptions.isOpenTelemetryTracingEnabled(),
+ serviceOptions.getOpenTelemetryTracer());
String cursor = result.getPageToken();
Map pageOptionMap =
Strings.isNullOrEmpty(cursor) ? optionsMap : optionMap(TableDataListOption.startIndex(0));
@@ -1295,7 +1768,18 @@ public Job getJob(JobId jobId, JobOption... options) {
jobId.getLocation() == null && getOptions().getLocation() != null
? getOptions().getLocation()
: jobId.getLocation());
- try {
+ Span jobGet = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ jobGet =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.getJob")
+ .setAllAttributes(completeJobId.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope jobGetScope = jobGet != null ? jobGet.makeCurrent() : null) {
com.google.api.services.bigquery.model.Job answer =
BigQueryRetryHelper.runWithRetries(
new Callable() {
@@ -1311,7 +1795,9 @@ public com.google.api.services.bigquery.model.Job call() throws IOException {
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer());
return Job.fromPb(this, answer);
} catch (BigQueryRetryHelperException e) {
if (isRetryErrorCodeHttpNotFound(e)) {
@@ -1321,12 +1807,32 @@ public com.google.api.services.bigquery.model.Job call() throws IOException {
return null;
}
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (jobGet != null) {
+ jobGet.end();
+ }
}
}
@Override
public Page listJobs(JobListOption... options) {
- return listJobs(getOptions(), optionMap(options));
+ Span jobsList = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ jobsList =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.listJobs")
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope jobsListScope = jobsList != null ? jobsList.makeCurrent() : null) {
+ return listJobs(getOptions(), optionMap(options));
+ } finally {
+ if (jobsList != null) {
+ jobsList.end();
+ }
+ }
}
private static Page listJobs(
@@ -1346,7 +1852,9 @@ public Tuple> call(
serviceOptions.getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
serviceOptions.getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ serviceOptions.isOpenTelemetryTracingEnabled(),
+ serviceOptions.getOpenTelemetryTracer());
String cursor = result.x();
Iterable jobs =
Iterables.transform(
@@ -1377,7 +1885,17 @@ public boolean cancel(JobId jobId) {
jobId.getLocation() == null && getOptions().getLocation() != null
? getOptions().getLocation()
: jobId.getLocation());
- try {
+ Span jobCancel = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ jobCancel =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.cancelJob")
+ .setAllAttributes(completeJobId.getOtelAttributes())
+ .startSpan();
+ }
+ try (Scope jobCancelScope = jobCancel != null ? jobCancel.makeCurrent() : null) {
return BigQueryRetryHelper.runWithRetries(
new Callable() {
@Override
@@ -1389,12 +1907,18 @@ public Boolean call() throws IOException {
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer());
} catch (BigQueryRetryHelperException e) {
if (isRetryErrorCodeHttpNotFound(e)) {
return false;
}
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (jobCancel != null) {
+ jobCancel.end();
+ }
}
}
@@ -1408,27 +1932,56 @@ public TableResult query(QueryJobConfiguration configuration, JobOption... optio
.setJobCreationMode(getOptions().getDefaultJobCreationMode())
.build();
- // If all parameters passed in configuration are supported by the query() method on the backend,
- // put on fast path
- QueryRequestInfo requestInfo =
- new QueryRequestInfo(configuration, getOptions().getUseInt64Timestamps());
- if (requestInfo.isFastQuerySupported(null)) {
- String projectId = getOptions().getProjectId();
- QueryRequest content = requestInfo.toPb();
- if (getOptions().getLocation() != null) {
- content.setLocation(getOptions().getLocation());
+ Span querySpan = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ querySpan =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.query")
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope queryScope = querySpan != null ? querySpan.makeCurrent() : null) {
+ // If all parameters passed in configuration are supported by the query() method on the
+ // backend,
+ // put on fast path
+ QueryRequestInfo requestInfo =
+ new QueryRequestInfo(configuration, getOptions().getUseInt64Timestamps());
+ if (requestInfo.isFastQuerySupported(null)) {
+ String projectId = getOptions().getProjectId();
+ QueryRequest content = requestInfo.toPb();
+ if (getOptions().getLocation() != null) {
+ content.setLocation(getOptions().getLocation());
+ }
+ return queryRpc(projectId, content, options);
+ }
+ // Otherwise, fall back to the existing create query job logic
+ return create(JobInfo.of(configuration), options).getQueryResults();
+ } finally {
+ if (querySpan != null) {
+ querySpan.end();
}
- return queryRpc(projectId, content, options);
}
- // Otherwise, fall back to the existing create query job logic
- return create(JobInfo.of(configuration), options).getQueryResults();
}
private TableResult queryRpc(
final String projectId, final QueryRequest content, JobOption... options)
throws InterruptedException {
com.google.api.services.bigquery.model.QueryResponse results;
- try {
+ Span queryRpc = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ queryRpc =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.queryRpc")
+ .setAttribute("bq.query.project_id", projectId)
+ .setAllAttributes(otelAttributesFromQueryRequest(content))
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope queryRpcScope = queryRpc != null ? queryRpc.makeCurrent() : null) {
results =
BigQueryRetryHelper.runWithRetries(
new Callable() {
@@ -1441,9 +1994,15 @@ public com.google.api.services.bigquery.model.QueryResponse call()
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- DEFAULT_RETRY_CONFIG);
+ DEFAULT_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer());
} catch (BigQueryRetryHelper.BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (queryRpc != null) {
+ queryRpc.end();
+ }
}
if (results.getErrors() != null) {
@@ -1513,37 +2072,74 @@ public TableResult query(QueryJobConfiguration configuration, JobId jobId, JobOp
throws InterruptedException, JobException {
Job.checkNotDryRun(configuration, "query");
- // If all parameters passed in configuration are supported by the query() method on the backend,
- // put on fast path
- QueryRequestInfo requestInfo =
- new QueryRequestInfo(configuration, getOptions().getUseInt64Timestamps());
- if (requestInfo.isFastQuerySupported(jobId)) {
- // Be careful when setting the projectID in JobId, if a projectID is specified in the JobId,
- // the job created by the query method will use that project. This may cause the query to
- // fail with "Access denied" if the project do not have enough permissions to run the job.
-
- String projectId =
- jobId.getProject() != null ? jobId.getProject() : getOptions().getProjectId();
- QueryRequest content = requestInfo.toPb();
- // Be careful when setting the location, if a location is specified in the BigQueryOption or
- // JobId the job created by the query method will be in that location, even if the table to be
- // queried is in a different location. This may cause the query to fail with
- // "BigQueryException: Not found"
- if (jobId.getLocation() != null) {
- content.setLocation(jobId.getLocation());
- } else if (getOptions().getLocation() != null) {
- content.setLocation(getOptions().getLocation());
- }
+ Span querySpan = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ querySpan =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.query")
+ .setAllAttributes(jobId.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope queryScope = querySpan != null ? querySpan.makeCurrent() : null) {
+ // If all parameters passed in configuration are supported by the query() method on the
+ // backend,
+ // put on fast path
+ QueryRequestInfo requestInfo =
+ new QueryRequestInfo(configuration, getOptions().getUseInt64Timestamps());
+ if (requestInfo.isFastQuerySupported(jobId)) {
+ // Be careful when setting the projectID in JobId, if a projectID is specified in the JobId,
+ // the job created by the query method will use that project. This may cause the query to
+ // fail with "Access denied" if the project do not have enough permissions to run the job.
+
+ String projectId =
+ jobId.getProject() != null ? jobId.getProject() : getOptions().getProjectId();
+ QueryRequest content = requestInfo.toPb();
+ // Be careful when setting the location, if a location is specified in the BigQueryOption or
+ // JobId the job created by the query method will be in that location, even if the table to
+ // be
+ // queried is in a different location. This may cause the query to fail with
+ // "BigQueryException: Not found"
+ if (jobId.getLocation() != null) {
+ content.setLocation(jobId.getLocation());
+ } else if (getOptions().getLocation() != null) {
+ content.setLocation(getOptions().getLocation());
+ }
- return queryRpc(projectId, content, options);
+ return queryRpc(projectId, content, options);
+ }
+ return create(JobInfo.of(jobId, configuration), options).getQueryResults();
+ } finally {
+ if (querySpan != null) {
+ querySpan.end();
+ }
}
- return create(JobInfo.of(jobId, configuration), options).getQueryResults();
}
@Override
public QueryResponse getQueryResults(JobId jobId, QueryResultsOption... options) {
Map optionsMap = optionMap(options);
- return getQueryResults(jobId, getOptions(), optionsMap);
+ Span getQueryResults = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ getQueryResults =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.getQueryResults")
+ .setAllAttributes(jobId.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope getQueryResultsScope =
+ getQueryResults != null ? getQueryResults.makeCurrent() : null) {
+ return getQueryResults(jobId, getOptions(), optionsMap);
+ } finally {
+ if (getQueryResults != null) {
+ getQueryResults.end();
+ }
+ }
}
private static QueryResponse getQueryResults(
@@ -1575,7 +2171,9 @@ public GetQueryResultsResponse call() throws IOException {
serviceOptions.getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
serviceOptions.getClock(),
- DEFAULT_RETRY_CONFIG);
+ DEFAULT_RETRY_CONFIG,
+ serviceOptions.isOpenTelemetryTracingEnabled(),
+ serviceOptions.getOpenTelemetryTracer());
TableSchema schemaPb = results.getSchema();
@@ -1619,8 +2217,19 @@ public Policy getIamPolicy(TableId tableId, IAMOption... options) {
? getOptions().getProjectId()
: tableId.getProject());
- try {
- final Map optionsMap = optionMap(options);
+ final Map optionsMap = optionMap(options);
+ Span iamPolicyGet = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ iamPolicyGet =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.getIamPolicy")
+ .setAllAttributes(tableId.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope iamPolicyGetScope = iamPolicyGet != null ? iamPolicyGet.makeCurrent() : null) {
return convertFromApiPolicy(
BigQueryRetryHelper.runWithRetries(
new Callable() {
@@ -1633,9 +2242,15 @@ public com.google.api.services.bigquery.model.Policy call() throws IOException {
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG));
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer()));
} catch (BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (iamPolicyGet != null) {
+ iamPolicyGet.end();
+ }
}
}
@@ -1646,8 +2261,21 @@ public Policy setIamPolicy(TableId tableId, final Policy policy, IAMOption... op
Strings.isNullOrEmpty(tableId.getProject())
? getOptions().getProjectId()
: tableId.getProject());
- try {
- final Map optionsMap = optionMap(options);
+
+ final Map optionsMap = optionMap(options);
+ Span iamPolicySet = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ iamPolicySet =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.setIamPolicy")
+ .setAllAttributes(tableId.getOtelAttributes())
+ .setAllAttributes(otelAttributesFromPolicy(policy))
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope iamPolicySetScope = iamPolicySet != null ? iamPolicySet.makeCurrent() : null) {
return convertFromApiPolicy(
BigQueryRetryHelper.runWithRetries(
new Callable() {
@@ -1660,9 +2288,15 @@ public com.google.api.services.bigquery.model.Policy call() throws IOException {
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG));
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer()));
} catch (BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (iamPolicySet != null) {
+ iamPolicySet.end();
+ }
}
}
@@ -1674,8 +2308,21 @@ public List testIamPermissions(
Strings.isNullOrEmpty(tableId.getProject())
? getOptions().getProjectId()
: tableId.getProject());
- try {
- final Map optionsMap = optionMap(options);
+ final Map optionsMap = optionMap(options);
+ Span testIamPermissions = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ testIamPermissions =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.BigQuery.testIamPermissions")
+ .setAllAttributes(tableId.getOtelAttributes())
+ .setAttribute("bq.iam.permissions", permissions.toString())
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+ try (Scope testIamPermissionsScope =
+ testIamPermissions != null ? testIamPermissions.makeCurrent() : null) {
com.google.api.services.bigquery.model.TestIamPermissionsResponse response =
BigQueryRetryHelper.runWithRetries(
new Callable() {
@@ -1689,12 +2336,18 @@ public com.google.api.services.bigquery.model.TestIamPermissionsResponse call()
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer());
return response.getPermissions() == null
? ImmutableList.of()
: ImmutableList.copyOf(response.getPermissions());
} catch (BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (testIamPermissions != null) {
+ testIamPermissions.end();
+ }
}
}
@@ -1708,6 +2361,39 @@ public com.google.api.services.bigquery.model.TestIamPermissionsResponse call()
return optionMap;
}
+ private static String getFieldAsString(Object field) {
+ return field == null ? "null" : field.toString();
+ }
+
+ private static Attributes otelAttributesFromOptions(Option... options) {
+ Attributes attributes = Attributes.builder().build();
+ for (Option option : options) {
+ attributes =
+ attributes.toBuilder()
+ .put("bq.option." + option.getRpcOption().toString(), option.getValue().toString())
+ .build();
+ }
+ return attributes;
+ }
+
+ private static Attributes otelAttributesFromQueryRequest(QueryRequest request) {
+ return Attributes.builder()
+ .put("bq.query.dry_run", getFieldAsString(request.getDryRun()))
+ .put("bq.query.job_creation_mode", getFieldAsString(request.getJobCreationMode()))
+ .put("bq.query.kind", getFieldAsString(request.getKind()))
+ .put("bq.query.location", getFieldAsString(request.getLocation()))
+ .put("bq.query.request_id", getFieldAsString(request.getRequestId()))
+ .put("bq.query.use_query_cache", getFieldAsString(request.getUseQueryCache()))
+ .build();
+ }
+
+ private static Attributes otelAttributesFromPolicy(Policy policy) {
+ return Attributes.builder()
+ .put("bq.policy.version", getFieldAsString(policy.getVersion()))
+ .put("bq.policy.bindings", getFieldAsString(policy.getBindings()))
+ .build();
+ }
+
static BigQueryRetryConfig getBigQueryRetryConfig(Map options) {
return (BigQueryRetryConfig)
options.getOrDefault(BigQueryRpc.Option.BIGQUERY_RETRY_CONFIG, null);
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java
index a1dacc4cf..36eeb2086 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java
@@ -16,6 +16,7 @@
package com.google.cloud.bigquery;
+import com.google.api.core.BetaApi;
import com.google.cloud.ServiceDefaults;
import com.google.cloud.ServiceOptions;
import com.google.cloud.ServiceRpc;
@@ -25,6 +26,7 @@
import com.google.cloud.bigquery.spi.v2.HttpBigQueryRpc;
import com.google.cloud.http.HttpTransportOptions;
import com.google.common.collect.ImmutableSet;
+import io.opentelemetry.api.trace.Tracer;
import java.util.Set;
public class BigQueryOptions extends ServiceOptions {
@@ -39,6 +41,8 @@ public class BigQueryOptions extends ServiceOptions {
private boolean setThrowNotFound;
private boolean useInt64Timestamps;
private JobCreationMode defaultJobCreationMode = JobCreationMode.JOB_CREATION_MODE_UNSPECIFIED;
+ private boolean enableOpenTelemetryTracing;
+ private Tracer openTelemetryTracer;
public static class DefaultBigQueryFactory implements BigQueryFactory {
@@ -64,6 +68,8 @@ public static class Builder extends ServiceOptions.Builder {
@@ -171,6 +201,26 @@ public JobCreationMode getDefaultJobCreationMode() {
return defaultJobCreationMode;
}
+ /**
+ * Returns whether this BigQuery instance has OpenTelemetry tracing enabled
+ *
+ * @return true if tracing is enabled, false if not
+ */
+ @BetaApi("Span names and attributes are subject to change without notice")
+ public boolean isOpenTelemetryTracingEnabled() {
+ return enableOpenTelemetryTracing;
+ }
+
+ /**
+ * Returns the OpenTelemetry tracer used by this BigQuery instance
+ *
+ * @return OpenTelemetry tracer object or {@code null} if not set
+ */
+ @BetaApi("Span names and attributes are subject to change without notice")
+ public Tracer getOpenTelemetryTracer() {
+ return openTelemetryTracer;
+ }
+
@SuppressWarnings("unchecked")
@Override
public Builder toBuilder() {
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryRetryHelper.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryRetryHelper.java
index d315241a3..9c7083046 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryRetryHelper.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryRetryHelper.java
@@ -25,6 +25,9 @@
import com.google.api.gax.retrying.RetryingFuture;
import com.google.api.gax.retrying.TimedRetryAlgorithm;
import com.google.cloud.RetryHelper;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.context.Scope;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
@@ -40,9 +43,18 @@ public static V runWithRetries(
RetrySettings retrySettings,
ResultRetryAlgorithm> resultRetryAlgorithm,
ApiClock clock,
- BigQueryRetryConfig bigQueryRetryConfig)
+ BigQueryRetryConfig bigQueryRetryConfig,
+ boolean isOpenTelemetryEnabled,
+ Tracer openTelemetryTracer)
throws RetryHelperException {
- try {
+ Span runWithRetries = null;
+ if (isOpenTelemetryEnabled && openTelemetryTracer != null) {
+ runWithRetries =
+ openTelemetryTracer
+ .spanBuilder("com.google.cloud.bigquery.BigQueryRetryHelper.runWithRetries")
+ .startSpan();
+ }
+ try (Scope runWithRetriesScope = runWithRetries != null ? runWithRetries.makeCurrent() : null) {
// Suppressing should be ok as a workaraund. Current and only ResultRetryAlgorithm
// implementation does not use response at all, so ignoring its type is ok.
@SuppressWarnings("unchecked")
@@ -59,6 +71,10 @@ public static V runWithRetries(
throw new BigQueryRetryHelperException(new BigQueryException((IOException) e.getCause()));
}
throw new BigQueryRetryHelperException(e.getCause());
+ } finally {
+ if (runWithRetries != null) {
+ runWithRetries.end();
+ }
}
}
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ConnectionImpl.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ConnectionImpl.java
index eb3a32db7..b12ad8556 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ConnectionImpl.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ConnectionImpl.java
@@ -476,7 +476,9 @@ private BigQueryResult queryRpc(
bigQueryOptions.getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
bigQueryOptions.getClock(),
- retryConfig);
+ retryConfig,
+ false,
+ null);
} catch (BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
}
@@ -932,7 +934,9 @@ private Job getQueryJobRpc(JobId jobId) {
bigQueryOptions.getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
bigQueryOptions.getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ false,
+ null);
} catch (BigQueryRetryHelperException e) {
if (e.getCause() instanceof BigQueryException) {
if (((BigQueryException) e.getCause()).getCode() == HTTP_NOT_FOUND) {
@@ -977,7 +981,9 @@ TableDataList tableDataListRpc(TableId destinationTable, String pageToken) {
bigQueryOptions.getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
bigQueryOptions.getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ false,
+ null);
return results;
} catch (BigQueryRetryHelperException e) {
@@ -1208,7 +1214,9 @@ GetQueryResultsResponse getQueryResultsFirstPage(JobId jobId) {
bigQueryOptions.getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
bigQueryOptions.getClock(),
- retryConfig);
+ retryConfig,
+ false,
+ null);
if (results.getErrors() != null) {
List bigQueryErrors =
@@ -1471,7 +1479,9 @@ com.google.api.services.bigquery.model.Job createQueryJob(
bigQueryOptions.getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
bigQueryOptions.getClock(),
- retryConfig);
+ retryConfig,
+ false,
+ null);
} catch (BigQueryRetryHelper.BigQueryRetryHelperException e) {
logger.log(Level.WARNING, "\n Error occurred while calling createJobForQuery", e);
throw BigQueryException.translateAndThrow(e);
@@ -1514,7 +1524,9 @@ com.google.api.services.bigquery.model.Job createDryRunJob(String sql) {
bigQueryOptions.getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
bigQueryOptions.getClock(),
- retryConfig);
+ retryConfig,
+ false,
+ null);
} catch (BigQueryRetryHelper.BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
}
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/DatasetId.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/DatasetId.java
index 0e2ad02b2..c06d257d7 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/DatasetId.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/DatasetId.java
@@ -20,6 +20,7 @@
import static com.google.common.base.Strings.isNullOrEmpty;
import com.google.api.services.bigquery.model.DatasetReference;
+import io.opentelemetry.api.common.Attributes;
import java.io.Serializable;
import java.util.Objects;
@@ -84,4 +85,11 @@ DatasetReference toPb() {
static DatasetId fromPb(DatasetReference datasetRef) {
return new DatasetId(datasetRef.getProjectId(), datasetRef.getDatasetId());
}
+
+ protected Attributes getOtelAttributes() {
+ return Attributes.builder()
+ .put("bq.dataset.project", this.getProject())
+ .put("bq.dataset.id", this.getDataset())
+ .build();
+ }
}
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java
index 90d6c2cd5..918761995 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java
@@ -27,6 +27,7 @@
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
+import io.opentelemetry.api.common.Attributes;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
@@ -746,6 +747,18 @@ public static DatasetInfo of(String datasetId) {
return newBuilder(datasetId).build();
}
+ private static String getFieldAsString(Object field) {
+ return field == null ? "null" : field.toString();
+ }
+
+ protected Attributes getOtelAttributes() {
+ return Attributes.builder()
+ .putAll(this.getDatasetId().getOtelAttributes())
+ .put("bq.dataset.last_modified", getFieldAsString(this.getLastModified()))
+ .put("bq.dataset.location", getFieldAsString(this.getLocation()))
+ .build();
+ }
+
static DatasetInfo fromPb(Dataset datasetPb) {
return new BuilderImpl(datasetPb).build();
}
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllRequest.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllRequest.java
index 53952bc6c..ce9380098 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllRequest.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllRequest.java
@@ -22,6 +22,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
+import io.opentelemetry.api.common.Attributes;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
@@ -479,4 +480,15 @@ public boolean equals(Object obj) {
&& Objects.equals(skipInvalidRows, other.skipInvalidRows)
&& Objects.equals(templateSuffix, other.templateSuffix);
}
+
+ private static String getFieldAsString(Object field) {
+ return field == null ? "null" : field.toString();
+ }
+
+ public Attributes getOtelAttributes() {
+ return Attributes.builder()
+ .put("bq.insert_all.table", getFieldAsString(this.getTable().getTable()))
+ .put("bq.insert_all.template_suffix", getFieldAsString(this.getTemplateSuffix()))
+ .build();
+ }
}
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Job.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Job.java
index 00edefb9f..88950b9fb 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Job.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Job.java
@@ -29,6 +29,9 @@
import com.google.cloud.bigquery.BigQuery.TableDataListOption;
import com.google.cloud.bigquery.JobConfiguration.Type;
import com.google.common.collect.ImmutableList;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.context.Scope;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.time.Duration;
@@ -172,7 +175,21 @@ public Job build() {
*/
public boolean exists() {
checkNotDryRun("exists");
- return bigquery.getJob(getJobId(), JobOption.fields()) != null;
+ Span exists = null;
+ if (options.isOpenTelemetryTracingEnabled() && options.getOpenTelemetryTracer() != null) {
+ exists =
+ options
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.Job.exists")
+ .startSpan();
+ }
+ try (Scope existsScope = exists != null ? exists.makeCurrent() : null) {
+ return bigquery.getJob(getJobId(), JobOption.fields()) != null;
+ } finally {
+ if (exists != null) {
+ exists.end();
+ }
+ }
}
/**
@@ -193,8 +210,22 @@ public boolean exists() {
*/
public boolean isDone() {
checkNotDryRun("isDone");
- Job job = bigquery.getJob(getJobId(), JobOption.fields(BigQuery.JobField.STATUS));
- return job == null || JobStatus.State.DONE.equals(job.getStatus().getState());
+ Span isDone = null;
+ if (options.isOpenTelemetryTracingEnabled() && options.getOpenTelemetryTracer() != null) {
+ isDone =
+ options
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.Job.isDone")
+ .startSpan();
+ }
+ try (Scope isDoneScope = isDone != null ? isDone.makeCurrent() : null) {
+ Job job = bigquery.getJob(getJobId(), JobOption.fields(BigQuery.JobField.STATUS));
+ return job == null || JobStatus.State.DONE.equals(job.getStatus().getState());
+ } finally {
+ if (isDone != null) {
+ isDone.end();
+ }
+ }
}
/** See {@link #waitFor(BigQueryRetryConfig, RetryOption...)} */
@@ -275,19 +306,34 @@ public Job waitFor(BigQueryRetryConfig bigQueryRetryConfig, RetryOption... waitO
private Job waitForInternal(BigQueryRetryConfig bigQueryRetryConfig, RetryOption... waitOptions)
throws InterruptedException {
checkNotDryRun("waitFor");
- Object completedJobResponse;
- if (getConfiguration().getType() == Type.QUERY) {
- completedJobResponse =
- waitForQueryResults(
- RetryOption.mergeToSettings(DEFAULT_JOB_WAIT_SETTINGS, waitOptions),
- bigQueryRetryConfig,
- DEFAULT_QUERY_WAIT_OPTIONS);
- } else {
- completedJobResponse =
- waitForJob(RetryOption.mergeToSettings(DEFAULT_QUERY_JOB_WAIT_SETTINGS, waitOptions));
+ Span waitFor = null;
+ if (this.options.isOpenTelemetryTracingEnabled()
+ && this.options.getOpenTelemetryTracer() != null) {
+ waitFor =
+ this.options
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.Job.waitFor")
+ .startSpan();
}
+ try (Scope waitForScope = waitFor != null ? waitFor.makeCurrent() : null) {
+ Object completedJobResponse;
+ if (getConfiguration().getType() == Type.QUERY) {
+ completedJobResponse =
+ waitForQueryResults(
+ RetryOption.mergeToSettings(DEFAULT_JOB_WAIT_SETTINGS, waitOptions),
+ bigQueryRetryConfig,
+ DEFAULT_QUERY_WAIT_OPTIONS);
+ } else {
+ completedJobResponse =
+ waitForJob(RetryOption.mergeToSettings(DEFAULT_QUERY_JOB_WAIT_SETTINGS, waitOptions));
+ }
- return completedJobResponse == null ? null : reload();
+ return completedJobResponse == null ? null : reload();
+ } finally {
+ if (waitFor != null) {
+ waitFor.end();
+ }
+ }
}
/**
@@ -304,72 +350,91 @@ private Job waitForInternal(BigQueryRetryConfig bigQueryRetryConfig, RetryOption
public TableResult getQueryResults(QueryResultsOption... options)
throws InterruptedException, JobException {
checkNotDryRun("getQueryResults");
- if (getConfiguration().getType() != Type.QUERY) {
- throw new UnsupportedOperationException(
- "Getting query results is supported only for " + Type.QUERY + " jobs");
- }
-
- List waitOptions =
- new ArrayList<>(Arrays.asList(DEFAULT_QUERY_WAIT_OPTIONS));
- List listOptions = new ArrayList<>();
- for (QueryResultsOption option : options) {
- switch (option.getRpcOption()) {
- case MAX_RESULTS:
- listOptions.add(TableDataListOption.pageSize((Long) option.getValue()));
- break;
- case PAGE_TOKEN:
- listOptions.add(TableDataListOption.pageToken((String) option.getValue()));
- break;
- case START_INDEX:
- listOptions.add(TableDataListOption.startIndex((Long) option.getValue()));
- break;
- case TIMEOUT:
- waitOptions.add(QueryResultsOption.maxWaitTime((Long) option.getValue()));
- break;
- }
+
+ Span getQueryResults = null;
+ if (this.options.isOpenTelemetryTracingEnabled()
+ && this.options.getOpenTelemetryTracer() != null) {
+ getQueryResults =
+ this.options
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.Job.getQueryResults")
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
}
+ try (Scope getQueryResultsScope =
+ getQueryResults != null ? getQueryResults.makeCurrent() : null) {
- QueryResponse response =
- waitForQueryResults(
- DEFAULT_JOB_WAIT_SETTINGS,
- DEFAULT_RETRY_CONFIG,
- waitOptions.toArray(new QueryResultsOption[0]));
-
- // Get the job resource to determine if it has errored.
- Job job = this;
- if (job.getStatus() == null || !JobStatus.State.DONE.equals(job.getStatus().getState())) {
- job = reload();
- }
- if (job.getStatus() != null && job.getStatus().getError() != null) {
- throw new BigQueryException(
- job.getStatus().getExecutionErrors() == null
- ? ImmutableList.of(job.getStatus().getError())
- : ImmutableList.copyOf(job.getStatus().getExecutionErrors()));
- }
-
- // If there are no rows in the result, this may have been a DDL query.
- // Listing table data might fail, such as with CREATE VIEW queries.
- // Avoid a tabledata.list API request by returning an empty TableResult.
- if (response.getTotalRows() == 0) {
- TableResult emptyTableResult =
- TableResult.newBuilder()
- .setSchema(response.getSchema())
- .setJobId(job.getJobId())
- .setTotalRows(0L)
- .setPageNoSchema(new PageImpl(null, "", null))
- .build();
- return emptyTableResult;
- }
-
- TableId table =
- ((QueryJobConfiguration) getConfiguration()).getDestinationTable() == null
- ? ((QueryJobConfiguration) job.getConfiguration()).getDestinationTable()
- : ((QueryJobConfiguration) getConfiguration()).getDestinationTable();
- TableResult tableResult =
- bigquery.listTableData(
- table, response.getSchema(), listOptions.toArray(new TableDataListOption[0]));
- TableResult tableResultWithJobId = tableResult.toBuilder().setJobId(job.getJobId()).build();
- return tableResultWithJobId;
+ if (getConfiguration().getType() != Type.QUERY) {
+ throw new UnsupportedOperationException(
+ "Getting query results is supported only for " + Type.QUERY + " jobs");
+ }
+
+ List waitOptions =
+ new ArrayList<>(Arrays.asList(DEFAULT_QUERY_WAIT_OPTIONS));
+ List listOptions = new ArrayList<>();
+ for (QueryResultsOption option : options) {
+ switch (option.getRpcOption()) {
+ case MAX_RESULTS:
+ listOptions.add(TableDataListOption.pageSize((Long) option.getValue()));
+ break;
+ case PAGE_TOKEN:
+ listOptions.add(TableDataListOption.pageToken((String) option.getValue()));
+ break;
+ case START_INDEX:
+ listOptions.add(TableDataListOption.startIndex((Long) option.getValue()));
+ break;
+ case TIMEOUT:
+ waitOptions.add(QueryResultsOption.maxWaitTime((Long) option.getValue()));
+ break;
+ }
+ }
+
+ QueryResponse response =
+ waitForQueryResults(
+ DEFAULT_JOB_WAIT_SETTINGS,
+ DEFAULT_RETRY_CONFIG,
+ waitOptions.toArray(new QueryResultsOption[0]));
+
+ // Get the job resource to determine if it has errored.
+ Job job = this;
+ if (job.getStatus() == null || !JobStatus.State.DONE.equals(job.getStatus().getState())) {
+ job = reload();
+ }
+ if (job.getStatus() != null && job.getStatus().getError() != null) {
+ throw new BigQueryException(
+ job.getStatus().getExecutionErrors() == null
+ ? ImmutableList.of(job.getStatus().getError())
+ : ImmutableList.copyOf(job.getStatus().getExecutionErrors()));
+ }
+
+ // If there are no rows in the result, this may have been a DDL query.
+ // Listing table data might fail, such as with CREATE VIEW queries.
+ // Avoid a tabledata.list API request by returning an empty TableResult.
+ if (response.getTotalRows() == 0) {
+ TableResult emptyTableResult =
+ TableResult.newBuilder()
+ .setSchema(response.getSchema())
+ .setJobId(job.getJobId())
+ .setTotalRows(0L)
+ .setPageNoSchema(new PageImpl(null, "", null))
+ .build();
+ return emptyTableResult;
+ }
+
+ TableId table =
+ ((QueryJobConfiguration) getConfiguration()).getDestinationTable() == null
+ ? ((QueryJobConfiguration) job.getConfiguration()).getDestinationTable()
+ : ((QueryJobConfiguration) getConfiguration()).getDestinationTable();
+ TableResult tableResult =
+ bigquery.listTableData(
+ table, response.getSchema(), listOptions.toArray(new TableDataListOption[0]));
+ TableResult tableResultWithJobId = tableResult.toBuilder().setJobId(job.getJobId()).build();
+ return tableResultWithJobId;
+ } finally {
+ if (getQueryResults != null) {
+ getQueryResults.end();
+ }
+ }
}
private QueryResponse waitForQueryResults(
@@ -382,7 +447,17 @@ private QueryResponse waitForQueryResults(
"Waiting for query results is supported only for " + Type.QUERY + " jobs");
}
- try {
+ Span waitForQueryResults = null;
+ if (options.isOpenTelemetryTracingEnabled() && options.getOpenTelemetryTracer() != null) {
+ waitForQueryResults =
+ options
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.Job.waitForQueryResults")
+ .setAllAttributes(otelAttributesFromOptions(resultsOptions))
+ .startSpan();
+ }
+ try (Scope waitForQueryResultsScope =
+ waitForQueryResults != null ? waitForQueryResults.makeCurrent() : null) {
return BigQueryRetryHelper.runWithRetries(
new Callable() {
@Override
@@ -401,14 +476,43 @@ public boolean shouldRetry(
}
},
options.getClock(),
- bigQueryRetryConfig);
+ bigQueryRetryConfig,
+ options.isOpenTelemetryTracingEnabled(),
+ options.getOpenTelemetryTracer());
} catch (BigQueryRetryHelper.BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (waitForQueryResults != null) {
+ waitForQueryResults.end();
+ }
}
}
private Job waitForJob(RetrySettings waitSettings) throws InterruptedException {
- try {
+ Span waitForJob = null;
+ if (options.isOpenTelemetryTracingEnabled() && options.getOpenTelemetryTracer() != null) {
+ waitForJob =
+ this.options
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.Job.waitForJob")
+ .setAttribute(
+ "bq.job.wait_settings.total_timeout",
+ getFieldAsString(waitSettings.getTotalTimeoutDuration()))
+ .setAttribute(
+ "bq.job.wait_settings.initial_retry_delay",
+ getFieldAsString(waitSettings.getInitialRetryDelayDuration()))
+ .setAttribute(
+ "bq.job.wait_settings.max_retry_delay",
+ getFieldAsString(waitSettings.getMaxRetryDelayDuration()))
+ .setAttribute(
+ "bq.job.wait_settings.initial_rpc_timeout",
+ getFieldAsString(waitSettings.getInitialRpcTimeoutDuration()))
+ .setAttribute(
+ "bq.job.wait_settings.max_rpc_timeout",
+ getFieldAsString(waitSettings.getMaxRpcTimeoutDuration()))
+ .startSpan();
+ }
+ try (Scope waitForJobScope = waitForJob != null ? waitForJob.makeCurrent() : null) {
return RetryHelper.poll(
new Callable() {
@Override
@@ -433,6 +537,10 @@ public boolean shouldRetry(Throwable prevThrowable, Job prevResponse) {
options.getClock());
} catch (ExecutionException e) {
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (waitForJob != null) {
+ waitForJob.end();
+ }
}
}
@@ -463,14 +571,31 @@ public boolean shouldRetry(Throwable prevThrowable, Job prevResponse) {
*/
public Job reload(JobOption... options) {
checkNotDryRun("reload");
- Job job = bigquery.getJob(getJobId(), options);
- if (job != null && job.getStatus().getError() != null) {
- throw new BigQueryException(
- job.getStatus().getExecutionErrors() == null
- ? ImmutableList.of(job.getStatus().getError())
- : ImmutableList.copyOf(job.getStatus().getExecutionErrors()));
- }
- return job;
+ Span reload = null;
+ if (this.options.isOpenTelemetryTracingEnabled()
+ && this.options.getOpenTelemetryTracer() != null) {
+ reload =
+ this.options
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.Job.reload")
+ .setAllAttributes(otelAttributesFromOptions(options))
+ .startSpan();
+ }
+
+ try (Scope reloadScope = reload != null ? reload.makeCurrent() : null) {
+ Job job = bigquery.getJob(getJobId(), options);
+ if (job != null && job.getStatus().getError() != null) {
+ throw new BigQueryException(
+ job.getStatus().getExecutionErrors() == null
+ ? ImmutableList.of(job.getStatus().getError())
+ : ImmutableList.copyOf(job.getStatus().getExecutionErrors()));
+ }
+ return job;
+ } finally {
+ if (reload != null) {
+ reload.end();
+ }
+ }
}
/**
@@ -492,7 +617,22 @@ public Job reload(JobOption... options) {
*/
public boolean cancel() {
checkNotDryRun("cancel");
- return bigquery.cancel(getJobId());
+ Span cancel = null;
+ if (options.isOpenTelemetryTracingEnabled() && options.getOpenTelemetryTracer() != null) {
+ cancel =
+ options
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.Job.cancel")
+ .startSpan();
+ }
+
+ try (Scope cancelScope = cancel != null ? cancel.makeCurrent() : null) {
+ return bigquery.cancel(getJobId());
+ } finally {
+ if (cancel != null) {
+ cancel.end();
+ }
+ }
}
private void checkNotDryRun(String op) {
@@ -556,4 +696,19 @@ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundE
static Job fromPb(BigQuery bigquery, com.google.api.services.bigquery.model.Job jobPb) {
return new Job(bigquery, new JobInfo.BuilderImpl(jobPb));
}
+
+ private static Attributes otelAttributesFromOptions(Option... options) {
+ Attributes attributes = Attributes.builder().build();
+ for (Option option : options) {
+ attributes =
+ attributes.toBuilder()
+ .put(option.getRpcOption().toString(), option.getValue().toString())
+ .build();
+ }
+ return attributes;
+ }
+
+ private static String getFieldAsString(Object field) {
+ return field == null ? "null" : field.toString();
+ }
}
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/JobId.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/JobId.java
index b966cebe1..4bfc2aa00 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/JobId.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/JobId.java
@@ -21,6 +21,7 @@
import com.google.api.services.bigquery.model.JobReference;
import com.google.auto.value.AutoValue;
+import io.opentelemetry.api.common.Attributes;
import java.io.Serializable;
import java.util.UUID;
import javax.annotation.Nullable;
@@ -123,4 +124,16 @@ static JobId fromPb(JobReference jobRef) {
.setLocation(jobRef.getLocation())
.build();
}
+
+ private static String getFieldAsString(Object field) {
+ return field == null ? "null" : field.toString();
+ }
+
+ protected Attributes getOtelAttributes() {
+ return Attributes.builder()
+ .put("bq.job.id", getFieldAsString(this.getJob()))
+ .put("bq.job.location", getFieldAsString(this.getLocation()))
+ .put("bq.job.project", getFieldAsString(this.getProject()))
+ .build();
+ }
}
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ModelId.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ModelId.java
index 9356c6935..adb497ffa 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ModelId.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ModelId.java
@@ -21,6 +21,7 @@
import com.google.api.services.bigquery.model.ModelReference;
import com.google.common.base.Function;
+import io.opentelemetry.api.common.Attributes;
import java.io.Serializable;
import java.util.Objects;
@@ -105,4 +106,12 @@ ModelReference toPb() {
static ModelId fromPb(ModelReference modelRef) {
return new ModelId(modelRef.getProjectId(), modelRef.getDatasetId(), modelRef.getModelId());
}
+
+ protected Attributes getOtelAttributes() {
+ return Attributes.builder()
+ .put("bq.model.project", this.getProject())
+ .put("bq.model.dataset", this.getDataset())
+ .put("bq.model.id", this.getModel())
+ .build();
+ }
}
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ModelInfo.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ModelInfo.java
index 922ed441c..3039483b5 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ModelInfo.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/ModelInfo.java
@@ -26,6 +26,7 @@
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
+import io.opentelemetry.api.common.Attributes;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
@@ -453,4 +454,19 @@ Model toPb() {
static ModelInfo fromPb(Model modelPb) {
return new BuilderImpl(modelPb).build();
}
+
+ private static String getFieldAsString(Object field) {
+ return field == null ? "null" : field.toString();
+ }
+
+ protected Attributes getOtelAttributes() {
+ return Attributes.builder()
+ .putAll(this.getModelId().getOtelAttributes())
+ .put("bq.model.type", getFieldAsString(this.getModelType()))
+ .put("bq.model.creation_time", getFieldAsString(this.getCreationTime()))
+ .put("bq.model.last_modified_time", getFieldAsString(this.getLastModifiedTime()))
+ .put("bq.model.expiration_time", getFieldAsString(this.getExpirationTime()))
+ .put("bq.model.location", getFieldAsString(this.getLocation()))
+ .build();
+ }
}
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RoutineId.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RoutineId.java
index c5c3dadb3..a632fc5a1 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RoutineId.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RoutineId.java
@@ -21,6 +21,7 @@
import com.google.api.services.bigquery.model.RoutineReference;
import com.google.common.base.Function;
+import io.opentelemetry.api.common.Attributes;
import java.io.Serializable;
import java.util.Objects;
@@ -108,4 +109,12 @@ static RoutineId fromPb(RoutineReference routineRef) {
return new RoutineId(
routineRef.getProjectId(), routineRef.getDatasetId(), routineRef.getRoutineId());
}
+
+ protected Attributes getOtelAttributes() {
+ return Attributes.builder()
+ .put("bq.routine.project", this.getProject())
+ .put("bq.routine.dataset", this.getDataset())
+ .put("bq.routine.id", this.getRoutine())
+ .build();
+ }
}
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RoutineInfo.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RoutineInfo.java
index 646a2fdea..c13b90b41 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RoutineInfo.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RoutineInfo.java
@@ -24,6 +24,7 @@
import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
+import io.opentelemetry.api.common.Attributes;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
@@ -544,4 +545,17 @@ Routine toPb() {
static RoutineInfo fromPb(Routine routinePb) {
return new BuilderImpl(routinePb).build();
}
+
+ private static String getFieldAsString(Object field) {
+ return field == null ? "null" : field.toString();
+ }
+
+ protected Attributes getOtelAttributes() {
+ return Attributes.builder()
+ .putAll(this.getRoutineId().getOtelAttributes())
+ .put("bq.routine.type", getFieldAsString(this.getRoutineType()))
+ .put("bq.routine.creation_time", getFieldAsString(this.getCreationTime()))
+ .put("bq.routine.last_modified_time", getFieldAsString(this.getLastModifiedTime()))
+ .build();
+ }
}
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/TableDataWriteChannel.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/TableDataWriteChannel.java
index aabd87d47..cc64ec72f 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/TableDataWriteChannel.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/TableDataWriteChannel.java
@@ -20,6 +20,8 @@
import com.google.cloud.RestorableState;
import com.google.cloud.WriteChannel;
import com.google.cloud.bigquery.BigQueryRetryHelper.BigQueryRetryHelperException;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.context.Scope;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
@@ -50,7 +52,19 @@ public class TableDataWriteChannel
@Override
protected void flushBuffer(final int length, final boolean last) {
- try {
+ Span flushBuffer = null;
+ if (getOptions().isOpenTelemetryTracingEnabled()
+ && getOptions().getOpenTelemetryTracer() != null) {
+ flushBuffer =
+ getOptions()
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.TableDataWriteChannel.flushBuffer")
+ .setAttribute("bq.table_data_write_channel.flush_buffer.length", length)
+ .setAttribute("bq.table_data_write_channel.flush_buffer.last", last)
+ .startSpan();
+ }
+
+ try (Scope flushBufferScope = flushBuffer != null ? flushBuffer.makeCurrent() : null) {
com.google.api.services.bigquery.model.Job jobPb =
BigQueryRetryHelper.runWithRetries(
new Callable() {
@@ -65,10 +79,16 @@ public com.google.api.services.bigquery.model.Job call() throws IOException {
getOptions().getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
getOptions().getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ getOptions().isOpenTelemetryTracingEnabled(),
+ getOptions().getOpenTelemetryTracer());
job = jobPb != null ? Job.fromPb(getOptions().getService(), jobPb) : null;
} catch (BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (flushBuffer != null) {
+ flushBuffer.end();
+ }
}
}
@@ -81,7 +101,18 @@ private static String open(
final BigQueryOptions options,
final JobId jobId,
final WriteChannelConfiguration writeChannelConfiguration) {
- try {
+ Span open = null;
+ if (options.isOpenTelemetryTracingEnabled() && options.getOpenTelemetryTracer() != null) {
+ open =
+ options
+ .getOpenTelemetryTracer()
+ .spanBuilder("com.google.cloud.bigquery.TableDataWriteChannel.open")
+ .setAllAttributes(jobId.getOtelAttributes())
+ .setAllAttributes(writeChannelConfiguration.getDestinationTable().getOtelAttributes())
+ .startSpan();
+ }
+
+ try (Scope openScope = open != null ? open.makeCurrent() : null) {
return BigQueryRetryHelper.runWithRetries(
new Callable() {
@Override
@@ -97,9 +128,15 @@ public String call() throws IOException {
options.getRetrySettings(),
BigQueryBaseService.BIGQUERY_EXCEPTION_HANDLER,
options.getClock(),
- EMPTY_RETRY_CONFIG);
+ EMPTY_RETRY_CONFIG,
+ options.isOpenTelemetryTracingEnabled(),
+ options.getOpenTelemetryTracer());
} catch (BigQueryRetryHelperException e) {
throw BigQueryException.translateAndThrow(e);
+ } finally {
+ if (open != null) {
+ open.end();
+ }
}
}
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/TableId.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/TableId.java
index b74055d4f..fcc208453 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/TableId.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/TableId.java
@@ -22,6 +22,7 @@
import com.google.api.services.bigquery.model.TableReference;
import com.google.common.base.Function;
+import io.opentelemetry.api.common.Attributes;
import java.io.Serializable;
import java.util.Objects;
@@ -114,4 +115,12 @@ TableReference toPb() {
static TableId fromPb(TableReference tableRef) {
return new TableId(tableRef.getProjectId(), tableRef.getDatasetId(), tableRef.getTableId());
}
+
+ protected Attributes getOtelAttributes() {
+ return Attributes.builder()
+ .put("bq.table.project", this.getProject())
+ .put("bq.table.dataset", this.getDataset())
+ .put("bq.table.id", this.getTable())
+ .build();
+ }
}
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/TableInfo.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/TableInfo.java
index 6e050d064..b3236f4c3 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/TableInfo.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/TableInfo.java
@@ -25,6 +25,7 @@
import com.google.api.services.bigquery.model.Table;
import com.google.common.base.Function;
import com.google.common.base.MoreObjects;
+import io.opentelemetry.api.common.Attributes;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.Map;
@@ -763,4 +764,19 @@ Table toPb() {
static TableInfo fromPb(Table tablePb) {
return new BuilderImpl(tablePb).build();
}
+
+ private static String getFieldAsString(Object field) {
+ return field == null ? "null" : field.toString();
+ }
+
+ protected Attributes getOtelAttributes() {
+ return Attributes.builder()
+ .putAll(this.getTableId().getOtelAttributes())
+ .put("bq.table.creation_time", getFieldAsString(this.getCreationTime()))
+ .put("bq.table.expiration_time", getFieldAsString(this.getExpirationTime()))
+ .put("bq.table.last_modified_time", getFieldAsString(this.getLastModifiedTime()))
+ .put("bq.table.num_bytes", getFieldAsString(this.getNumBytes()))
+ .put("bq.table.num_rows", getFieldAsString(this.getNumRows()))
+ .build();
+ }
}
diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java
index bd17b14fc..551e1eb40 100644
--- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java
+++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java
@@ -161,6 +161,17 @@
import com.google.common.io.BaseEncoding;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.gson.JsonObject;
+import io.opentelemetry.api.OpenTelemetry;
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.context.Scope;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
+import io.opentelemetry.sdk.common.CompletableResultCode;
+import io.opentelemetry.sdk.trace.SdkTracerProvider;
+import io.opentelemetry.sdk.trace.data.SpanData;
+import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
+import io.opentelemetry.sdk.trace.samplers.Sampler;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -220,6 +231,11 @@ public class ITBigQueryTest {
private static final String STORAGE_BILLING_MODEL = "LOGICAL";
private static final Long MAX_TIME_TRAVEL_HOURS = 120L;
private static final Long MAX_TIME_TRAVEL_HOURS_DEFAULT = 168L;
+ private static final Map, Object>> OTEL_ATTRIBUTES =
+ new HashMap, Object>>();
+ private static final Map OTEL_PARENT_SPAN_IDS = new HashMap<>();
+ private static final Map OTEL_SPAN_IDS_TO_NAMES = new HashMap<>();
+ private static final String OTEL_PARENT_SPAN_ID = "0000000000000000";
private static final String CLOUD_SAMPLES_DATA =
Optional.fromNullable(System.getenv("CLOUD_SAMPLES_DATA_BUCKET")).or("cloud-samples-data");
private static final Map LABELS =
@@ -1017,6 +1033,32 @@ public class ITBigQueryTest {
private static BigQuery bigquery;
private static Storage storage;
+ private static OpenTelemetry otel;
+
+ private static class TestSpanExporter implements io.opentelemetry.sdk.trace.export.SpanExporter {
+ @Override
+ public CompletableResultCode export(Collection collection) {
+ if (collection.isEmpty()) {
+ return CompletableResultCode.ofFailure();
+ }
+ for (SpanData data : collection) {
+ OTEL_ATTRIBUTES.put(data.getName(), data.getAttributes().asMap());
+ OTEL_PARENT_SPAN_IDS.put(data.getName(), data.getParentSpanId());
+ OTEL_SPAN_IDS_TO_NAMES.put(data.getSpanId(), data.getName());
+ }
+ return CompletableResultCode.ofSuccess();
+ }
+
+ @Override
+ public CompletableResultCode flush() {
+ return CompletableResultCode.ofSuccess();
+ }
+
+ @Override
+ public CompletableResultCode shutdown() {
+ return CompletableResultCode.ofSuccess();
+ }
+ }
@Rule public Timeout globalTimeout = Timeout.seconds(300);
@@ -1025,6 +1067,13 @@ public static void beforeClass() throws InterruptedException, IOException {
RemoteBigQueryHelper bigqueryHelper = RemoteBigQueryHelper.create();
RemoteStorageHelper storageHelper = RemoteStorageHelper.create();
Map labels = ImmutableMap.of("test-job-name", "test-load-job");
+ SdkTracerProvider tracerProvider =
+ SdkTracerProvider.builder()
+ .addSpanProcessor(SimpleSpanProcessor.create(new TestSpanExporter()))
+ .setSampler(Sampler.alwaysOn())
+ .build();
+ otel = OpenTelemetrySdk.builder().setTracerProvider(tracerProvider).buildAndRegisterGlobal();
+
bigquery = bigqueryHelper.getOptions().getService();
storage = storageHelper.getOptions().getService();
storage.create(BucketInfo.of(BUCKET));
@@ -6440,6 +6489,14 @@ public void testLocation() throws Exception {
assertThat(location).isNotEqualTo(wrongLocation);
+ Tracer tracer = otel.getTracer("Test Tracer");
+ bigquery =
+ bigquery.getOptions().toBuilder()
+ .setEnableOpenTelemetryTracing(true)
+ .setOpenTelemetryTracer(tracer)
+ .build()
+ .getService();
+
Dataset dataset =
bigquery.create(
DatasetInfo.newBuilder("locationset_" + UUID.randomUUID().toString().replace("-", "_"))
@@ -6516,6 +6573,11 @@ public void testLocation() throws Exception {
bigquery.writer(
JobId.newBuilder().setLocation(location).build(), writeChannelConfiguration)) {
writer.write(ByteBuffer.wrap("foo".getBytes()));
+ assertEquals(
+ OTEL_ATTRIBUTES
+ .get("com.google.cloud.bigquery.TableDataWriteChannel.open")
+ .get(AttributeKey.stringKey("bq.job.location")),
+ location);
}
try {
@@ -6528,6 +6590,12 @@ public void testLocation() throws Exception {
}
} finally {
bigquery.delete(dataset.getDatasetId(), DatasetDeleteOption.deleteContents());
+ bigquery =
+ bigquery.getOptions().toBuilder()
+ .setEnableOpenTelemetryTracing(false)
+ .setOpenTelemetryTracer(null)
+ .build()
+ .getService();
}
}
@@ -7493,4 +7561,163 @@ public void testStatementType() throws InterruptedException {
assertTrue(remoteTable.getDefinition() instanceof MaterializedViewDefinition);
assertTrue(remoteTable.delete());
}
+
+ @Test
+ public void testOpenTelemetryTracingDatasets() {
+ Tracer tracer = otel.getTracer("Test Tracer");
+ BigQueryOptions otelOptions =
+ BigQueryOptions.newBuilder()
+ .setEnableOpenTelemetryTracing(true)
+ .setOpenTelemetryTracer(tracer)
+ .build();
+ BigQuery bigquery = otelOptions.getService();
+
+ Span parentSpan =
+ tracer
+ .spanBuilder("Test Parent Span")
+ .setNoParent()
+ .setAttribute("test-attribute", "test-value")
+ .startSpan();
+ String billingModelDataset = RemoteBigQueryHelper.generateDatasetName();
+
+ try (Scope parentScope = parentSpan.makeCurrent()) {
+ DatasetInfo info =
+ DatasetInfo.newBuilder(billingModelDataset)
+ .setDescription(DESCRIPTION)
+ .setMaxTimeTravelHours(72L)
+ .setLabels(LABELS)
+ .build();
+
+ Dataset dataset = bigquery.create(info);
+ assertNotNull(dataset);
+ dataset = bigquery.getDataset(dataset.getDatasetId().getDataset());
+ assertNotNull(dataset);
+
+ DatasetInfo updatedInfo =
+ DatasetInfo.newBuilder(billingModelDataset)
+ .setDescription("Updated Description")
+ .setMaxTimeTravelHours(96L)
+ .setLabels(LABELS)
+ .build();
+
+ dataset = bigquery.update(updatedInfo, DatasetOption.accessPolicyVersion(2));
+ assertEquals(dataset.getDescription(), "Updated Description");
+ assertTrue(bigquery.delete(dataset.getDatasetId()));
+ } finally {
+ parentSpan.end();
+ Map, Object> createMap =
+ OTEL_ATTRIBUTES.get("com.google.cloud.bigquery.BigQuery.createDataset");
+ assertEquals(createMap.get(AttributeKey.stringKey("bq.dataset.location")), "null");
+
+ Map, Object> getMap =
+ OTEL_ATTRIBUTES.get("com.google.cloud.bigquery.BigQuery.getDataset");
+ assertEquals(getMap.get(AttributeKey.stringKey("bq.dataset.id")), billingModelDataset);
+
+ Map, Object> updateMap =
+ OTEL_ATTRIBUTES.get("com.google.cloud.bigquery.BigQuery.updateDataset");
+ assertEquals(updateMap.get(AttributeKey.stringKey("bq.option.ACCESS_POLICY_VERSION")), "2");
+
+ Map, Object> deleteMap =
+ OTEL_ATTRIBUTES.get("com.google.cloud.bigquery.BigQuery.deleteDataset");
+ assertEquals(deleteMap.get(AttributeKey.stringKey("bq.dataset.id")), billingModelDataset);
+
+ // All should be children spans of parentSpan
+ assertEquals(
+ OTEL_SPAN_IDS_TO_NAMES.get(
+ OTEL_PARENT_SPAN_IDS.get("com.google.cloud.bigquery.BigQuery.getDataset")),
+ "Test Parent Span");
+ assertEquals(
+ OTEL_SPAN_IDS_TO_NAMES.get(
+ OTEL_PARENT_SPAN_IDS.get("com.google.cloud.bigquery.BigQuery.createDataset")),
+ "Test Parent Span");
+ assertEquals(
+ OTEL_SPAN_IDS_TO_NAMES.get(
+ OTEL_PARENT_SPAN_IDS.get("com.google.cloud.bigquery.BigQuery.deleteDataset")),
+ "Test Parent Span");
+ assertEquals(OTEL_PARENT_SPAN_IDS.get("Test Parent Span"), OTEL_PARENT_SPAN_ID);
+ RemoteBigQueryHelper.forceDelete(bigquery, billingModelDataset);
+ }
+ }
+
+ @Test
+ public void testOpenTelemetryTracingTables() {
+ Tracer tracer = otel.getTracer("Test Tracer");
+ BigQueryOptions otelOptions =
+ BigQueryOptions.newBuilder()
+ .setEnableOpenTelemetryTracing(true)
+ .setOpenTelemetryTracer(tracer)
+ .build();
+ BigQuery bigquery = otelOptions.getService();
+
+ String tableName = "test_otel_table";
+ StandardTableDefinition tableDefinition = StandardTableDefinition.of(TABLE_SCHEMA);
+ TableInfo tableInfo =
+ TableInfo.newBuilder(TableId.of(DATASET, tableName), tableDefinition)
+ .setDescription("Some Description")
+ .build();
+ Table createdTable = bigquery.create(tableInfo);
+ assertThat(createdTable.getDescription()).isEqualTo("Some Description");
+
+ assertEquals(
+ OTEL_PARENT_SPAN_IDS.get("com.google.cloud.bigquery.BigQuery.createTable"),
+ OTEL_PARENT_SPAN_ID);
+ assertEquals(
+ OTEL_ATTRIBUTES
+ .get("com.google.cloud.bigquery.BigQuery.createTable")
+ .get(AttributeKey.stringKey("bq.table.id")),
+ tableName);
+ assertEquals(
+ OTEL_ATTRIBUTES
+ .get("com.google.cloud.bigquery.BigQuery.createTable")
+ .get(AttributeKey.stringKey("bq.table.creation_time")),
+ "null");
+
+ Table updatedTable =
+ bigquery.update(createdTable.toBuilder().setDescription("Updated Description").build());
+ assertThat(updatedTable.getDescription()).isEqualTo("Updated Description");
+
+ assertNotNull(OTEL_ATTRIBUTES.get("com.google.cloud.bigquery.BigQuery.updateTable"));
+ assertEquals(
+ OTEL_PARENT_SPAN_IDS.get("com.google.cloud.bigquery.BigQuery.updateTable"),
+ OTEL_PARENT_SPAN_ID);
+ assertTrue(bigquery.delete(updatedTable.getTableId()));
+ }
+
+ @Test
+ public void testOpenTelemetryTracingQuery() throws InterruptedException {
+ Tracer tracer = otel.getTracer("Test Tracer");
+ BigQueryOptions otelOptions =
+ BigQueryOptions.newBuilder()
+ .setEnableOpenTelemetryTracing(true)
+ .setOpenTelemetryTracer(tracer)
+ .build();
+ BigQuery bigquery = otelOptions.getService();
+
+ // Stateless query
+ bigquery.getOptions().setDefaultJobCreationMode(JobCreationMode.JOB_CREATION_OPTIONAL);
+ TableResult tableResult = executeSimpleQuery(bigquery);
+ assertNotNull(tableResult.getQueryId());
+ assertNull(tableResult.getJobId());
+
+ assertNotNull(OTEL_ATTRIBUTES.get("com.google.cloud.bigquery.BigQuery.queryRpc"));
+ assertNotNull(
+ OTEL_ATTRIBUTES.get("com.google.cloud.bigquery.BigQueryRetryHelper.runWithRetries"));
+ assertTrue(OTEL_ATTRIBUTES.containsKey("com.google.cloud.bigquery.BigQuery.query"));
+
+ // Query job
+ String query = "SELECT TimestampField, StringField, BooleanField FROM " + TABLE_ID.getTable();
+ QueryJobConfiguration config =
+ QueryJobConfiguration.newBuilder(query).setDefaultDataset(DatasetId.of(DATASET)).build();
+ Job job = bigquery.create(JobInfo.of(JobId.of(), config));
+
+ TableResult result = job.getQueryResults();
+ assertNotNull(result.getJobId());
+ assertEquals(QUERY_RESULT_SCHEMA, result.getSchema());
+
+ assertNotNull(OTEL_ATTRIBUTES.get("com.google.cloud.bigquery.BigQuery.getQueryResults"));
+ assertNotNull(OTEL_ATTRIBUTES.get("com.google.cloud.bigquery.BigQuery.listTableData"));
+ assertNotNull(OTEL_ATTRIBUTES.get("com.google.cloud.bigquery.BigQuery.createJob"));
+ assertTrue(OTEL_ATTRIBUTES.containsKey("com.google.cloud.bigquery.Job.getQueryResults"));
+ assertTrue(OTEL_ATTRIBUTES.containsKey("com.google.cloud.bigquery.Job.waitForQueryResults"));
+ }
}
diff --git a/pom.xml b/pom.xml
index e281937a3..b265c66e3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
com.google.cloud
google-cloud-bigquery-parent
pom
- 2.51.0
+ 2.52.0
BigQuery Parent
https://github.com/googleapis/java-bigquery
@@ -14,7 +14,7 @@
com.google.cloud
sdk-platform-java-config
- 3.49.0
+ 3.50.0
@@ -71,7 +71,7 @@
com.google.cloud
google-cloud-bigquerystorage-bom
- 3.15.0
+ 3.15.3
pom
import
@@ -79,7 +79,7 @@
com.google.cloud
google-cloud-datacatalog-bom
- 1.69.0
+ 1.72.0
pom
import
@@ -93,7 +93,7 @@
com.google.cloud
google-cloud-bigquery
- 2.51.0
+ 2.52.0
@@ -137,19 +137,19 @@
com.google.cloud
google-cloud-storage
- 2.52.2
+ 2.53.1
test
com.google.cloud
google-cloud-bigqueryconnection
- 2.65.0
+ 2.68.0
test
com.google.api.grpc
proto-google-cloud-bigqueryconnection-v1
- 2.65.0
+ 2.68.0
test
diff --git a/renovate.json b/renovate.json
index 833ec769e..aacfaebeb 100644
--- a/renovate.json
+++ b/renovate.json
@@ -15,9 +15,9 @@
"customManagers": [
{
"customType": "regex",
- "fileMatch": [
- "^.kokoro/continuous/graalvm-native.*.cfg$",
- "^.kokoro/presubmit/graalvm-native.*.cfg$"
+ "managerFilePatterns": [
+ "/^.kokoro/continuous/graalvm-native.*.cfg$/",
+ "/^.kokoro/presubmit/graalvm-native.*.cfg$/"
],
"matchStrings": [
"value: \"gcr.io/cloud-devrel-public-resources/graalvm.*:(?.*?)\""
@@ -27,8 +27,8 @@
},
{
"customType": "regex",
- "fileMatch": [
- "^.github/workflows/unmanaged_dependency_check.yaml$"
+ "managerFilePatterns": [
+ "/^.github/workflows/unmanaged_dependency_check.yaml$/"
],
"matchStrings": [
"uses: googleapis/sdk-platform-java/java-shared-dependencies/unmanaged-dependency-check@google-cloud-shared-dependencies/v(?.+?)\\n"
diff --git a/samples/install-without-bom/pom.xml b/samples/install-without-bom/pom.xml
index 0719a5045..4089821fe 100644
--- a/samples/install-without-bom/pom.xml
+++ b/samples/install-without-bom/pom.xml
@@ -45,7 +45,7 @@
com.google.cloud
google-cloud-bigquery
- 2.50.0
+ 2.51.0
@@ -63,13 +63,13 @@
com.google.cloud
google-cloud-bigtable
- 2.59.0
+ 2.60.0
test
com.google.cloud
google-cloud-bigqueryconnection
- 2.65.0
+ 2.68.0
test
@@ -92,7 +92,7 @@
org.codehaus.mojo
build-helper-maven-plugin
- 3.6.0
+ 3.6.1
add-snippets-source
diff --git a/samples/snapshot/pom.xml b/samples/snapshot/pom.xml
index f81a2b0d9..1a1655234 100644
--- a/samples/snapshot/pom.xml
+++ b/samples/snapshot/pom.xml
@@ -44,7 +44,7 @@
com.google.cloud
google-cloud-bigquery
- 2.51.0
+ 2.52.0
@@ -61,13 +61,13 @@
com.google.cloud
google-cloud-bigtable
- 2.59.0
+ 2.60.0
test
com.google.cloud
google-cloud-bigqueryconnection
- 2.65.0
+ 2.68.0
test
@@ -90,7 +90,7 @@
org.codehaus.mojo
build-helper-maven-plugin
- 3.6.0
+ 3.6.1
add-snippets-source
diff --git a/samples/snippets/pom.xml b/samples/snippets/pom.xml
index 9ddab8dc9..160e38cb0 100644
--- a/samples/snippets/pom.xml
+++ b/samples/snippets/pom.xml
@@ -47,7 +47,7 @@
com.google.cloud
libraries-bom
- 26.43.0
+ 26.62.0
pom
import
@@ -79,13 +79,13 @@
com.google.cloud
google-cloud-bigtable
- 2.59.0
+ 2.60.0
test
com.google.cloud
google-cloud-bigqueryconnection
- 2.65.0
+ 2.68.0
test
diff --git a/samples/snippets/src/main/java/com/example/bigquery/ResourceCleanUp.java b/samples/snippets/src/main/java/com/example/bigquery/ResourceCleanUp.java
index cc294f7a5..a530885cf 100644
--- a/samples/snippets/src/main/java/com/example/bigquery/ResourceCleanUp.java
+++ b/samples/snippets/src/main/java/com/example/bigquery/ResourceCleanUp.java
@@ -54,6 +54,7 @@ public static void main(String[] args) {
|| datasetName.contains("gcloud_test_")
|| datasetName.contains("SHARED_DATASET_TEST_")
|| datasetName.contains("WRITE_STREAM_TEST"))
+ || datasetName.contains("MY_VIEW_DATASET_NAME_TEST_")
&& dataset.getCreationTime() > sixHourAgo) {
System.out.format("\tDeleting Dataset: %s\n", datasetName);
bigquery.delete(
diff --git a/versions.txt b/versions.txt
index b17f78a7b..2b5922874 100644
--- a/versions.txt
+++ b/versions.txt
@@ -1,4 +1,4 @@
# Format:
# module:released-version:current-version
-google-cloud-bigquery:2.51.0:2.51.0
\ No newline at end of file
+google-cloud-bigquery:2.52.0:2.52.0
\ No newline at end of file