Skip to content

feat(bigquery-jdbc): add opt-out controls - #14199

Open
Neenu1995 wants to merge 6 commits into
jdbc-telemetry-featurefrom
jdbc-telemetry-pr8-impl
Open

feat(bigquery-jdbc): add opt-out controls#14199
Neenu1995 wants to merge 6 commits into
jdbc-telemetry-featurefrom
jdbc-telemetry-pr8-impl

Conversation

@Neenu1995

@Neenu1995 Neenu1995 commented Aug 27, 2026

Copy link
Copy Markdown
Contributor
  • Telemetry Configuration & Resolution:

    • Set default Clearcut log source to 3071 (DEFAULT_LOG_SOURCE).
    • Implemented hierarchical property resolution with precedence: JVM System Properties > Environment Variables > Connection Properties.
    • Added support for telemetry opt-out flags (EnableDiagnosticTelemetry / enableDiagnosticTelemetry) and tuning parameters (TelemetryUploadInterval, TelemetryBatchSize).
  • Telemetry Manager & Recording Engine:

    • Implemented thread-safe singleton lifecycle with permanent global disable safeguards when opted out.
    • Added enum converters for StatementType (via Protobuf reflection) and AuthenticationType (mapping JDBC OAuth types).
    • Added latency histogram bucketing (toDurationBucketMs) for query execution durations.
    • Implemented metric recording APIs (recordConnectionAttempt, recordStatementExecution, recordFeatureUsage) with runSafely exception protection.
  • Protobuf Schema Definitions:

    • Updated telemetry.proto to match internal requirements.

@Neenu1995
Neenu1995 requested review from a team as code owners August 27, 2026 15:31

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

Copy link
Copy Markdown
Contributor

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 in-memory aggregation of telemetry events (connection attempts, statement executions, error metrics, and feature usages) in TelemetryBatcher before flushing, along with support for dynamically enabling or disabling telemetry via connection properties or environment variables. The feedback highlights a critical issue with configuring the global TelemetryManager singleton using connection-specific properties, which ignores settings for subsequent connections. Additionally, the reviewer recommends replacing a large switch statement in toStatementType with dynamic enum mapping, copying explicit_bounds when merging duration histograms to prevent invalid payloads, and explicitly handling positive values for the GOOGLE_CLOUD_TELEMETRY_ENABLED environment variable.

// 1. Connection Properties (lowest precedence)
if (connectionProperties != null) {
String propValue = connectionProperties.getProperty("EnableDiagnosticTelemetry");
if (propValue == null) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This if assigns exact same value

propValue = connectionProperties.getProperty("enableDiagnosticTelemetry");
}
if (propValue != null) {
if ("0".equals(propValue) || "false".equalsIgnoreCase(propValue)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We have BigQueryJdbcUrlUtility.convertIntToBoolean(), can we reuse it? (or move it to some utils class to use in both places)

}
}

String sysInterval = System.getProperty("GOOGLE_CLOUD_TELEMETRY_UPLOAD_INTERVAL");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: we have 2 types here, int & bool. I'd suggest moving it to helper methods to have smth like this

this.uploadIntervalMs = parseInt(System.getProperty("GOOGLE_CLOUD_TELEMETRY_UPLOAD_INTERVAL"), this.UploadIntervalMs);

(Second param for default value)

if (localRef == null) {
TelemetryConfiguration config = TelemetryConfiguration.builder().build();
TelemetryConfiguration config =
TelemetryConfiguration.builder().resolveProperties(properties).build();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

properties is always null at this point

return AuthenticationType.AUTHENTICATION_TYPE_SERVICE_ACCOUNT;
case 1:
return AuthenticationType.AUTHENTICATION_TYPE_USER_AUTHENTICATION;
case 2:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Where is int coming from? It doesn't match OAuthType connection properties

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.

2 participants