Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions java-bigquery-jdbc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,12 @@
<artifactId>opentelemetry-sdk-testing</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-trace</artifactId>
<version>2.92.0</version><!-- {x-version-update:google-cloud-trace:current} -->
<scope>test</scope>
</dependency>
</dependencies>

<profiles>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import com.google.cloud.bigquery.storage.v1.BigQueryWriteSettings;
import com.google.cloud.http.HttpTransportOptions;
import com.google.cloud.logging.Logging;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSortedSet;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.baggage.Baggage;
Expand Down Expand Up @@ -438,7 +439,8 @@ String getConnectionUrl() {
return connectionUrl;
}

String getConnectionId() {
@VisibleForTesting
public String getConnectionId() {
Comment thread
keshavdandeva marked this conversation as resolved.
return this.connectionId;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ public class BigQueryJdbcOpenTelemetry {
private static final String OTLP_ENDPOINT_VALUE = "https://telemetry.googleapis.com:443";
private static final String EXPORTER_NONE = "none";
private static final String EXPORTER_OTLP = "otlp";
private static final String OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT =
"otel.span.attribute.value.length.limit";
private static final String OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT =
"otel.attribute.value.length.limit";
private static final String DEFAULT_ATTRIBUTE_LENGTH_LIMIT = "32768";
private static final BigQueryJdbcCustomLogger LOG =
new BigQueryJdbcCustomLogger("BigQueryJdbcOpenTelemetry");

Expand Down Expand Up @@ -290,6 +295,17 @@ public static OpenTelemetry getOpenTelemetry(
props.put(GOOGLE_CLOUD_PROJECT, gcpTelemetryProjectId);
}

// Set safe, generous default limits on attribute value lengths (32KB) to protect
// customers from GCP Cloud Trace 64KB span ingestion failures when logging massive
// exception stack traces or database schema metadata.
// Respect any existing user configuration overrides.
if (!props.containsKey(OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT)) {
props.put(OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT, DEFAULT_ATTRIBUTE_LENGTH_LIMIT);
}
if (!props.containsKey(OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT)) {
props.put(OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT, DEFAULT_ATTRIBUTE_LENGTH_LIMIT);
}

AutoConfiguredOpenTelemetrySdk autoConfigured =
AutoConfiguredOpenTelemetrySdk.builder().addPropertiesSupplier(() -> props).build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -912,8 +912,7 @@ private void processArrowStream(
enqueueError(arrowBatchWrapperBlockingQueue, e);
Thread.currentThread().interrupt();
} catch (Exception e) {
if (e.getCause() instanceof InterruptedException
|| Thread.currentThread().isInterrupted()) {
if (e.getCause() instanceof InterruptedException || Thread.currentThread().isInterrupted()) {
LOG.log(
Level.WARNING,
"\n" + Thread.currentThread().getName() + " Interrupted @ arrowStreamProcessor",
Expand Down Expand Up @@ -1684,8 +1683,7 @@ private void parseAndPopulateRpcData(
}

} catch (Exception ex) {
if (ex.getCause() instanceof InterruptedException
|| Thread.currentThread().isInterrupted()) {
if (ex.getCause() instanceof InterruptedException || Thread.currentThread().isInterrupted()) {
LOG.log(
Level.WARNING,
"\n" + Thread.currentThread().getName() + " Interrupted @ populateBufferAsync",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@
public class OpenTelemetryJulHandler extends Handler {
private static final Pattern UNSAFE_LOG_CHARACTERS = Pattern.compile("[^a-zA-Z0-9./_-]");

public OpenTelemetryJulHandler() {}
public OpenTelemetryJulHandler() {
setLevel(Level.ALL);
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.

Is this intentional? I don't think we should alter log level from non-test code

Copy link
Copy Markdown
Contributor Author

@keshavdandeva keshavdandeva May 22, 2026

Choose a reason for hiding this comment

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

Yeah, so this does not modify or alter any global logging levels. By default, Java Handler thresholds default to INFO. Without setLevel(Level.ALL), our custom handler would silently drop all FINE query logs before exporting them, even if the user explicitly enabled lower log level on their connection.

Overriding it here just ensures log filtering is done strictly at the Logger level and not here

}

@Override
public void publish(LogRecord record) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,30 @@
import com.google.cloud.bigquery.exception.BigQueryJdbcException;
import com.google.cloud.bigquery.storage.v1.BigQueryReadClient;
import com.google.cloud.bigquery.storage.v1.BigQueryWriteClient;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension;
import io.opentelemetry.sdk.trace.data.SpanData;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.List;
import java.util.Optional;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

public class BigQueryConnectionTest extends BigQueryJdbcLoggingBaseTest {

@RegisterExtension
static final OpenTelemetryExtension otelTesting = OpenTelemetryExtension.create();

private static final String DEFAULT_VERSION = "0.0.0";
private static final String DEFAULT_JDBC_TOKEN_VALUE = "Google-BigQuery-JDBC-Driver";
private static final String BASE_URL =
Expand Down Expand Up @@ -461,6 +470,27 @@ public void testIsReadOnlyTokenProvided(String readonlyProp, boolean expectedIsR
}
}

@Test
public void testConnect_withCustomOpenTelemetry_usesCustomInstance() throws Exception {
DataSource ds = DataSource.fromUrl(BASE_URL);
ds.setCustomOpenTelemetry(otelTesting.getOpenTelemetry());

try (BigQueryConnection connection = new BigQueryConnection(BASE_URL, ds)) {
assertNotNull(connection);
assertFalse(connection.isClosed());

Tracer tracer = connection.getTracer();
assertNotNull(tracer);

Span span = tracer.spanBuilder("custom-otel-span").startSpan();
span.end();

List<SpanData> spans = otelTesting.getSpans();
assertEquals(1, spans.size());
assertEquals("custom-otel-span", spans.get(0).getName());
}
}

@Test
public void testConnectionPropertiesLoggingAndMasking() throws IOException, SQLException {
Logger rootLogger = BigQueryJdbcRootLogger.getRootLogger();
Expand Down
Loading
Loading