This is an automated email from the ASF dual-hosted git repository. ramanathan1504 pushed a commit to branch fix-trace-metadata-1976 in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit e75233d92585caeb77cbf6d5a75a242a1e968daa Author: Ramanathan <[email protected]> AuthorDate: Sat Jul 4 18:52:36 2026 +0530 Refactor tracing metadata documentation and improve code comments for clarity --- .../logging/log4j/spi/TraceContextProvider.java | 15 ++++++++++-- .../log4j/core/async/RingBufferLogEventTest.java | 8 +++---- .../log4j/core/impl/MutableLogEventTest.java | 6 ++--- .../log4j/core/impl/TestTraceContextProvider.java | 4 ---- .../core/impl/TraceContextIntegrationTest.java | 8 +++---- .../org/apache/logging/log4j/core/LogEvent.java | 27 +++++++++++++++++++--- .../log4j/core/async/RingBufferLogEvent.java | 6 ++--- .../log4j/core/pattern/SpanIdPatternConverter.java | 3 --- .../core/pattern/TraceFlagsPatternConverter.java | 3 --- .../core/pattern/TraceIdPatternConverter.java | 3 --- .../log4j/perf/jmh/AsyncTraceContextBenchmark.java | 6 ++--- 11 files changed, 53 insertions(+), 36 deletions(-) diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/TraceContextProvider.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/TraceContextProvider.java index 3c1ef5b8c1..de2ffbeb8b 100644 --- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/TraceContextProvider.java +++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/TraceContextProvider.java @@ -17,8 +17,19 @@ package org.apache.logging.log4j.spi; /** - * Service Provider Interface (SPI) for retrieving standard W3C tracing metadata from the active context. - * Placed in the API module to allow third-party providers to compile against it with minimal dependencies. + * Service Provider Interface (SPI) for retrieving distributed tracing metadata (such as W3C Trace Context) + * from the active execution context. + * <p> + * Implementing this SPI allows tracing frameworks (e.g., OpenTelemetry, Micrometer, Zipkin) to pass native + * trace identifiers directly to Log4j events. This completely bypasses the {@link org.apache.logging.log4j.ThreadContext} + * map, eliminating map-cloning and garbage collection overhead during asynchronous logging. + * </p> + * <p> + * Log4j locates implementations of this interface using the standard Java {@link java.util.ServiceLoader} mechanism. + * To register a custom provider, create a plain-text file named + * {@code org.apache.logging.log4j.spi.TraceContextProvider} in the {@code META-INF/services/} directory + * containing the fully qualified class name of the implementation. + * </p> * * @since 2.27.0 */ diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java index 26044686fe..20b2a7ec44 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java @@ -476,12 +476,12 @@ class RingBufferLogEventTest { void testRingBufferLogEventTracingFieldsAndClear() { final RingBufferLogEvent event = new RingBufferLogEvent(); - // 1. Check initial state + // Check initial state assertThat(event.getTraceId()).isNull(); assertThat(event.getSpanId()).isNull(); assertThat(event.getTraceFlags()).isNull(); - // 2. Initialize with trace fields inside 18-parameter setValues + // Initialize with trace fields inside 18-parameter setValues event.setValues( null, "TestLogger", @@ -502,12 +502,12 @@ class RingBufferLogEventTest { "span-id-ringbuffer", "01"); - // 3. Assert values are retrievable + // Assert values are retrievable assertThat(event.getTraceId()).isEqualTo("trace-id-ringbuffer"); assertThat(event.getSpanId()).isEqualTo("span-id-ringbuffer"); assertThat(event.getTraceFlags()).isEqualTo("01"); - // 4. Verify clearing wipes tracing state to avoid leakage on slot reuse + // Verify clearing wipes tracing state to avoid leakage on slot reuse event.clear(); assertNull(event.getTraceId()); assertNull(event.getSpanId()); diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java index 87c032fa71..459c84fbaa 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java @@ -378,18 +378,18 @@ class MutableLogEventTest { final MutableLogEvent mutableEvent = new MutableLogEvent(); - // 1. Initially empty + // Initially empty assertThat(mutableEvent.getTraceId()).isNull(); assertThat(mutableEvent.getSpanId()).isNull(); assertThat(mutableEvent.getTraceFlags()).isNull(); - // 2. Verify propagation via initFrom + // Verify propagation via initFrom mutableEvent.initFrom(sourceEvent); assertThat(mutableEvent.getTraceId()).isEqualTo("trace-xyz-123"); assertThat(mutableEvent.getSpanId()).isEqualTo("span-abc-456"); assertThat(mutableEvent.getTraceFlags()).isEqualTo("01"); - // 3. Verify clearing removes tracking state to prevent leakage on pool reuse + // Verify clearing removes tracking state to prevent leakage on pool reuse mutableEvent.clear(); assertThat(mutableEvent.getTraceId()).isNull(); assertThat(mutableEvent.getSpanId()).isNull(); diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/TestTraceContextProvider.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/TestTraceContextProvider.java index 8bb0248e1f..94a0d009ed 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/TestTraceContextProvider.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/TestTraceContextProvider.java @@ -18,10 +18,6 @@ package org.apache.logging.log4j.core.impl; import org.apache.logging.log4j.spi.TraceContextProvider; -/** - * A test-only TraceContextProvider designed to simulate thread-local trace contexts. - * Mimics active span context lookups in systems like OpenTelemetry or Micrometer. - */ public class TestTraceContextProvider implements TraceContextProvider { private static final ThreadLocal<String> TRACE_ID = new ThreadLocal<>(); diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/TraceContextIntegrationTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/TraceContextIntegrationTest.java index 48aebe6026..ffa10ab9ff 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/TraceContextIntegrationTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/TraceContextIntegrationTest.java @@ -152,26 +152,26 @@ public class TraceContextIntegrationTest { @Test public void testTracePatternConverters() { - // 1. Setup an event with trace data + // Setup an event with trace data final LogEvent event = Log4jLogEvent.newBuilder() .setTraceId("test-trace-123") .setSpanId("test-span-456") .setTraceFlags("01") .build(); - // 2. Test Trace ID Converter + // Test Trace ID Converter final StringBuilder traceSb = new StringBuilder(); org.apache.logging.log4j.core.pattern.TraceIdPatternConverter.newInstance(null) .format(event, traceSb); assertThat(traceSb.toString()).isEqualTo("test-trace-123"); - // 3. Test Span ID Converter + // Test Span ID Converter final StringBuilder spanSb = new StringBuilder(); org.apache.logging.log4j.core.pattern.SpanIdPatternConverter.newInstance(null) .format(event, spanSb); assertThat(spanSb.toString()).isEqualTo("test-span-456"); - // 4. Test Trace Flags Converter + // Test Trace Flags Converter final StringBuilder flagsSb = new StringBuilder(); org.apache.logging.log4j.core.pattern.TraceFlagsPatternConverter.newInstance(null) .format(event, flagsSb); diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/LogEvent.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/LogEvent.java index 50d947ed34..f4cc136ff3 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/LogEvent.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/LogEvent.java @@ -242,21 +242,42 @@ public interface LogEvent extends Serializable { */ long getNanoTime(); /** - * Returns the standard Trace ID. + * Returns the distributed tracing Trace ID from the active context (e.g., W3C Trace Context). + * <p> + * A Trace ID is typically a 32-character lowercase hexadecimal string representing the + * entire trace forest. The default implementation returns {@code null}. + * </p> + * + * @return the Trace ID, or {@code null} if no tracing context is active or supported. + * @since 2.27.0 */ default String getTraceId() { return null; } /** - * Returns the standard Span ID. + * Returns the distributed tracing Span ID from the active context (e.g., W3C Trace Context). + * <p> + * A Span ID is typically a 16-character lowercase hexadecimal string representing a + * single operation within a trace. The default implementation returns {@code null}. + * </p> + * + * @return the Span ID, or {@code null} if no tracing context is active or supported. + * @since 2.27.0 */ default String getSpanId() { return null; } /** - * Returns the standard Trace Flags. + * Returns the distributed tracing Trace Flags from the active context (e.g., W3C Trace Context). + * <p> + * Trace Flags are typically a 2-character lowercase hexadecimal string representing + * tracing options (such as whether the trace is sampled). The default implementation returns {@code null}. + * </p> + * + * @return the Trace Flags, or {@code null} if no tracing context is active or supported. + * @since 2.27.0 */ default String getTraceFlags() { return null; diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java index 8a46be100e..b64a32e118 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/RingBufferLogEvent.java @@ -169,9 +169,9 @@ public class RingBufferLogEvent implements LogEvent, ReusableMessage, CharSequen aLocation, clock, nanoClock, - null, // traceId default - null, // spanId default - null // traceFlags default + null, // traceId + null, // spanId + null // traceFlags ); } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/SpanIdPatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/SpanIdPatternConverter.java index 7dd7c3217f..94544ca945 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/SpanIdPatternConverter.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/SpanIdPatternConverter.java @@ -19,9 +19,6 @@ package org.apache.logging.log4j.core.pattern; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.config.plugins.Plugin; -/** - * converter to format W3C standard span ID natively. - */ @Plugin(name = "SpanIdPatternConverter", category = PatternConverter.CATEGORY) @ConverterKeys({"spanId"}) public final class SpanIdPatternConverter extends LogEventPatternConverter { diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/TraceFlagsPatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/TraceFlagsPatternConverter.java index 3970d00463..a27502abcf 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/TraceFlagsPatternConverter.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/TraceFlagsPatternConverter.java @@ -19,9 +19,6 @@ package org.apache.logging.log4j.core.pattern; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.config.plugins.Plugin; -/** - * Built-in converter to format W3C standard trace flags natively. - */ @Plugin(name = "TraceFlagsPatternConverter", category = PatternConverter.CATEGORY) @ConverterKeys({"traceFlags"}) public final class TraceFlagsPatternConverter extends LogEventPatternConverter { diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/TraceIdPatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/TraceIdPatternConverter.java index c7e84f2252..ab1ed09acc 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/TraceIdPatternConverter.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/TraceIdPatternConverter.java @@ -19,9 +19,6 @@ package org.apache.logging.log4j.core.pattern; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.config.plugins.Plugin; -/** - * Built-in converter to format W3C standard trace ID natively. - */ @Plugin(name = "TraceIdPatternConverter", category = PatternConverter.CATEGORY) @ConverterKeys({"traceId"}) public final class TraceIdPatternConverter extends LogEventPatternConverter { diff --git a/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/AsyncTraceContextBenchmark.java b/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/AsyncTraceContextBenchmark.java index 6483b59e0a..b1ecf5da6c 100644 --- a/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/AsyncTraceContextBenchmark.java +++ b/log4j-perf-test/src/main/java/org/apache/logging/log4j/perf/jmh/AsyncTraceContextBenchmark.java @@ -52,10 +52,8 @@ public class AsyncTraceContextBenchmark { message = new SimpleMessage("Test performance message"); } - /** - * Reusable thread-local state to match how Disruptor events and translators - * are held per-thread in production. - */ + // Reusable thread-local state to match Disruptor events and translators. + @State(Scope.Thread) public static class ThreadState { final RingBufferLogEvent event = new RingBufferLogEvent();
