From 5e7838b12c1108b9b509c943d6b039500d2540c8 Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Thu, 4 Jun 2026 14:15:41 -0400 Subject: [PATCH 1/3] fix(bigquery-jdbc): lazy caller inference and zero-overhead coercion logging --- .../jdbc/BigQueryJdbcCustomLogger.java | 87 +++++++++++++++---- .../bigquery/jdbc/BigQueryTypeCoercer.java | 9 +- .../jdbc/BigQueryJdbcCustomLoggerTest.java | 25 ++++++ 3 files changed, 101 insertions(+), 20 deletions(-) diff --git a/java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcCustomLogger.java b/java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcCustomLogger.java index 75787850cbd8..61b04bf882e2 100644 --- a/java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcCustomLogger.java +++ b/java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcCustomLogger.java @@ -42,28 +42,83 @@ private void logWithCaller(Level level, Throwable thrown, Supplier msgSu return; } - StackTraceElement[] stackTrace = new Throwable().getStackTrace(); - String sourceClass = "unknown"; - String sourceMethod = "unknown"; - - for (StackTraceElement element : stackTrace) { - String className = element.getClassName(); - if (!className.equals(BigQueryJdbcCustomLogger.class.getName()) - && !className.startsWith("com.google.cloud.bigquery.exception.")) { + LogRecord record = new BigQueryJdbcLogRecord(level, msgSupplier.get()); + record.setThrown(thrown); + log(record); + } + + static class BigQueryJdbcLogRecord extends LogRecord { + private boolean callerInferred = false; + private String sourceClass; + private String sourceMethod; + + public BigQueryJdbcLogRecord(Level level, String msg) { + super(level, msg); + } + + boolean isCallerInferred() { + return callerInferred; + } + + @Override + public String getSourceClassName() { + inferCaller(); + return sourceClass; + } + + @Override + public void setSourceClassName(String sourceClassName) { + super.setSourceClassName(sourceClassName); + this.sourceClass = sourceClassName; + this.callerInferred = true; + } + + @Override + public String getSourceMethodName() { + inferCaller(); + return sourceMethod; + } + + @Override + public void setSourceMethodName(String sourceMethodName) { + super.setSourceMethodName(sourceMethodName); + this.sourceMethod = sourceMethodName; + this.callerInferred = true; + } + + private synchronized void inferCaller() { + if (callerInferred) { + return; + } + callerInferred = true; + StackTraceElement[] stackTrace = new Throwable().getStackTrace(); + sourceClass = "unknown"; + sourceMethod = "unknown"; + + for (StackTraceElement element : stackTrace) { + String className = element.getClassName(); + if (shouldSkipClass(className)) { + continue; + } sourceClass = className; sourceMethod = element.getMethodName(); break; } + super.setSourceClassName(sourceClass); + super.setSourceMethodName(sourceMethod); } - if (thrown == null) { - logp(level, sourceClass, sourceMethod, msgSupplier); - } else { - LogRecord record = new LogRecord(level, msgSupplier.get()); - record.setSourceClassName(sourceClass); - record.setSourceMethodName(sourceMethod); - record.setThrown(thrown); - log(record); + private static boolean shouldSkipClass(String className) { + return className.equals("com.google.cloud.bigquery.jdbc.BigQueryJdbcCustomLogger") + || className.equals("com.google.cloud.bigquery.jdbc.BigQueryJdbcResultSetLogger") + || className.startsWith("com.google.cloud.bigquery.jdbc.BigQueryJdbcRootLogger") + || className.equals(BigQueryJdbcLogRecord.class.getName()) + || className.startsWith("java.util.logging.") + || className.startsWith("sun.util.logging.") + || className.startsWith("com.google.cloud.bigquery.exception.") + || className.startsWith("org.slf4j.bridge.") + || className.startsWith("org.apache.logging.log4j.jul.") + || className.startsWith("org.apache.commons.logging."); } } diff --git a/java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryTypeCoercer.java b/java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryTypeCoercer.java index af3f2fb28452..9f968fd4b8d0 100644 --- a/java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryTypeCoercer.java +++ b/java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryTypeCoercer.java @@ -67,8 +67,8 @@ */ @InternalApi class BigQueryTypeCoercer { - private static final BigQueryJdbcCustomLogger LOG = - new BigQueryJdbcCustomLogger(BigQueryTypeCoercer.class.getName()); + private static final BigQueryJdbcResultSetLogger LOG = + BigQueryJdbcResultSetLogger.getLogger(BigQueryTypeCoercer.class); /** A {@link BigQueryTypeCoercer} instance with all the inbuilt {@link BigQueryCoercion}s */ static BigQueryTypeCoercer INSTANCE; @@ -108,8 +108,9 @@ T coerceTo(Class targetClass, Object value, BigQueryJdbcResultSetLogger l return targetClass.cast(value); } BigQueryCoercion coercion = findCoercion(sourceClass, targetClass); - BigQueryJdbcCustomLogger effectiveLog = log != null ? log : LOG; - effectiveLog.finest("%s coercion for %s", coercion, value); + BigQueryJdbcResultSetLogger effectiveLog = log != null ? log : LOG; + effectiveLog.finestTrace( + "coerceTo", () -> String.format("%s coercion for %s", coercion, value)); // Value is null case & no explicit coercion if (sourceClass == Void.class && coercion == null) { return null; diff --git a/java-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcCustomLoggerTest.java b/java-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcCustomLoggerTest.java index a96b08ed1485..223007e7b6fb 100644 --- a/java-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcCustomLoggerTest.java +++ b/java-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcCustomLoggerTest.java @@ -93,6 +93,31 @@ public void testLogWithCallerInference() { assertEquals(BigQueryJdbcCustomLoggerTest.class.getName(), record.getSourceClassName()); } + @Test + public void testLazyCallerInference() { + logger.fine("Lazy log message"); + + List records = testHandler.getRecords(); + assertEquals(1, records.size()); + LogRecord record = records.get(0); + + assertTrue(record instanceof BigQueryJdbcCustomLogger.BigQueryJdbcLogRecord); + BigQueryJdbcCustomLogger.BigQueryJdbcLogRecord lazyRecord = + (BigQueryJdbcCustomLogger.BigQueryJdbcLogRecord) record; + + // Verify stack walk has not been executed yet + assertTrue(!lazyRecord.isCallerInferred()); + + // Trigger stack walk + String className = record.getSourceClassName(); + String methodName = record.getSourceMethodName(); + + // Verify stack walk has executed and correct caller was inferred + assertTrue(lazyRecord.isCallerInferred()); + assertEquals(BigQueryJdbcCustomLoggerTest.class.getName(), className); + assertEquals("testLazyCallerInference", methodName); + } + @Test public void testHotPathLoggerLogToDefaultWhenContextIsNull() { BigQueryJdbcCustomLogger hotpathLogger = From 31e02b005ee5d289ff1f209e6756d03556ef86a9 Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Thu, 4 Jun 2026 14:22:22 -0400 Subject: [PATCH 2/3] synchronize getters and setters --- .../cloud/bigquery/jdbc/BigQueryJdbcCustomLogger.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcCustomLogger.java b/java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcCustomLogger.java index 61b04bf882e2..74942b909331 100644 --- a/java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcCustomLogger.java +++ b/java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcCustomLogger.java @@ -56,31 +56,31 @@ public BigQueryJdbcLogRecord(Level level, String msg) { super(level, msg); } - boolean isCallerInferred() { + synchronized boolean isCallerInferred() { return callerInferred; } @Override - public String getSourceClassName() { + public synchronized String getSourceClassName() { inferCaller(); return sourceClass; } @Override - public void setSourceClassName(String sourceClassName) { + public synchronized void setSourceClassName(String sourceClassName) { super.setSourceClassName(sourceClassName); this.sourceClass = sourceClassName; this.callerInferred = true; } @Override - public String getSourceMethodName() { + public synchronized String getSourceMethodName() { inferCaller(); return sourceMethod; } @Override - public void setSourceMethodName(String sourceMethodName) { + public synchronized void setSourceMethodName(String sourceMethodName) { super.setSourceMethodName(sourceMethodName); this.sourceMethod = sourceMethodName; this.callerInferred = true; From 81c8a53f97513d78e205207b5c84cdfac8481625 Mon Sep 17 00:00:00 2001 From: Neenu1995 Date: Fri, 5 Jun 2026 14:43:31 -0400 Subject: [PATCH 3/3] whitelist instead of blacklist --- .../jdbc/BigQueryJdbcCustomLogger.java | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcCustomLogger.java b/java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcCustomLogger.java index 74942b909331..e1edd575b322 100644 --- a/java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcCustomLogger.java +++ b/java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcCustomLogger.java @@ -97,28 +97,26 @@ private synchronized void inferCaller() { for (StackTraceElement element : stackTrace) { String className = element.getClassName(); - if (shouldSkipClass(className)) { - continue; + if (isDriverClass(className) && !isLoggerClass(className)) { + sourceClass = className; + sourceMethod = element.getMethodName(); + break; } - sourceClass = className; - sourceMethod = element.getMethodName(); - break; } super.setSourceClassName(sourceClass); super.setSourceMethodName(sourceMethod); } - private static boolean shouldSkipClass(String className) { + private static boolean isDriverClass(String className) { + return className.startsWith("com.google.cloud.bigquery.jdbc.") + || className.startsWith("com.google.cloud.bigquery.exception."); + } + + private static boolean isLoggerClass(String className) { return className.equals("com.google.cloud.bigquery.jdbc.BigQueryJdbcCustomLogger") || className.equals("com.google.cloud.bigquery.jdbc.BigQueryJdbcResultSetLogger") || className.startsWith("com.google.cloud.bigquery.jdbc.BigQueryJdbcRootLogger") - || className.equals(BigQueryJdbcLogRecord.class.getName()) - || className.startsWith("java.util.logging.") - || className.startsWith("sun.util.logging.") - || className.startsWith("com.google.cloud.bigquery.exception.") - || className.startsWith("org.slf4j.bridge.") - || className.startsWith("org.apache.logging.log4j.jul.") - || className.startsWith("org.apache.commons.logging."); + || className.equals(BigQueryJdbcLogRecord.class.getName()); } }