Skip to content

Commit 2801fbd

Browse files
feat(bigquery-jdbc): add otel trace and span IDs to local logs (#13935)
b/538631816 This PR integrates OpenTelemetry tracing context into the JDBC driver's local file logging system, bringing it to parity with the existing Google Cloud Logging export integration. **Key Changes:** * **`BigQueryJdbcRootLogger.java`**: Updated the root formatter to extract the active `TraceId` and `SpanId` from the current OpenTelemetry thread context. When a valid trace is active, local logs will now automatically include a `[trace_id=... span_id=...]` block. * **`BigQueryJdbcRootLoggerTest.java`**: Added `testFormatterWithOpenTelemetrySpan` to verify the formatter correctly extracts and formats IDs when a span is active.
1 parent 0faedf3 commit 2801fbd

2 files changed

Lines changed: 44 additions & 7 deletions

File tree

‎java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcRootLogger.java‎

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
package com.google.cloud.bigquery.jdbc;
1818

1919
import com.google.common.base.Strings;
20+
import io.opentelemetry.api.trace.Span;
21+
import io.opentelemetry.api.trace.SpanContext;
22+
import io.opentelemetry.context.Context;
2023
import java.io.IOException;
2124
import java.lang.management.ManagementFactory;
2225
import java.time.Instant;
@@ -84,6 +87,18 @@ public static Formatter getFormatter() {
8487
return new Formatter() {
8588
private static final int MAX_THREAD_NAME_LENGTH = 15;
8689

90+
private void appendTraceBlock(StringBuilder sb) {
91+
SpanContext spanContext = Span.fromContext(Context.current()).getSpanContext();
92+
if (!spanContext.isValid()) {
93+
return;
94+
}
95+
sb.append("[trace_id=")
96+
.append(spanContext.getTraceId())
97+
.append(" span_id=")
98+
.append(spanContext.getSpanId())
99+
.append("] ");
100+
}
101+
87102
@Override
88103
public String format(LogRecord record) {
89104
String date = DATE_FORMATTER.format(Instant.ofEpochMilli(record.getMillis()));
@@ -114,14 +129,12 @@ public String format(LogRecord record) {
114129
: record.getLoggerName();
115130
String sourceMethodName = record.getSourceMethodName();
116131

117-
// Expected log format: yyyy-MM-dd HH:mm:ss.SSS [CONNECTION_ID] LEVEL PID --- [THREAD] CLASS
118-
// METHOD: MESSAGE
132+
// Expected log format: yyyy-MM-dd HH:mm:ss.SSS [CONNECTION_ID] [trace_id=<trace_id>
133+
// span_id=<span_id>] LEVEL PID --- [THREAD] CLASS METHOD: MESSAGE
119134
StringBuilder sb = new StringBuilder(256);
120-
sb.append(date)
121-
.append(" [")
122-
.append(connStr)
123-
.append("] ")
124-
.append(Strings.padEnd(record.getLevel().getName(), 7, ' '))
135+
sb.append(date).append(" [").append(connStr).append("] ");
136+
appendTraceBlock(sb);
137+
sb.append(Strings.padEnd(record.getLevel().getName(), 7, ' '))
125138
.append(" ")
126139
.append(PROCESS_ID)
127140
.append(" --- [")

‎java-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcRootLoggerTest.java‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@
2020
import static org.junit.jupiter.api.Assertions.assertNotNull;
2121
import static org.junit.jupiter.api.Assertions.assertTrue;
2222

23+
import io.opentelemetry.api.trace.Span;
24+
import io.opentelemetry.api.trace.SpanContext;
25+
import io.opentelemetry.api.trace.TraceFlags;
26+
import io.opentelemetry.api.trace.TraceState;
27+
import io.opentelemetry.context.Scope;
2328
import java.util.logging.Formatter;
2429
import java.util.logging.Level;
2530
import java.util.logging.LogRecord;
@@ -71,4 +76,23 @@ public void testGetThreadNameNotFound() {
7176
String name = BigQueryJdbcRootLogger.getThreadName(-1);
7277
assertEquals("", name);
7378
}
79+
80+
@Test
81+
public void testFormatterWithOpenTelemetrySpan() {
82+
SpanContext spanContext =
83+
SpanContext.create(
84+
"00000000000000000000000000000001",
85+
"0000000000000002",
86+
TraceFlags.getDefault(),
87+
TraceState.getDefault());
88+
Span span = Span.wrap(spanContext);
89+
try (Scope scope = span.makeCurrent()) {
90+
Formatter formatter = BigQueryJdbcRootLogger.getFormatter();
91+
LogRecord record = new LogRecord(Level.INFO, "Test message with span");
92+
String formatted = formatter.format(record);
93+
assertTrue(
94+
formatted.contains(
95+
"[trace_id=00000000000000000000000000000001 span_id=0000000000000002] "));
96+
}
97+
}
7498
}

0 commit comments

Comments
 (0)