Skip to content

chore(bqjdbc): refactor log levels#13166

Open
Neenu1995 wants to merge 5 commits into
mainfrom
ns/refactor-logs
Open

chore(bqjdbc): refactor log levels#13166
Neenu1995 wants to merge 5 commits into
mainfrom
ns/refactor-logs

Conversation

@Neenu1995
Copy link
Copy Markdown
Contributor

@Neenu1995 Neenu1995 commented May 11, 2026

b/505825091

- Causal Exception Unwrapping: Updated async stream readers (BigQueryStatement) to check e.getCause(), properly categorizing wrapped network interrupts during query shutdown to prevent false severe error logs.
- POJO Log Stripping: Removed repetitive, low-level diagnostic logs from intermediate state wrappers (BigQueryCallableStatement) to improve per-connection file readability.
- Standardized Level Routing: All Non-ResultSet trace logs now logs at Level.FINER, cleanly separating infrastructure execution boundaries from raw data iteration outputs (Level.FINEST).

@Neenu1995 Neenu1995 requested review from a team as code owners May 11, 2026 20:21
Copy link
Copy Markdown
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 refactors the logging infrastructure of the BigQuery JDBC driver to improve performance and consistency. It removes numerous manual method entry/exit logs across the codebase, replacing them with a centralized logging mechanism within BigQueryJdbcContextProxy using dynamic proxies. The BigQueryJdbcResultSetLogger and BigQueryJdbcRootLogger were updated to better handle LogRecord objects and thread IDs. Feedback highlights potential reliability risks in the proxy's logging logic where calling toString() on arguments or results could trigger exceptions, and notes that setting thread IDs manually in the thread factory is misleading and redundant.

@Neenu1995 Neenu1995 marked this pull request as draft May 11, 2026 20:32
@Neenu1995
Copy link
Copy Markdown
Contributor Author

/gemini review

Copy link
Copy Markdown
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 refactors the logging infrastructure across the BigQuery JDBC driver, primarily shifting method entry/exit tracing from Level.FINEST to Level.FINER and introducing a more structured LogRecord approach to avoid expensive stack trace parsing. It also enhances the BigQueryJdbcContextProxy to automatically log method calls and results. Feedback focuses on a security concern regarding the potential for sensitive data exposure (CWE-532) when logging all method arguments and return values at the FINER level, as well as the performance implications of wrapping high-frequency JDBC operations.

@Neenu1995 Neenu1995 marked this pull request as ready for review May 12, 2026 19:29
}

void append(JsonArray data, long offset) throws DescriptorValidationException, IOException {
if (LOG.isLoggable(Level.FINER)) {
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: no need to check this, it constructs MsgSupplier object under the cover, so no real string.format

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I will keep this because appends is a hotpath when inserting with BulkInsertWriter. The check helps eliminate the hidden cost of varargs allocation, auto-boxing and lambda creation.

}

public void onFailure(Throwable throwable) {
parent.LOG.warning(
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.

Why using parent.LOG there and LOG in other places?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The AppendCompleteCallback class is static and the LOG is not. Hence the parent.LOG reference.

"\n" + Thread.currentThread().getName() + " Error @ arrowStreamProcessor",
e);
enqueueError(arrowBatchWrapperBlockingQueue, e);
if (e.getCause() instanceof InterruptedException
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.

Use a separate catch (InterruptedException) {} instead

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This was added to distinguish between actual errors/interruption to the worker thread operation vs shutdown signal send by the jdbc driver. Since standard Java Iterator and stream interfaces do not allow checked exceptions in their signatures, any underlying InterruptedException is typically wrapped inside an unchecked exception (such as RuntimeException, UncheckedExecutionException, or GAX's ApiException). Catching InterruptedException directly will miss these wrapped occurrences.

"\n" + Thread.currentThread().getName() + " Error @ populateBufferAsync",
ex);
enqueueBufferError(bigQueryFieldValueListWrapperBlockingQueue, ex);
if (ex.getCause() instanceof InterruptedException
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.

same, separate catch clause

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Same as above.

public void finestTrace(String methodName, String msg) {
if (isLoggable(Level.FINEST)) {
logp(Level.FINEST, targetClassName, methodName, msg);
LogRecord record = new LogRecord(Level.FINEST, msg);
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.

Should this be done as a part of log(record) ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The standard log(LogRecord record) method signature in Java's java.util.logging.Logger framework requires accepting an already-constructed LogRecord object as its argument. So I moved the LogRecord creation to private helper methods instead.


Object result = method.invoke(target, args);

// Suppress exit logging for Connection.close() since its file handler is unmounted during
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.

Do we need this? I'd guess if file handler is removed at this point, nothing will be logged either way

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The file handler for the connection is removed at this point, so without the check this particular close log gets logged to the global file handler.

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