Skip to content

feat(jdbc): basic OpenTelemetry tracing integration for BigQuery JDBC Statement#12124

Draft
keshavdandeva wants to merge 4 commits intomainfrom
jdbc/otel-clean-branch
Draft

feat(jdbc): basic OpenTelemetry tracing integration for BigQuery JDBC Statement#12124
keshavdandeva wants to merge 4 commits intomainfrom
jdbc/otel-clean-branch

Conversation

@keshavdandeva
Copy link
Contributor

b/491239772
b/491239773

This PR introduces the foundational OpenTelemetry tracing for the BigQuery JDBC driver. It intercepts standard JDBC executions (queries, updates, batch) to open spans, capture query text, track latencies, and tag exceptions natively, without breaking existing driver flows.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request establishes the foundational OpenTelemetry tracing capabilities within the BigQuery JDBC driver. It allows for detailed observability of database interactions by automatically creating spans for JDBC query, update, and batch operations, enriching them with query details, execution times, and error information. This integration is designed to be non-disruptive, providing valuable insights into driver performance and behavior without altering existing workflows.

Highlights

  • OpenTelemetry Tracing Integration: Integrated foundational OpenTelemetry tracing into the BigQuery JDBC driver to provide observability for database interactions.
  • JDBC Execution Interception: Implemented interception for standard JDBC executions, including queries, updates, and batch operations, to create and manage OpenTelemetry spans.
  • Span Enrichment: Enhanced OpenTelemetry spans with details such as query text, execution latencies, and exception tagging for comprehensive performance monitoring.
  • Configuration Properties: Introduced new connection properties, EnableOpenTelemetry and OpenTelemetryExporter, allowing users to enable and configure tracing behavior.
  • Dependency Management: Updated Maven dependencies to include OpenTelemetry libraries and configured shading exclusions to prevent conflicts with OpenTelemetry API and Context classes.
  • Dedicated OpenTelemetry Utility: Added a new utility class, BigQueryJdbcOpenTelemetry, to centralize the initialization and management of OpenTelemetry instances and tracers.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces foundational OpenTelemetry tracing for the BigQuery JDBC driver's statement execution, which is a valuable addition for observability. The implementation correctly handles context propagation for asynchronous operations like pagination and streaming, and follows standard OpenTelemetry patterns for creating spans and recording exceptions. I have provided a couple of suggestions: one is a minor correction for a copyright year, and the other is a recommendation to unify the exception handling logic within the new tracing code for improved consistency and maintainability. Overall, this is a solid contribution.

@@ -0,0 +1,120 @@
/*
* Copyright 2026 Google LLC
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The copyright year is set to 2026, which is in the future. Please update it to the current year (2024).

Suggested change
* Copyright 2026 Google LLC
* Copyright 2024 Google LLC

Comment on lines +244 to 276
Tracer tracer = getSafeTracer();
Span span = tracer.spanBuilder("BigQueryStatement.executeQuery").startSpan();
try (Scope scope = span.makeCurrent()) {
span.setAttribute("db.statement", sql);
this.otelContext = Context.current();
logQueryExecutionStart(sql);
try {
QueryJobConfiguration jobConfiguration =
setDestinationDatasetAndTableInJobConfig(getJobConfig(sql).build());
runQuery(sql, jobConfiguration);
} catch (InterruptedException ex) {
span.recordException(ex);
span.setStatus(StatusCode.ERROR, ex.getMessage());
throw new BigQueryJdbcException(ex);
} catch (Exception ex) {
span.recordException(ex);
span.setStatus(StatusCode.ERROR, ex.getMessage());
throw ex;
}

if (!isSingularResultSet()) {
throw new BigQueryJdbcException(
"Query returned more than one or didn't return any ResultSet.");
if (!isSingularResultSet()) {
BigQueryJdbcException ex =
new BigQueryJdbcException(
"Query returned more than one or didn't return any ResultSet.");
span.recordException(ex);
span.setStatus(StatusCode.ERROR, ex.getMessage());
throw ex;
}
// This contains all the other assertions spec required on this method
return getCurrentResultSet();
} finally {
span.end();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The exception handling and tracing logic here is a bit verbose and inconsistent with the cleaner pattern used in executeBatch. To improve consistency and maintainability, I suggest refactoring this method to use a single outer try-catch block for recording exceptions on the span. This avoids repetitive exception recording and simplifies the code structure.

The same refactoring should be applied to executeLargeUpdate (lines 280-312) and execute (lines 331-359) for consistency across all traced methods.

    Tracer tracer = getSafeTracer();
    Span span = tracer.spanBuilder("BigQueryStatement.executeQuery").startSpan();
    try (Scope scope = span.makeCurrent()) {
      span.setAttribute("db.statement", sql);
      this.otelContext = Context.current();
      logQueryExecutionStart(sql);
      try {
        QueryJobConfiguration jobConfiguration =
            setDestinationDatasetAndTableInJobConfig(getJobConfig(sql).build());
        runQuery(sql, jobConfiguration);
      } catch (InterruptedException ex) {
        throw new BigQueryJdbcException(ex);
      }

      if (!isSingularResultSet()) {
        throw new BigQueryJdbcException(
            "Query returned more than one or didn't return any ResultSet.");
      }
      // This contains all the other assertions spec required on this method
      return getCurrentResultSet();
    } catch (Exception ex) {
      span.recordException(ex);
      span.setStatus(StatusCode.ERROR, ex.getMessage());
      throw ex;
    } finally {
      span.end();
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant