From 74d1a1e61feceb068742fd1fa5151c979f459c25 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 7 Oct 2025 17:11:54 -0700 Subject: [PATCH 01/18] Add logstash structured arg support --- .../appender/v1_0/OpenTelemetryAppender.java | 29 ++++- .../v1_0/internal/LoggingEventMapper.java | 85 +++++++++++-- .../logback/appender/v1_0/Slf4j2Test.java | 114 ++++++++++++++++++ .../slf4j2ApiTest/resources/logback-test.xml | 3 +- 4 files changed, 215 insertions(+), 16 deletions(-) diff --git a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java index 19dc01bf398a..35b5a7047fe3 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java @@ -36,7 +36,8 @@ public class OpenTelemetryAppender extends UnsynchronizedAppenderBase captureMdcAttributes = emptyList(); private boolean captureEventName = false; @@ -88,7 +89,8 @@ public void start() { .setCaptureKeyValuePairAttributes(captureKeyValuePairAttributes) .setCaptureLoggerContext(captureLoggerContext) .setCaptureArguments(captureArguments) - .setCaptureLogstashAttributes(captureLogstashAttributes) + .setCaptureLogstashMarkers(captureLogstashMarkers) + .setCaptureLogstashStructuredArguments(captureLogstashStructuredArguments) .setCaptureEventName(captureEventName) .build(); eventsToReplay = new ArrayBlockingQueue<>(numLogsCapturedBeforeOtelInstall); @@ -188,9 +190,30 @@ public void setCaptureArguments(boolean captureArguments) { * Sets whether the Logstash attributes should be set to logs. * * @param captureLogstashAttributes To enable or disable capturing Logstash attributes + * @deprecated Use {@link #setCaptureLogstashStructuredArguments(boolean)} instead. This method + * is deprecated and will be removed in a future release. */ + @Deprecated public void setCaptureLogstashAttributes(boolean captureLogstashAttributes) { - this.captureLogstashAttributes = captureLogstashAttributes; + setCaptureLogstashStructuredArguments(captureLogstashAttributes); + } + + /** + * Sets whether the Logstash marker attributes should be set to logs. + * + * @param captureLogstashMarkers To enable or disable capturing Logstash marker attributes + */ + public void setCaptureLogstashMarkers(boolean captureLogstashMarkers) { + this.captureLogstashMarkers = captureLogstashMarkers; + } + + /** + * Sets whether the Logstash StructuredArguments should be captured as attributes. + * + * @param captureLogstashStructuredArguments To enable or disable capturing Logstash StructuredArguments + */ + public void setCaptureLogstashStructuredArguments(boolean captureLogstashStructuredArguments) { + this.captureLogstashStructuredArguments = captureLogstashStructuredArguments; } /** Configures the {@link MDC} attributes that will be copied to logs. */ diff --git a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java index fe385550d305..4c5ce1974305 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java @@ -66,6 +66,7 @@ public final class LoggingEventMapper { private static final boolean supportsKeyValuePairs = supportsKeyValuePairs(); private static final boolean supportsMultipleMarkers = supportsMultipleMarkers(); private static final boolean supportsLogstashMarkers = supportsLogstashMarkers(); + private static final boolean supportsLogstashStructuredArguments = supportsLogstashStructuredArguments(); private static final Cache> attributeKeys = Cache.bounded(100); private static final AttributeKey> LOG_MARKER = @@ -83,7 +84,8 @@ public final class LoggingEventMapper { private final boolean captureKeyValuePairAttributes; private final boolean captureLoggerContext; private final boolean captureArguments; - private final boolean captureLogstashAttributes; + private final boolean captureLogstashMarkers; + private final boolean captureLogstashStructuredArguments; private final boolean captureEventName; private LoggingEventMapper(Builder builder) { @@ -94,7 +96,8 @@ private LoggingEventMapper(Builder builder) { this.captureKeyValuePairAttributes = builder.captureKeyValuePairAttributes; this.captureLoggerContext = builder.captureLoggerContext; this.captureArguments = builder.captureArguments; - this.captureLogstashAttributes = builder.captureLogstashAttributes; + this.captureLogstashMarkers = builder.captureLogstashMarkers; + this.captureLogstashStructuredArguments = builder.captureLogstashStructuredArguments; this.captureAllMdcAttributes = builder.captureMdcAttributes.size() == 1 && builder.captureMdcAttributes.get(0).equals("*"); this.captureEventName = builder.captureEventName; @@ -192,7 +195,7 @@ private void mapLoggingEvent( } if (captureMarkerAttribute) { - boolean skipLogstashMarkers = supportsLogstashMarkers && captureLogstashAttributes; + boolean skipLogstashMarkers = supportsLogstashMarkers && captureLogstashMarkers; captureMarkerAttribute(builder, loggingEvent, skipLogstashMarkers); } @@ -200,6 +203,13 @@ private void mapLoggingEvent( captureKeyValuePairAttributes(builder, loggingEvent); } + if (supportsLogstashStructuredArguments + && captureLogstashStructuredArguments + && loggingEvent.getArgumentArray() != null + && loggingEvent.getArgumentArray().length > 0) { + captureLogstashStructuredArguments(builder, loggingEvent.getArgumentArray()); + } + if (captureLoggerContext) { captureLoggerContext(builder, loggingEvent.getLoggerContextVO().getPropertyMap()); } @@ -210,8 +220,8 @@ private void mapLoggingEvent( captureArguments(builder, loggingEvent.getMessage(), loggingEvent.getArgumentArray()); } - if (supportsLogstashMarkers && captureLogstashAttributes) { - captureLogstashAttributes(builder, loggingEvent); + if (supportsLogstashMarkers && captureLogstashMarkers) { + captureLogstashMarkers(builder, loggingEvent); } // span context builder.setContext(Context.current()); @@ -463,11 +473,11 @@ private static boolean supportsMultipleMarkers() { return true; } - private void captureLogstashAttributes(LogRecordBuilder builder, ILoggingEvent loggingEvent) { + private void captureLogstashMarkers(LogRecordBuilder builder, ILoggingEvent loggingEvent) { if (supportsMultipleMarkers && hasMultipleMarkers(loggingEvent)) { - captureMultipleLogstashAttributes(builder, loggingEvent); + captureMultipleLogstashMarkers(builder, loggingEvent); } else { - captureSingleLogstashAttribute(builder, loggingEvent); + captureSingleLogstashMarker(builder, loggingEvent); } } @@ -477,7 +487,7 @@ private static boolean isLogstashMarker(Marker marker) { } @SuppressWarnings("deprecation") // getMarker is deprecate since 1.3.0 - private void captureSingleLogstashAttribute( + private void captureSingleLogstashMarker( LogRecordBuilder builder, ILoggingEvent loggingEvent) { Marker marker = loggingEvent.getMarker(); if (isLogstashMarker(marker)) { @@ -486,7 +496,7 @@ private void captureSingleLogstashAttribute( } @NoMuzzle - private void captureMultipleLogstashAttributes( + private void captureMultipleLogstashMarkers( LogRecordBuilder builder, ILoggingEvent loggingEvent) { for (Marker marker : loggingEvent.getMarkerList()) { if (isLogstashMarker(marker)) { @@ -615,6 +625,40 @@ private static boolean supportsLogstashMarkers() { return true; } + private static boolean supportsLogstashStructuredArguments() { + try { + Class.forName("net.logstash.logback.argument.StructuredArgument"); + } catch (ClassNotFoundException e) { + return false; + } + + return true; + } + + @NoMuzzle + private void captureLogstashStructuredArguments(LogRecordBuilder builder, Object[] arguments) { + for (Object argument : arguments) { + if (isLogstashStructuredArgument(argument)) { + captureLogstashStructuredArgument(builder, argument); + } + } + } + + @NoMuzzle + private static boolean isLogstashStructuredArgument(Object argument) { + // StructuredArguments implement the marker interface, so we can check for it + // without importing the class directly (which may not be available at runtime) + return argument instanceof SingleFieldAppendingMarker; + } + + @NoMuzzle + private void captureLogstashStructuredArgument(LogRecordBuilder builder, Object argument) { + // StructuredArguments created by v() or keyValue() extend SingleFieldAppendingMarker + // which has getFieldName() and provides field value via reflection + SingleFieldAppendingMarker marker = (SingleFieldAppendingMarker) argument; + captureLogstashMarkerAttributes(builder, marker); + } + private interface FieldReader { void read(LogRecordBuilder builder, Object logstashMarker, boolean captureEventName); } @@ -642,7 +686,8 @@ public static final class Builder { private boolean captureKeyValuePairAttributes; private boolean captureLoggerContext; private boolean captureArguments; - private boolean captureLogstashAttributes; + private boolean captureLogstashMarkers; + private boolean captureLogstashStructuredArguments; private boolean captureEventName; Builder() {} @@ -689,9 +734,25 @@ public Builder setCaptureArguments(boolean captureArguments) { return this; } + /** + * @deprecated Use {@link #setCaptureLogstashStructuredArguments(boolean)} instead. This method + * is deprecated and will be removed in a future release. + */ + @Deprecated @CanIgnoreReturnValue public Builder setCaptureLogstashAttributes(boolean captureLogstashAttributes) { - this.captureLogstashAttributes = captureLogstashAttributes; + return setCaptureLogstashStructuredArguments(captureLogstashAttributes); + } + + @CanIgnoreReturnValue + public Builder setCaptureLogstashMarkers(boolean captureLogstashMarkers) { + this.captureLogstashMarkers = captureLogstashMarkers; + return this; + } + + @CanIgnoreReturnValue + public Builder setCaptureLogstashStructuredArguments(boolean captureLogstashStructuredArguments) { + this.captureLogstashStructuredArguments = captureLogstashStructuredArguments; return this; } diff --git a/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/Slf4j2Test.java b/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/Slf4j2Test.java index a8ae2ab74fde..b62d993f46b9 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/Slf4j2Test.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/Slf4j2Test.java @@ -15,6 +15,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import net.logstash.logback.argument.StructuredArguments; import net.logstash.logback.marker.Markers; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -239,4 +240,117 @@ void logstashEmptyAndNullValues() { .hasBody("log message 1") .hasTotalAttributeCount(codeAttributesLogCount())); } + + @Test + void structuredArgumentsWithV() { + logger.warn( + "This is a warning log for customerId: {}", + StructuredArguments.v("customer_id", "123")); + + testing.waitAndAssertLogRecords( + logRecord -> + logRecord + .hasResource(resource) + .hasInstrumentationScope(instrumentationScopeInfo) + .hasBody("This is a warning log for customerId: 123") + .hasTotalAttributeCount(codeAttributesLogCount() + 3) + .hasAttributesSatisfying( + equalTo(AttributeKey.stringKey("customer_id"), "123"), + equalTo( + AttributeKey.stringKey("log.body.template"), + "This is a warning log for customerId: {}"), + equalTo( + AttributeKey.stringArrayKey("log.body.parameters"), + Arrays.asList("123")))); + } + + @Test + void structuredArgumentsWithKeyValue() { + logger.info("Processing order: {}", StructuredArguments.keyValue("order_id", "ORD-456")); + + testing.waitAndAssertLogRecords( + logRecord -> + logRecord + .hasResource(resource) + .hasInstrumentationScope(instrumentationScopeInfo) + .hasBody("Processing order: order_id=ORD-456") + .hasTotalAttributeCount(codeAttributesLogCount() + 3) + .hasAttributesSatisfying( + equalTo(AttributeKey.stringKey("order_id"), "ORD-456"), + equalTo(AttributeKey.stringKey("log.body.template"), "Processing order: {}"), + equalTo( + AttributeKey.stringArrayKey("log.body.parameters"), + Arrays.asList("order_id=ORD-456")))); + } + + @Test + void structuredArgumentsMultiple() { + logger.warn( + "Transaction failed for customer: {} with amount: {}", + StructuredArguments.v("customer_id", "789"), + StructuredArguments.v("amount", 99.99)); + + testing.waitAndAssertLogRecords( + logRecord -> + logRecord + .hasResource(resource) + .hasInstrumentationScope(instrumentationScopeInfo) + .hasBody("Transaction failed for customer: 789 with amount: 99.99") + .hasTotalAttributeCount(codeAttributesLogCount() + 4) + .hasAttributesSatisfying( + equalTo(AttributeKey.stringKey("customer_id"), "789"), + equalTo(AttributeKey.doubleKey("amount"), 99.99), + equalTo( + AttributeKey.stringKey("log.body.template"), + "Transaction failed for customer: {} with amount: {}"), + equalTo( + AttributeKey.stringArrayKey("log.body.parameters"), + Arrays.asList("789", "99.99")))); + } + + @Test + void structuredArgumentsWithEventName() { + logger.info("Event occurred: {}", StructuredArguments.v("event.name", "OrderPlaced")); + + testing.waitAndAssertLogRecords( + logRecord -> + logRecord + .hasResource(resource) + .hasInstrumentationScope(instrumentationScopeInfo) + .hasBody("Event occurred: OrderPlaced") + .hasEventName("OrderPlaced") + .hasTotalAttributeCount(codeAttributesLogCount() + 2) + .hasAttributesSatisfying( + equalTo(AttributeKey.stringKey("log.body.template"), "Event occurred: {}"), + equalTo( + AttributeKey.stringArrayKey("log.body.parameters"), + Arrays.asList("OrderPlaced")))); + } + + @Test + void structuredArgumentsWithTypedValues() { + long timestamp = System.currentTimeMillis(); + logger.info( + "User logged in: {} at {} with session: {}", + StructuredArguments.v("user_id", 12345), + StructuredArguments.v("timestamp", timestamp), + StructuredArguments.v("session_active", true)); + + testing.waitAndAssertLogRecords( + logRecord -> + logRecord + .hasResource(resource) + .hasInstrumentationScope(instrumentationScopeInfo) + .hasTotalAttributeCount(codeAttributesLogCount() + 5) + .hasAttributesSatisfying( + equalTo(AttributeKey.longKey("user_id"), 12345L), + equalTo(AttributeKey.longKey("timestamp"), timestamp), + equalTo(AttributeKey.booleanKey("session_active"), true), + equalTo( + AttributeKey.stringKey("log.body.template"), + "User logged in: {} at {} with session: {}"), + equalTo( + AttributeKey.stringArrayKey("log.body.parameters"), + Arrays.asList("12345", String.valueOf(timestamp), "true")))); + } } diff --git a/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/resources/logback-test.xml b/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/resources/logback-test.xml index 60a3589281bf..04edb448ffab 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/resources/logback-test.xml +++ b/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/resources/logback-test.xml @@ -15,7 +15,8 @@ true true true - true + true + true * true From feda4276d77e9e13374cb1e47d224f66e3b16ed2 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sat, 11 Oct 2025 11:27:27 -0700 Subject: [PATCH 02/18] docs --- .../logback-appender-1.0/javaagent/README.md | 3 ++- .../appender/v1_0/LogbackSingletons.java | 14 +++++++++++--- .../logback-appender-1.0/library/README.md | 3 ++- .../appender/v1_0/OpenTelemetryAppender.java | 10 +++++----- .../v1_0/internal/LoggingEventMapper.java | 18 +++++++++--------- .../slf4j2ApiTest/resources/logback-test.xml | 2 +- .../logging/LogbackAppenderInstaller.java | 19 +++++++++++++++---- ...itional-spring-configuration-metadata.json | 10 ++++++++-- 8 files changed, 53 insertions(+), 26 deletions(-) diff --git a/instrumentation/logback/logback-appender-1.0/javaagent/README.md b/instrumentation/logback/logback-appender-1.0/javaagent/README.md index e83844e560db..8ad17030a717 100644 --- a/instrumentation/logback/logback-appender-1.0/javaagent/README.md +++ b/instrumentation/logback/logback-appender-1.0/javaagent/README.md @@ -8,7 +8,8 @@ | `otel.instrumentation.logback-appender.experimental.capture-key-value-pair-attributes` | Boolean | `false` | Enable the capture of Logback key value pairs as attributes. | | `otel.instrumentation.logback-appender.experimental.capture-logger-context-attributes` | Boolean | `false` | Enable the capture of Logback logger context properties as attributes. | | `otel.instrumentation.logback-appender.experimental.capture-arguments` | Boolean | `false` | Enable the capture of Logback logger arguments. | -| `otel.instrumentation.logback-appender.experimental.capture-logstash-attributes` | Boolean | `false` | Enable the capture of Logstash attributes, supported are those added to logs via `Markers.append()`, `Markers.appendEntries()`, `Markers.appendArray()` and `Markers.appendRaw()` methods. | +| `otel.instrumentation.logback-appender.experimental.capture-logstash-marker-attributes` | Boolean | `false` | Enable the capture of Logstash markers, supported are those added to logs via `Markers.append()`, `Markers.appendEntries()`, `Markers.appendArray()` and `Markers.appendRaw()` methods. | +| `otel.instrumentation.logback-appender.experimental.capture-logstash-structured-arguments` | Boolean | `false` | Enable the capture of Logstash StructuredArguments as attributes (e.g., `StructuredArguments.v()` and `StructuredArguments.keyValue()`). | | `otel.instrumentation.logback-appender.experimental.capture-mdc-attributes` | String | | Comma separated list of MDC attributes to capture. Use the wildcard character `*` to capture all attributes. | | `otel.instrumentation.logback-appender.experimental.capture-event-name` | Boolean | `false` | Enable moving the `event.name` attribute (captured by one of the other mechanisms of capturing attributes) to the log event name. | diff --git a/instrumentation/logback/logback-appender-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/logback/appender/v1_0/LogbackSingletons.java b/instrumentation/logback/logback-appender-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/logback/appender/v1_0/LogbackSingletons.java index 7a5df143cf4e..ffd92bd1497d 100644 --- a/instrumentation/logback/logback-appender-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/logback/appender/v1_0/LogbackSingletons.java +++ b/instrumentation/logback/logback-appender-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/logback/appender/v1_0/LogbackSingletons.java @@ -10,6 +10,7 @@ import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.logback.appender.v1_0.internal.LoggingEventMapper; import io.opentelemetry.javaagent.bootstrap.internal.AgentInstrumentationConfig; +import io.opentelemetry.javaagent.bootstrap.internal.DeprecatedConfigProperties; import java.util.List; public final class LogbackSingletons { @@ -39,9 +40,15 @@ public final class LogbackSingletons { boolean captureArguments = config.getBoolean( "otel.instrumentation.logback-appender.experimental.capture-arguments", false); - boolean captureLogstashAttributes = - config.getBoolean( + boolean captureLogstashMarkerAttributes = + DeprecatedConfigProperties.getBoolean( + config, "otel.instrumentation.logback-appender.experimental.capture-logstash-attributes", + "otel.instrumentation.logback-appender.experimental.capture-logstash-marker-attributes", + false); + boolean captureLogstashStructuredArguments = + config.getBoolean( + "otel.instrumentation.logback-appender.experimental.capture-logstash-structured-arguments", false); List captureMdcAttributes = config.getList( @@ -60,7 +67,8 @@ public final class LogbackSingletons { .setCaptureKeyValuePairAttributes(captureKeyValuePairAttributes) .setCaptureLoggerContext(captureLoggerContext) .setCaptureArguments(captureArguments) - .setCaptureLogstashAttributes(captureLogstashAttributes) + .setCaptureLogstashMarkerAttributes(captureLogstashMarkerAttributes) + .setCaptureLogstashStructuredArguments(captureLogstashStructuredArguments) .setCaptureEventName(captureEventName) .build(); } diff --git a/instrumentation/logback/logback-appender-1.0/library/README.md b/instrumentation/logback/logback-appender-1.0/library/README.md index 6de16a108ce5..d0fd3813d538 100644 --- a/instrumentation/logback/logback-appender-1.0/library/README.md +++ b/instrumentation/logback/logback-appender-1.0/library/README.md @@ -101,7 +101,8 @@ The available settings are: | `captureKeyValuePairAttributes` | Boolean | `false` | Enable the capture of Logback key value pairs as attributes. | | `captureLoggerContext` | Boolean | `false` | Enable the capture of Logback logger context properties as attributes. | | `captureArguments` | Boolean | `false` | Enable the capture of Logback logger arguments. | -| `captureLogstashAttributes` | Boolean | `false` | Enable the capture of Logstash attributes, supported are those added to logs via `Markers.append()`, `Markers.appendEntries()`, `Markers.appendArray()` and `Markers.appendRaw()` methods. | +| `captureLogstashMarkerAttributes` | Boolean | `false` | Enable the capture of Logstash markers, supported are those added to logs via `Markers.append()`, `Markers.appendEntries()`, `Markers.appendArray()` and `Markers.appendRaw()` methods. | +| `captureLogstashStructuredArguments` | Boolean | `false` | Enable the capture of Logstash StructuredArguments as attributes (e.g., `StructuredArguments.v()` and `StructuredArguments.keyValue()`). | | `captureMdcAttributes` | String | | Comma separated list of MDC attributes to capture. Use the wildcard character `*` to capture all attributes. | | `captureEventName` | Boolean | `false` | Enable moving the `event.name` attribute (captured by one of the other mechanisms of capturing attributes) to the log event name. | | `numLogsCapturedBeforeOtelInstall` | Integer | 1000 | Log telemetry is emitted after the initialization of the OpenTelemetry Logback appender with an OpenTelemetry object. This setting allows you to modify the size of the cache used to replay the first logs. thread.id attribute is not captured. | diff --git a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java index 35b5a7047fe3..a21b180829fa 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java @@ -36,7 +36,7 @@ public class OpenTelemetryAppender extends UnsynchronizedAppenderBase captureMdcAttributes = emptyList(); private boolean captureEventName = false; @@ -89,7 +89,7 @@ public void start() { .setCaptureKeyValuePairAttributes(captureKeyValuePairAttributes) .setCaptureLoggerContext(captureLoggerContext) .setCaptureArguments(captureArguments) - .setCaptureLogstashMarkers(captureLogstashMarkers) + .setCaptureLogstashMarkerAttributes(captureLogstashMarkerAttributes) .setCaptureLogstashStructuredArguments(captureLogstashStructuredArguments) .setCaptureEventName(captureEventName) .build(); @@ -201,10 +201,10 @@ public void setCaptureLogstashAttributes(boolean captureLogstashAttributes) { /** * Sets whether the Logstash marker attributes should be set to logs. * - * @param captureLogstashMarkers To enable or disable capturing Logstash marker attributes + * @param captureLogstashMarkerAttributes To enable or disable capturing Logstash marker attributes */ - public void setCaptureLogstashMarkers(boolean captureLogstashMarkers) { - this.captureLogstashMarkers = captureLogstashMarkers; + public void setCaptureLogstashMarkerAttributes(boolean captureLogstashMarkerAttributes) { + this.captureLogstashMarkerAttributes = captureLogstashMarkerAttributes; } /** diff --git a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java index 4c5ce1974305..503cb417e258 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java @@ -84,7 +84,7 @@ public final class LoggingEventMapper { private final boolean captureKeyValuePairAttributes; private final boolean captureLoggerContext; private final boolean captureArguments; - private final boolean captureLogstashMarkers; + private final boolean captureLogstashMarkerAttributes; private final boolean captureLogstashStructuredArguments; private final boolean captureEventName; @@ -96,7 +96,7 @@ private LoggingEventMapper(Builder builder) { this.captureKeyValuePairAttributes = builder.captureKeyValuePairAttributes; this.captureLoggerContext = builder.captureLoggerContext; this.captureArguments = builder.captureArguments; - this.captureLogstashMarkers = builder.captureLogstashMarkers; + this.captureLogstashMarkerAttributes = builder.captureLogstashMarkerAttributes; this.captureLogstashStructuredArguments = builder.captureLogstashStructuredArguments; this.captureAllMdcAttributes = builder.captureMdcAttributes.size() == 1 && builder.captureMdcAttributes.get(0).equals("*"); @@ -195,7 +195,7 @@ private void mapLoggingEvent( } if (captureMarkerAttribute) { - boolean skipLogstashMarkers = supportsLogstashMarkers && captureLogstashMarkers; + boolean skipLogstashMarkers = supportsLogstashMarkers && captureLogstashMarkerAttributes; captureMarkerAttribute(builder, loggingEvent, skipLogstashMarkers); } @@ -220,8 +220,8 @@ private void mapLoggingEvent( captureArguments(builder, loggingEvent.getMessage(), loggingEvent.getArgumentArray()); } - if (supportsLogstashMarkers && captureLogstashMarkers) { - captureLogstashMarkers(builder, loggingEvent); + if (supportsLogstashMarkers && captureLogstashMarkerAttributes) { + captureLogstashMarkerAttributes(builder, loggingEvent); } // span context builder.setContext(Context.current()); @@ -473,7 +473,7 @@ private static boolean supportsMultipleMarkers() { return true; } - private void captureLogstashMarkers(LogRecordBuilder builder, ILoggingEvent loggingEvent) { + private void captureLogstashMarkerAttributes(LogRecordBuilder builder, ILoggingEvent loggingEvent) { if (supportsMultipleMarkers && hasMultipleMarkers(loggingEvent)) { captureMultipleLogstashMarkers(builder, loggingEvent); } else { @@ -686,7 +686,7 @@ public static final class Builder { private boolean captureKeyValuePairAttributes; private boolean captureLoggerContext; private boolean captureArguments; - private boolean captureLogstashMarkers; + private boolean captureLogstashMarkerAttributes; private boolean captureLogstashStructuredArguments; private boolean captureEventName; @@ -745,8 +745,8 @@ public Builder setCaptureLogstashAttributes(boolean captureLogstashAttributes) { } @CanIgnoreReturnValue - public Builder setCaptureLogstashMarkers(boolean captureLogstashMarkers) { - this.captureLogstashMarkers = captureLogstashMarkers; + public Builder setCaptureLogstashMarkerAttributes(boolean captureLogstashMarkerAttributes) { + this.captureLogstashMarkerAttributes = captureLogstashMarkerAttributes; return this; } diff --git a/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/resources/logback-test.xml b/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/resources/logback-test.xml index 04edb448ffab..92b2ddefc859 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/resources/logback-test.xml +++ b/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/resources/logback-test.xml @@ -15,7 +15,7 @@ true true true - true + true true * true diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LogbackAppenderInstaller.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LogbackAppenderInstaller.java index fd13848aaf2f..19bd5be5e221 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LogbackAppenderInstaller.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LogbackAppenderInstaller.java @@ -143,12 +143,23 @@ private static void initializeOpenTelemetryAppenderFromProperties( openTelemetryAppender.setCaptureArguments(captureArguments.booleanValue()); } - Boolean captureLogstashAttributes = + Boolean captureLogstashMarkerAttributes = + DeprecatedConfigProperties.getBoolean( + applicationEnvironmentPreparedEvent, + "otel.instrumentation.logback-appender.experimental.capture-logstash-markers", + "otel.instrumentation.logback-appender.experimental.capture-logstash-marker-attributes"); + if (captureLogstashMarkerAttributes != null) { + openTelemetryAppender.setCaptureLogstashMarkerAttributes( + captureLogstashMarkerAttributes.booleanValue()); + } + + Boolean captureLogstashStructuredArguments = evaluateBooleanProperty( applicationEnvironmentPreparedEvent, - "otel.instrumentation.logback-appender.experimental.capture-logstash-attributes"); - if (captureLogstashAttributes != null) { - openTelemetryAppender.setCaptureLogstashAttributes(captureLogstashAttributes.booleanValue()); + "otel.instrumentation.logback-appender.experimental.capture-logstash-structured-arguments"); + if (captureLogstashStructuredArguments != null) { + openTelemetryAppender.setCaptureLogstashStructuredArguments( + captureLogstashStructuredArguments.booleanValue()); } String mdcAttributeProperty = diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index e92a74381443..2269bd2794a8 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -442,9 +442,15 @@ "defaultValue": false }, { - "name": "otel.instrumentation.logback-appender.experimental.capture-logstash-attributes", + "name": "otel.instrumentation.logback-appender.experimental.capture-logstash-marker-attributes", "type": "java.lang.Boolean", - "description": "Enable the capture of Logstash attributes, supported are those added to logs via `Markers.append()`, `Markers.appendEntries()`, `Markers.appendArray()` and `Markers.appendRaw()` methods.", + "description": "Enable the capture of Logstash marker attributes, supported are those added to logs via `Markers.append()`, `Markers.appendEntries()`, `Markers.appendArray()` and `Markers.appendRaw()` methods.", + "defaultValue": false + }, + { + "name": "otel.instrumentation.logback-appender.experimental.capture-logstash-structured-arguments", + "type": "java.lang.Boolean", + "description": "Enable the capture of Logstash StructuredArguments as attributes (e.g., `StructuredArguments.v()` and `StructuredArguments.keyValue()`).", "defaultValue": false }, { From 25815faaf7b8c99ffb24f05de0a74a5eb7fe1953 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sat, 11 Oct 2025 13:55:44 -0700 Subject: [PATCH 03/18] renames --- .../v1_0/internal/LoggingEventMapper.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java index 503cb417e258..257e81b5dccc 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java @@ -491,7 +491,7 @@ private void captureSingleLogstashMarker( LogRecordBuilder builder, ILoggingEvent loggingEvent) { Marker marker = loggingEvent.getMarker(); if (isLogstashMarker(marker)) { - captureLogstashMarker(builder, marker); + captureLogstashMarkerAndReferences(builder, marker); } } @@ -500,27 +500,28 @@ private void captureMultipleLogstashMarkers( LogRecordBuilder builder, ILoggingEvent loggingEvent) { for (Marker marker : loggingEvent.getMarkerList()) { if (isLogstashMarker(marker)) { - captureLogstashMarker(builder, marker); + captureLogstashMarkerAndReferences(builder, marker); } } } @NoMuzzle - private void captureLogstashMarker(LogRecordBuilder builder, Marker marker) { + private void captureLogstashMarkerAndReferences(LogRecordBuilder builder, Marker marker) { LogstashMarker logstashMarker = (LogstashMarker) marker; - captureLogstashMarkerAttributes(builder, logstashMarker); + captureLogstashMarker(builder, logstashMarker); if (logstashMarker.hasReferences()) { for (Iterator it = logstashMarker.iterator(); it.hasNext(); ) { Marker referenceMarker = it.next(); if (isLogstashMarker(referenceMarker)) { - captureLogstashMarker(builder, referenceMarker); + captureLogstashMarkerAndReferences(builder, referenceMarker); } } } } - private void captureLogstashMarkerAttributes(LogRecordBuilder builder, Object logstashMarker) { + @NoMuzzle + private void captureLogstashMarker(LogRecordBuilder builder, LogstashMarker logstashMarker) { FieldReader fieldReader = LogstashFieldReaderHolder.valueField.get(logstashMarker.getClass()); if (fieldReader != null) { fieldReader.read(builder, logstashMarker, this.captureEventName); @@ -656,7 +657,7 @@ private void captureLogstashStructuredArgument(LogRecordBuilder builder, Object // StructuredArguments created by v() or keyValue() extend SingleFieldAppendingMarker // which has getFieldName() and provides field value via reflection SingleFieldAppendingMarker marker = (SingleFieldAppendingMarker) argument; - captureLogstashMarkerAttributes(builder, marker); + captureLogstashMarker(builder, marker); } private interface FieldReader { From 5d8517eb5ee678bcd18b17afd748b3034136974e Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sat, 11 Oct 2025 14:10:33 -0700 Subject: [PATCH 04/18] fix --- .../logback/appender/v1_0/internal/LoggingEventMapper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java index 257e81b5dccc..72266d50fb73 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java @@ -519,9 +519,9 @@ private void captureLogstashMarkerAndReferences(LogRecordBuilder builder, Marker } } } + - @NoMuzzle - private void captureLogstashMarker(LogRecordBuilder builder, LogstashMarker logstashMarker) { + private void captureLogstashMarker(LogRecordBuilder builder, Object logstashMarker) { FieldReader fieldReader = LogstashFieldReaderHolder.valueField.get(logstashMarker.getClass()); if (fieldReader != null) { fieldReader.read(builder, logstashMarker, this.captureEventName); From 7fa4c3b6a5abca4cd0708a865b1061cfec97f5af Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sat, 11 Oct 2025 14:16:23 -0700 Subject: [PATCH 05/18] spotless --- .../appender/v1_0/OpenTelemetryAppender.java | 10 ++++++---- .../appender/v1_0/internal/LoggingEventMapper.java | 13 +++++++------ .../logback/appender/v1_0/Slf4j2Test.java | 6 ++---- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java index a21b180829fa..6286c0be8bf7 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java @@ -190,8 +190,8 @@ public void setCaptureArguments(boolean captureArguments) { * Sets whether the Logstash attributes should be set to logs. * * @param captureLogstashAttributes To enable or disable capturing Logstash attributes - * @deprecated Use {@link #setCaptureLogstashStructuredArguments(boolean)} instead. This method - * is deprecated and will be removed in a future release. + * @deprecated Use {@link #setCaptureLogstashStructuredArguments(boolean)} instead. This method is + * deprecated and will be removed in a future release. */ @Deprecated public void setCaptureLogstashAttributes(boolean captureLogstashAttributes) { @@ -201,7 +201,8 @@ public void setCaptureLogstashAttributes(boolean captureLogstashAttributes) { /** * Sets whether the Logstash marker attributes should be set to logs. * - * @param captureLogstashMarkerAttributes To enable or disable capturing Logstash marker attributes + * @param captureLogstashMarkerAttributes To enable or disable capturing Logstash marker + * attributes */ public void setCaptureLogstashMarkerAttributes(boolean captureLogstashMarkerAttributes) { this.captureLogstashMarkerAttributes = captureLogstashMarkerAttributes; @@ -210,7 +211,8 @@ public void setCaptureLogstashMarkerAttributes(boolean captureLogstashMarkerAttr /** * Sets whether the Logstash StructuredArguments should be captured as attributes. * - * @param captureLogstashStructuredArguments To enable or disable capturing Logstash StructuredArguments + * @param captureLogstashStructuredArguments To enable or disable capturing Logstash + * StructuredArguments */ public void setCaptureLogstashStructuredArguments(boolean captureLogstashStructuredArguments) { this.captureLogstashStructuredArguments = captureLogstashStructuredArguments; diff --git a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java index 72266d50fb73..4090cfb4fcbc 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java @@ -66,7 +66,8 @@ public final class LoggingEventMapper { private static final boolean supportsKeyValuePairs = supportsKeyValuePairs(); private static final boolean supportsMultipleMarkers = supportsMultipleMarkers(); private static final boolean supportsLogstashMarkers = supportsLogstashMarkers(); - private static final boolean supportsLogstashStructuredArguments = supportsLogstashStructuredArguments(); + private static final boolean supportsLogstashStructuredArguments = + supportsLogstashStructuredArguments(); private static final Cache> attributeKeys = Cache.bounded(100); private static final AttributeKey> LOG_MARKER = @@ -473,7 +474,8 @@ private static boolean supportsMultipleMarkers() { return true; } - private void captureLogstashMarkerAttributes(LogRecordBuilder builder, ILoggingEvent loggingEvent) { + private void captureLogstashMarkerAttributes( + LogRecordBuilder builder, ILoggingEvent loggingEvent) { if (supportsMultipleMarkers && hasMultipleMarkers(loggingEvent)) { captureMultipleLogstashMarkers(builder, loggingEvent); } else { @@ -487,8 +489,7 @@ private static boolean isLogstashMarker(Marker marker) { } @SuppressWarnings("deprecation") // getMarker is deprecate since 1.3.0 - private void captureSingleLogstashMarker( - LogRecordBuilder builder, ILoggingEvent loggingEvent) { + private void captureSingleLogstashMarker(LogRecordBuilder builder, ILoggingEvent loggingEvent) { Marker marker = loggingEvent.getMarker(); if (isLogstashMarker(marker)) { captureLogstashMarkerAndReferences(builder, marker); @@ -519,7 +520,6 @@ private void captureLogstashMarkerAndReferences(LogRecordBuilder builder, Marker } } } - private void captureLogstashMarker(LogRecordBuilder builder, Object logstashMarker) { FieldReader fieldReader = LogstashFieldReaderHolder.valueField.get(logstashMarker.getClass()); @@ -752,7 +752,8 @@ public Builder setCaptureLogstashMarkerAttributes(boolean captureLogstashMarkerA } @CanIgnoreReturnValue - public Builder setCaptureLogstashStructuredArguments(boolean captureLogstashStructuredArguments) { + public Builder setCaptureLogstashStructuredArguments( + boolean captureLogstashStructuredArguments) { this.captureLogstashStructuredArguments = captureLogstashStructuredArguments; return this; } diff --git a/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/Slf4j2Test.java b/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/Slf4j2Test.java index b62d993f46b9..85781fa6347a 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/Slf4j2Test.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/Slf4j2Test.java @@ -244,8 +244,7 @@ void logstashEmptyAndNullValues() { @Test void structuredArgumentsWithV() { logger.warn( - "This is a warning log for customerId: {}", - StructuredArguments.v("customer_id", "123")); + "This is a warning log for customerId: {}", StructuredArguments.v("customer_id", "123")); testing.waitAndAssertLogRecords( logRecord -> @@ -260,8 +259,7 @@ void structuredArgumentsWithV() { AttributeKey.stringKey("log.body.template"), "This is a warning log for customerId: {}"), equalTo( - AttributeKey.stringArrayKey("log.body.parameters"), - Arrays.asList("123")))); + AttributeKey.stringArrayKey("log.body.parameters"), Arrays.asList("123")))); } @Test From 9e12b621d8a614af28918b1984187a06267c9904 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sat, 11 Oct 2025 17:45:15 -0700 Subject: [PATCH 06/18] fix --- .../internal/DeprecatedConfigProperties.java | 49 +++++++++++++++++++ .../logging/LogbackAppenderInstaller.java | 1 + 2 files changed, 50 insertions(+) create mode 100644 instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java new file mode 100644 index 000000000000..2f0195095942 --- /dev/null +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java @@ -0,0 +1,49 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.spring.autoconfigure.internal; + +import static java.util.logging.Level.WARNING; + +import java.util.logging.Logger; +import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +@SuppressWarnings("unused") +public final class DeprecatedConfigProperties { + + private static final Logger logger = Logger.getLogger(DeprecatedConfigProperties.class.getName()); + + public static Boolean getBoolean( + ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent, + String deprecatedPropertyName, + String newPropertyName) { + warnIfUsed(applicationEnvironmentPreparedEvent, deprecatedPropertyName, newPropertyName); + Boolean deprecatedValue = + applicationEnvironmentPreparedEvent.getEnvironment().getProperty(deprecatedPropertyName, Boolean.class); + Boolean newValue = + applicationEnvironmentPreparedEvent.getEnvironment().getProperty(newPropertyName, Boolean.class); + + // Return the new value if it exists, otherwise return the deprecated value + return newValue != null ? newValue : deprecatedValue; + } + + private static void warnIfUsed( + ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent, + String deprecatedPropertyName, + String newPropertyName) { + if (applicationEnvironmentPreparedEvent.getEnvironment().getProperty(deprecatedPropertyName) != null) { + logger.log( + WARNING, + "Deprecated property \"{0}\" was used; use the \"{1}\" property instead", + new Object[] {deprecatedPropertyName, newPropertyName}); + } + } + + private DeprecatedConfigProperties() {} +} \ No newline at end of file diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LogbackAppenderInstaller.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LogbackAppenderInstaller.java index 19bd5be5e221..f6354622174c 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LogbackAppenderInstaller.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LogbackAppenderInstaller.java @@ -9,6 +9,7 @@ import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.Appender; import io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.DeprecatedConfigProperties; import java.util.Iterator; import java.util.Optional; import org.slf4j.ILoggerFactory; From 27fbe01251d2574cadbfa0a845ae0d5e76327756 Mon Sep 17 00:00:00 2001 From: otelbot <197425009+otelbot@users.noreply.github.com> Date: Sun, 12 Oct 2025 00:53:26 +0000 Subject: [PATCH 07/18] ./gradlew spotlessApply --- .../internal/DeprecatedConfigProperties.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java index 2f0195095942..a6cd481fc184 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java @@ -24,11 +24,15 @@ public static Boolean getBoolean( String deprecatedPropertyName, String newPropertyName) { warnIfUsed(applicationEnvironmentPreparedEvent, deprecatedPropertyName, newPropertyName); - Boolean deprecatedValue = - applicationEnvironmentPreparedEvent.getEnvironment().getProperty(deprecatedPropertyName, Boolean.class); - Boolean newValue = - applicationEnvironmentPreparedEvent.getEnvironment().getProperty(newPropertyName, Boolean.class); - + Boolean deprecatedValue = + applicationEnvironmentPreparedEvent + .getEnvironment() + .getProperty(deprecatedPropertyName, Boolean.class); + Boolean newValue = + applicationEnvironmentPreparedEvent + .getEnvironment() + .getProperty(newPropertyName, Boolean.class); + // Return the new value if it exists, otherwise return the deprecated value return newValue != null ? newValue : deprecatedValue; } @@ -37,7 +41,8 @@ private static void warnIfUsed( ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent, String deprecatedPropertyName, String newPropertyName) { - if (applicationEnvironmentPreparedEvent.getEnvironment().getProperty(deprecatedPropertyName) != null) { + if (applicationEnvironmentPreparedEvent.getEnvironment().getProperty(deprecatedPropertyName) + != null) { logger.log( WARNING, "Deprecated property \"{0}\" was used; use the \"{1}\" property instead", @@ -46,4 +51,4 @@ private static void warnIfUsed( } private DeprecatedConfigProperties() {} -} \ No newline at end of file +} From f2a4384023eb55a2efdcb8486e6b950d40f0d845 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sun, 12 Oct 2025 11:43:16 -0700 Subject: [PATCH 08/18] Better test split --- .../library/build.gradle.kts | 54 +++++ .../appender/v1_0/LogstashMarkerTest.java | 154 ++++++++++++ .../resources/logback-test.xml | 23 ++ .../v1_0/LogstashStructuredArgsTest.java | 122 ++++++++++ .../resources/logback-test.xml | 23 ++ .../logback/appender/v1_0/Slf4j2Test.java | 223 ------------------ 6 files changed, 376 insertions(+), 223 deletions(-) create mode 100644 instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java create mode 100644 instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/resources/logback-test.xml create mode 100644 instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java create mode 100644 instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/resources/logback-test.xml diff --git a/instrumentation/logback/logback-appender-1.0/library/build.gradle.kts b/instrumentation/logback/logback-appender-1.0/library/build.gradle.kts index b5fa1af6d883..e4679f6f1b75 100644 --- a/instrumentation/logback/logback-appender-1.0/library/build.gradle.kts +++ b/instrumentation/logback/logback-appender-1.0/library/build.gradle.kts @@ -74,6 +74,30 @@ val latestDepTest = findProperty("testLatestDeps") as Boolean testing { suites { val slf4j2ApiTest by registering(JvmTestSuite::class) { + dependencies { + implementation(project(":instrumentation:logback:logback-appender-1.0:library")) + implementation("io.opentelemetry:opentelemetry-sdk-testing") + implementation(project(":testing-common")) + + if (latestDepTest) { + implementation("ch.qos.logback:logback-classic:latest.release") + implementation("org.slf4j:slf4j-api:latest.release") + } else { + implementation("ch.qos.logback:logback-classic") { + version { + strictly("1.3.0") + } + } + implementation("org.slf4j:slf4j-api") { + version { + strictly("2.0.0") + } + } + } + } + } + + val logstashMarkerTest by registering(JvmTestSuite::class) { dependencies { implementation(project(":instrumentation:logback:logback-appender-1.0:library")) implementation("io.opentelemetry:opentelemetry-sdk-testing") @@ -103,6 +127,36 @@ testing { } } + val logstashStructuredArgsTest by registering(JvmTestSuite::class) { + dependencies { + implementation(project(":instrumentation:logback:logback-appender-1.0:library")) + implementation("io.opentelemetry:opentelemetry-sdk-testing") + implementation(project(":testing-common")) + + if (latestDepTest) { + implementation("ch.qos.logback:logback-classic:latest.release") + implementation("org.slf4j:slf4j-api:latest.release") + implementation("net.logstash.logback:logstash-logback-encoder:latest.release") + } else { + implementation("ch.qos.logback:logback-classic") { + version { + strictly("1.3.0") + } + } + implementation("org.slf4j:slf4j-api") { + version { + strictly("2.0.0") + } + } + implementation("net.logstash.logback:logstash-logback-encoder") { + version { + strictly("6.6") + } + } + } + } + } + val asyncAppenderTest by registering(JvmTestSuite::class) { dependencies { implementation(project(":instrumentation:logback:logback-appender-1.0:library")) diff --git a/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java b/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java new file mode 100644 index 000000000000..2fe9f9fc6ba4 --- /dev/null +++ b/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java @@ -0,0 +1,154 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.logback.appender.v1_0; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.resources.Resource; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import net.logstash.logback.marker.Markers; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Tests for Logstash Marker functionality using net.logstash.logback.marker.Markers. + * This test suite focuses specifically on testing marker-based structured logging. + */ +public class LogstashMarkerTest { + private static final Logger logger = LoggerFactory.getLogger("TestLogger"); + + @RegisterExtension + private static final LibraryInstrumentationExtension testing = + LibraryInstrumentationExtension.create(); + + private static Resource resource; + private static InstrumentationScopeInfo instrumentationScopeInfo; + + @BeforeAll + static void setupAll() { + resource = Resource.getDefault(); + instrumentationScopeInfo = InstrumentationScopeInfo.create("TestLogger"); + + // Configuration is handled by logback-test.xml in resources + OpenTelemetryAppender.install(testing.getOpenTelemetry()); + } + + @Test + void logstash() { + Map entries = new HashMap<>(); + entries.put("field2", 2); + entries.put("field3", "value3"); + + logger + .atInfo() + .setMessage("log message 1") + .addMarker(Markers.append("field1", "value1")) + .addMarker(Markers.append("event.name", "MyEventName")) + .addMarker(Markers.appendEntries(entries)) + .log(); + + testing.waitAndAssertLogRecords( + logRecord -> + logRecord + .hasResource(resource) + .hasInstrumentationScope(instrumentationScopeInfo) + .hasBody("log message 1") + .hasTotalAttributeCount(3) // 3 markers (event.name handled separately) + .hasEventName("MyEventName") + .hasAttributesSatisfying( + equalTo(AttributeKey.stringKey("field1"), "value1"), + equalTo(AttributeKey.longKey("field2"), 2L), + equalTo(AttributeKey.stringKey("field3"), "value3"))); + } + + @Test + void logstashVariousValues() { + Map entries = new HashMap<>(); + entries.put("map1", 1); + entries.put("map2", 2.0); + entries.put("map3", "text-5"); + entries.put("map4", null); + + logger + .atInfo() + .setMessage("log message 1") + .addMarker(Markers.append("field1", 1)) + .addMarker(Markers.append("field2", 2.0)) + .addMarker(Markers.append("field3", "text-1")) + .addMarker(Markers.append("field4", true)) + .addMarker(Markers.append("field5", new Integer[] {1, null, 2, 3})) + .addMarker(Markers.append("field6", new double[] {1.0, 2.0, 3.0})) + .addMarker(Markers.append("field7", new String[] {"text-2", "text-3", "text-4", null})) + .addMarker(Markers.append("field8", new Boolean[] {true, false, true})) + .addMarker(Markers.appendArray("field9", 1, 2.0, true, "text")) + .addMarker(Markers.appendRaw("field10", "raw value")) + .addMarker(Markers.append("field11", Arrays.asList(1, 2, 3))) + .addMarker(Markers.appendEntries(entries)) + .log(); + + testing.waitAndAssertLogRecords( + logRecord -> + logRecord + .hasResource(resource) + .hasInstrumentationScope(instrumentationScopeInfo) + .hasBody("log message 1") + // 14 fields (including map keys) + .hasTotalAttributeCount(14) + .hasAttributesSatisfying( + equalTo(AttributeKey.longKey("field1"), 1L), + equalTo(AttributeKey.doubleKey("field2"), 2.0), + equalTo(AttributeKey.stringKey("field3"), "text-1"), + equalTo(AttributeKey.booleanKey("field4"), true), + equalTo(AttributeKey.longArrayKey("field5"), Arrays.asList(1L, 2L, 3L)), + equalTo(AttributeKey.doubleArrayKey("field6"), Arrays.asList(1.0, 2.0, 3.0)), + equalTo( + AttributeKey.stringArrayKey("field7"), + Arrays.asList("text-2", "text-3", "text-4")), + equalTo( + AttributeKey.booleanArrayKey("field8"), Arrays.asList(true, false, true)), + equalTo( + AttributeKey.stringArrayKey("field9"), + Arrays.asList("1", "2.0", "true", "text")), + equalTo(AttributeKey.stringKey("field10"), "raw value"), + equalTo(AttributeKey.stringArrayKey("field11"), Arrays.asList("1", "2", "3")), + equalTo(AttributeKey.longKey("map1"), 1L), + equalTo(AttributeKey.doubleKey("map2"), 2.0), + equalTo(AttributeKey.stringKey("map3"), "text-5"))); + } + + @Test + void logstashEmptyAndNullValues() { + Map noEntries = new HashMap<>(); + + logger + .atInfo() + .setMessage("log message 1") + .addMarker(Markers.appendEntries(noEntries)) + .addMarker(Markers.append("field2", null)) + .addMarker(Markers.append("field3", new int[0])) + .addMarker(Markers.append("field4", new String[0])) + .addMarker(Markers.appendArray("field5")) + .addMarker(Markers.appendArray("field6", (Object) null)) + .addMarker(Markers.appendArray("field7", null, null, null)) + .log(); + + testing.waitAndAssertLogRecords( + logRecord -> + logRecord + .hasResource(resource) + .hasInstrumentationScope(instrumentationScopeInfo) + .hasBody("log message 1") + .hasTotalAttributeCount(0)); + } +} diff --git a/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/resources/logback-test.xml b/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/resources/logback-test.xml new file mode 100644 index 000000000000..ad6a06bf04b1 --- /dev/null +++ b/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/resources/logback-test.xml @@ -0,0 +1,23 @@ + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + true + true + + + + + + + + diff --git a/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java b/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java new file mode 100644 index 000000000000..04f170b06035 --- /dev/null +++ b/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java @@ -0,0 +1,122 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.logback.appender.v1_0; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension; +import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.resources.Resource; +import net.logstash.logback.argument.StructuredArguments; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Tests for Logstash StructuredArguments functionality using net.logstash.logback.argument.StructuredArguments. + * This test suite focuses specifically on testing structured argument logging. + */ +public class LogstashStructuredArgsTest { + private static final Logger logger = LoggerFactory.getLogger("TestLogger"); + + @RegisterExtension + private static final LibraryInstrumentationExtension testing = + LibraryInstrumentationExtension.create(); + + private static Resource resource; + private static InstrumentationScopeInfo instrumentationScopeInfo; + + @BeforeAll + static void setupAll() { + resource = Resource.getDefault(); + instrumentationScopeInfo = InstrumentationScopeInfo.create("TestLogger"); + + // Configuration is handled by logback-test.xml in resources + OpenTelemetryAppender.install(testing.getOpenTelemetry()); + } + + @Test + void basicStructuredArgumentWithV() { + logger.info("Basic structured arg: {}", StructuredArguments.v("customer_id", "123")); + + testing.waitAndAssertLogRecords( + logRecord -> + logRecord + .hasResource(resource) + .hasInstrumentationScope(instrumentationScopeInfo) + .hasBody("Basic structured arg: 123") + .hasAttributesSatisfying( + equalTo(AttributeKey.stringKey("customer_id"), "123"))); + } + + @Test + void structuredArgumentWithKeyValue() { + logger.info("Processing order: {}", StructuredArguments.keyValue("order_id", "ORD-456")); + + testing.waitAndAssertLogRecords( + logRecord -> + logRecord + .hasResource(resource) + .hasInstrumentationScope(instrumentationScopeInfo) + .hasBody("Processing order: order_id=ORD-456") + .hasAttributesSatisfying( + equalTo(AttributeKey.stringKey("order_id"), "ORD-456"))); + } + + @Test + void multipleStructuredArguments() { + logger.info( + "Transaction: {} amount: {}", + StructuredArguments.v("customer_id", "789"), + StructuredArguments.v("amount", 99.99)); + + testing.waitAndAssertLogRecords( + logRecord -> + logRecord + .hasResource(resource) + .hasInstrumentationScope(instrumentationScopeInfo) + .hasBody("Transaction: 789 amount: 99.99") + .hasAttributesSatisfying( + equalTo(AttributeKey.stringKey("customer_id"), "789"), + equalTo(AttributeKey.doubleKey("amount"), 99.99))); + } + + @Test + void structuredArgumentWithEventName() { + logger.info("Event occurred: {}", StructuredArguments.v("event.name", "OrderPlaced")); + + testing.waitAndAssertLogRecords( + logRecord -> + logRecord + .hasResource(resource) + .hasInstrumentationScope(instrumentationScopeInfo) + .hasBody("Event occurred: OrderPlaced") + .hasEventName("OrderPlaced")); + } + + @Test + void structuredArgumentsWithTypedValues() { + long timestamp = System.currentTimeMillis(); + logger.info( + "User logged in: {} at {} with session: {}", + StructuredArguments.v("user_id", 12345), + StructuredArguments.v("timestamp", timestamp), + StructuredArguments.v("session_active", true)); + + testing.waitAndAssertLogRecords( + logRecord -> + logRecord + .hasResource(resource) + .hasInstrumentationScope(instrumentationScopeInfo) + .hasAttributesSatisfying( + equalTo(AttributeKey.longKey("user_id"), 12345L), + equalTo(AttributeKey.longKey("timestamp"), timestamp), + equalTo(AttributeKey.booleanKey("session_active"), true))); + } +} diff --git a/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/resources/logback-test.xml b/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/resources/logback-test.xml new file mode 100644 index 000000000000..9e9211c2f3fe --- /dev/null +++ b/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/resources/logback-test.xml @@ -0,0 +1,23 @@ + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + true + true + + + + + + + + diff --git a/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/Slf4j2Test.java b/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/Slf4j2Test.java index 85781fa6347a..1de6cd8dfd32 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/Slf4j2Test.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/slf4j2ApiTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/Slf4j2Test.java @@ -13,10 +13,6 @@ import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.resources.Resource; import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import net.logstash.logback.argument.StructuredArguments; -import net.logstash.logback.marker.Markers; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -132,223 +128,4 @@ void arguments() { AttributeKey.stringKey("log.body.template"), "log message {} and {}, bool {}, long {}"))); } - - @Test - void logstash() { - Map entries = new HashMap<>(); - entries.put("field2", 2); - entries.put("field3", "value3"); - - logger - .atInfo() - .setMessage("log message 1") - .addMarker(Markers.append("field1", "value1")) - .addMarker(Markers.append("event.name", "MyEventName")) - .addMarker(Markers.appendEntries(entries)) - .log(); - - testing.waitAndAssertLogRecords( - logRecord -> - logRecord - .hasResource(resource) - .hasInstrumentationScope(instrumentationScopeInfo) - .hasBody("log message 1") - .hasTotalAttributeCount(codeAttributesLogCount() + 3) // 3 markers - .hasEventName("MyEventName") - .hasAttributesSatisfying( - equalTo(AttributeKey.stringKey("field1"), "value1"), - equalTo(AttributeKey.longKey("field2"), 2L), - equalTo(AttributeKey.stringKey("field3"), "value3"))); - } - - @Test - void logstashVariousValues() { - Map entries = new HashMap<>(); - entries.put("map1", 1); - entries.put("map2", 2.0); - entries.put("map3", "text-5"); - entries.put("map4", null); - - logger - .atInfo() - .setMessage("log message 1") - .addMarker(Markers.append("field1", 1)) - .addMarker(Markers.append("field2", 2.0)) - .addMarker(Markers.append("field3", "text-1")) - .addMarker(Markers.append("field4", true)) - .addMarker(Markers.append("field5", new Integer[] {1, null, 2, 3})) - .addMarker(Markers.append("field6", new double[] {1.0, 2.0, 3.0})) - .addMarker(Markers.append("field7", new String[] {"text-2", "text-3", "text-4", null})) - .addMarker(Markers.append("field8", new Boolean[] {true, false, true})) - .addMarker(Markers.appendArray("field9", 1, 2.0, true, "text")) - .addMarker(Markers.appendRaw("field10", "raw value")) - .addMarker(Markers.append("field11", Arrays.asList(1, 2, 3))) - .addMarker(Markers.appendEntries(entries)) - .log(); - - testing.waitAndAssertLogRecords( - logRecord -> - logRecord - .hasResource(resource) - .hasInstrumentationScope(instrumentationScopeInfo) - .hasBody("log message 1") - // 14 fields (including map keys) - .hasTotalAttributeCount(codeAttributesLogCount() + 14) - .hasAttributesSatisfying( - equalTo(AttributeKey.longKey("field1"), 1L), - equalTo(AttributeKey.doubleKey("field2"), 2.0), - equalTo(AttributeKey.stringKey("field3"), "text-1"), - equalTo(AttributeKey.booleanKey("field4"), true), - equalTo(AttributeKey.longArrayKey("field5"), Arrays.asList(1L, 2L, 3L)), - equalTo(AttributeKey.doubleArrayKey("field6"), Arrays.asList(1.0, 2.0, 3.0)), - equalTo( - AttributeKey.stringArrayKey("field7"), - Arrays.asList("text-2", "text-3", "text-4")), - equalTo( - AttributeKey.booleanArrayKey("field8"), Arrays.asList(true, false, true)), - equalTo( - AttributeKey.stringArrayKey("field9"), - Arrays.asList("1", "2.0", "true", "text")), - equalTo(AttributeKey.stringKey("field10"), "raw value"), - equalTo(AttributeKey.stringArrayKey("field11"), Arrays.asList("1", "2", "3")), - equalTo(AttributeKey.longKey("map1"), 1L), - equalTo(AttributeKey.doubleKey("map2"), 2.0), - equalTo(AttributeKey.stringKey("map3"), "text-5"))); - } - - @Test - void logstashEmptyAndNullValues() { - Map noEntries = new HashMap<>(); - - logger - .atInfo() - .setMessage("log message 1") - .addMarker(Markers.appendEntries(noEntries)) - .addMarker(Markers.append("field2", null)) - .addMarker(Markers.append("field3", new int[0])) - .addMarker(Markers.append("field4", new String[0])) - .addMarker(Markers.appendArray("field5")) - .addMarker(Markers.appendArray("field6", (Object) null)) - .addMarker(Markers.appendArray("field7", null, null, null)) - .log(); - - testing.waitAndAssertLogRecords( - logRecord -> - logRecord - .hasResource(resource) - .hasInstrumentationScope(instrumentationScopeInfo) - .hasBody("log message 1") - .hasTotalAttributeCount(codeAttributesLogCount())); - } - - @Test - void structuredArgumentsWithV() { - logger.warn( - "This is a warning log for customerId: {}", StructuredArguments.v("customer_id", "123")); - - testing.waitAndAssertLogRecords( - logRecord -> - logRecord - .hasResource(resource) - .hasInstrumentationScope(instrumentationScopeInfo) - .hasBody("This is a warning log for customerId: 123") - .hasTotalAttributeCount(codeAttributesLogCount() + 3) - .hasAttributesSatisfying( - equalTo(AttributeKey.stringKey("customer_id"), "123"), - equalTo( - AttributeKey.stringKey("log.body.template"), - "This is a warning log for customerId: {}"), - equalTo( - AttributeKey.stringArrayKey("log.body.parameters"), Arrays.asList("123")))); - } - - @Test - void structuredArgumentsWithKeyValue() { - logger.info("Processing order: {}", StructuredArguments.keyValue("order_id", "ORD-456")); - - testing.waitAndAssertLogRecords( - logRecord -> - logRecord - .hasResource(resource) - .hasInstrumentationScope(instrumentationScopeInfo) - .hasBody("Processing order: order_id=ORD-456") - .hasTotalAttributeCount(codeAttributesLogCount() + 3) - .hasAttributesSatisfying( - equalTo(AttributeKey.stringKey("order_id"), "ORD-456"), - equalTo(AttributeKey.stringKey("log.body.template"), "Processing order: {}"), - equalTo( - AttributeKey.stringArrayKey("log.body.parameters"), - Arrays.asList("order_id=ORD-456")))); - } - - @Test - void structuredArgumentsMultiple() { - logger.warn( - "Transaction failed for customer: {} with amount: {}", - StructuredArguments.v("customer_id", "789"), - StructuredArguments.v("amount", 99.99)); - - testing.waitAndAssertLogRecords( - logRecord -> - logRecord - .hasResource(resource) - .hasInstrumentationScope(instrumentationScopeInfo) - .hasBody("Transaction failed for customer: 789 with amount: 99.99") - .hasTotalAttributeCount(codeAttributesLogCount() + 4) - .hasAttributesSatisfying( - equalTo(AttributeKey.stringKey("customer_id"), "789"), - equalTo(AttributeKey.doubleKey("amount"), 99.99), - equalTo( - AttributeKey.stringKey("log.body.template"), - "Transaction failed for customer: {} with amount: {}"), - equalTo( - AttributeKey.stringArrayKey("log.body.parameters"), - Arrays.asList("789", "99.99")))); - } - - @Test - void structuredArgumentsWithEventName() { - logger.info("Event occurred: {}", StructuredArguments.v("event.name", "OrderPlaced")); - - testing.waitAndAssertLogRecords( - logRecord -> - logRecord - .hasResource(resource) - .hasInstrumentationScope(instrumentationScopeInfo) - .hasBody("Event occurred: OrderPlaced") - .hasEventName("OrderPlaced") - .hasTotalAttributeCount(codeAttributesLogCount() + 2) - .hasAttributesSatisfying( - equalTo(AttributeKey.stringKey("log.body.template"), "Event occurred: {}"), - equalTo( - AttributeKey.stringArrayKey("log.body.parameters"), - Arrays.asList("OrderPlaced")))); - } - - @Test - void structuredArgumentsWithTypedValues() { - long timestamp = System.currentTimeMillis(); - logger.info( - "User logged in: {} at {} with session: {}", - StructuredArguments.v("user_id", 12345), - StructuredArguments.v("timestamp", timestamp), - StructuredArguments.v("session_active", true)); - - testing.waitAndAssertLogRecords( - logRecord -> - logRecord - .hasResource(resource) - .hasInstrumentationScope(instrumentationScopeInfo) - .hasTotalAttributeCount(codeAttributesLogCount() + 5) - .hasAttributesSatisfying( - equalTo(AttributeKey.longKey("user_id"), 12345L), - equalTo(AttributeKey.longKey("timestamp"), timestamp), - equalTo(AttributeKey.booleanKey("session_active"), true), - equalTo( - AttributeKey.stringKey("log.body.template"), - "User logged in: {} at {} with session: {}"), - equalTo( - AttributeKey.stringArrayKey("log.body.parameters"), - Arrays.asList("12345", String.valueOf(timestamp), "true")))); - } } From 3c54b6edecdd7e24a0f3106a71f6d1e9d8e97a17 Mon Sep 17 00:00:00 2001 From: otelbot <197425009+otelbot@users.noreply.github.com> Date: Sun, 12 Oct 2025 18:55:23 +0000 Subject: [PATCH 09/18] ./gradlew spotlessApply --- .../logback/appender/v1_0/LogstashMarkerTest.java | 4 ++-- .../appender/v1_0/LogstashStructuredArgsTest.java | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java b/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java index 2fe9f9fc6ba4..a40368aa5d60 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java @@ -22,8 +22,8 @@ import org.slf4j.LoggerFactory; /** - * Tests for Logstash Marker functionality using net.logstash.logback.marker.Markers. - * This test suite focuses specifically on testing marker-based structured logging. + * Tests for Logstash Marker functionality using net.logstash.logback.marker.Markers. This test + * suite focuses specifically on testing marker-based structured logging. */ public class LogstashMarkerTest { private static final Logger logger = LoggerFactory.getLogger("TestLogger"); diff --git a/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java b/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java index 04f170b06035..730cfad14c4d 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java @@ -19,8 +19,9 @@ import org.slf4j.LoggerFactory; /** - * Tests for Logstash StructuredArguments functionality using net.logstash.logback.argument.StructuredArguments. - * This test suite focuses specifically on testing structured argument logging. + * Tests for Logstash StructuredArguments functionality using + * net.logstash.logback.argument.StructuredArguments. This test suite focuses specifically on + * testing structured argument logging. */ public class LogstashStructuredArgsTest { private static final Logger logger = LoggerFactory.getLogger("TestLogger"); @@ -51,8 +52,7 @@ void basicStructuredArgumentWithV() { .hasResource(resource) .hasInstrumentationScope(instrumentationScopeInfo) .hasBody("Basic structured arg: 123") - .hasAttributesSatisfying( - equalTo(AttributeKey.stringKey("customer_id"), "123"))); + .hasAttributesSatisfying(equalTo(AttributeKey.stringKey("customer_id"), "123"))); } @Test @@ -65,8 +65,7 @@ void structuredArgumentWithKeyValue() { .hasResource(resource) .hasInstrumentationScope(instrumentationScopeInfo) .hasBody("Processing order: order_id=ORD-456") - .hasAttributesSatisfying( - equalTo(AttributeKey.stringKey("order_id"), "ORD-456"))); + .hasAttributesSatisfying(equalTo(AttributeKey.stringKey("order_id"), "ORD-456"))); } @Test From bc58d378f1efa2281f2ea6cb8493ecb0f833ba04 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sun, 12 Oct 2025 12:50:57 -0700 Subject: [PATCH 10/18] up --- .../logback/appender/v1_0/LogstashMarkerTest.java | 4 ---- .../logback/appender/v1_0/LogstashStructuredArgsTest.java | 5 ----- 2 files changed, 9 deletions(-) diff --git a/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java b/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java index a40368aa5d60..1004e1154c6c 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java @@ -21,10 +21,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** - * Tests for Logstash Marker functionality using net.logstash.logback.marker.Markers. This test - * suite focuses specifically on testing marker-based structured logging. - */ public class LogstashMarkerTest { private static final Logger logger = LoggerFactory.getLogger("TestLogger"); diff --git a/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java b/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java index 730cfad14c4d..45603d32b79d 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java @@ -18,11 +18,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** - * Tests for Logstash StructuredArguments functionality using - * net.logstash.logback.argument.StructuredArguments. This test suite focuses specifically on - * testing structured argument logging. - */ public class LogstashStructuredArgsTest { private static final Logger logger = LoggerFactory.getLogger("TestLogger"); From 23c2f6d690240856065fff3e5eb38b560f143199 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sun, 12 Oct 2025 13:19:44 -0700 Subject: [PATCH 11/18] up --- .../appender/v1_0/LogstashMarkerTest.java | 1 - .../v1_0/LogstashStructuredArgsTest.java | 1 - .../appender/v1_0/OpenTelemetryAppender.java | 18 ++++-------------- .../v1_0/internal/LoggingEventMapper.java | 4 ++-- .../internal/DeprecatedConfigProperties.java | 2 +- .../internal/DeprecatedConfigProperties.java | 2 +- 6 files changed, 8 insertions(+), 20 deletions(-) diff --git a/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java b/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java index 1004e1154c6c..6681c095199b 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java @@ -36,7 +36,6 @@ static void setupAll() { resource = Resource.getDefault(); instrumentationScopeInfo = InstrumentationScopeInfo.create("TestLogger"); - // Configuration is handled by logback-test.xml in resources OpenTelemetryAppender.install(testing.getOpenTelemetry()); } diff --git a/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java b/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java index 45603d32b79d..df9a06c54e9e 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java @@ -33,7 +33,6 @@ static void setupAll() { resource = Resource.getDefault(); instrumentationScopeInfo = InstrumentationScopeInfo.create("TestLogger"); - // Configuration is handled by logback-test.xml in resources OpenTelemetryAppender.install(testing.getOpenTelemetry()); } diff --git a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java index 6286c0be8bf7..3bd21953efdf 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java @@ -190,30 +190,20 @@ public void setCaptureArguments(boolean captureArguments) { * Sets whether the Logstash attributes should be set to logs. * * @param captureLogstashAttributes To enable or disable capturing Logstash attributes - * @deprecated Use {@link #setCaptureLogstashStructuredArguments(boolean)} instead. This method is + * @deprecated Use {@link #setCaptureLogstashMarkerAttributes(boolean)} instead. This method is * deprecated and will be removed in a future release. */ @Deprecated public void setCaptureLogstashAttributes(boolean captureLogstashAttributes) { - setCaptureLogstashStructuredArguments(captureLogstashAttributes); + setCaptureLogstashMarkerAttributes(captureLogstashAttributes); } - /** - * Sets whether the Logstash marker attributes should be set to logs. - * - * @param captureLogstashMarkerAttributes To enable or disable capturing Logstash marker - * attributes - */ + /** Sets whether the Logstash marker attributes should be captured. */ public void setCaptureLogstashMarkerAttributes(boolean captureLogstashMarkerAttributes) { this.captureLogstashMarkerAttributes = captureLogstashMarkerAttributes; } - /** - * Sets whether the Logstash StructuredArguments should be captured as attributes. - * - * @param captureLogstashStructuredArguments To enable or disable capturing Logstash - * StructuredArguments - */ + /** Sets whether the Logstash StructuredArguments should be captured. */ public void setCaptureLogstashStructuredArguments(boolean captureLogstashStructuredArguments) { this.captureLogstashStructuredArguments = captureLogstashStructuredArguments; } diff --git a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java index 4090cfb4fcbc..a447ff862618 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java @@ -736,13 +736,13 @@ public Builder setCaptureArguments(boolean captureArguments) { } /** - * @deprecated Use {@link #setCaptureLogstashStructuredArguments(boolean)} instead. This method + * @deprecated Use {@link #setCaptureLogstashMarkerAttributes(boolean)} instead. This method * is deprecated and will be removed in a future release. */ @Deprecated @CanIgnoreReturnValue public Builder setCaptureLogstashAttributes(boolean captureLogstashAttributes) { - return setCaptureLogstashStructuredArguments(captureLogstashAttributes); + return setCaptureLogstashMarkerAttributes(captureLogstashAttributes); } @CanIgnoreReturnValue diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java index a6cd481fc184..1e161621b34d 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java @@ -14,7 +14,7 @@ * This class is internal and is hence not for public use. Its APIs are unstable and can change at * any time. */ -@SuppressWarnings("unused") +@SuppressWarnings("unused") // keep around for next time even if not currently used public final class DeprecatedConfigProperties { private static final Logger logger = Logger.getLogger(DeprecatedConfigProperties.class.getName()); diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/DeprecatedConfigProperties.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/DeprecatedConfigProperties.java index 2709a6ab0ea2..d81ccbb96116 100644 --- a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/DeprecatedConfigProperties.java +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/DeprecatedConfigProperties.java @@ -16,7 +16,7 @@ * This class is internal and is hence not for public use. Its APIs are unstable and can change at * any time. */ -@SuppressWarnings("unused") +@SuppressWarnings("unused") // keep around for next time even if not currently used public final class DeprecatedConfigProperties { private static final Logger logger = Logger.getLogger(DeprecatedConfigProperties.class.getName()); From 4ebc2171670e8e8c9b0d2d1f4e7459993930e219 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sun, 12 Oct 2025 13:42:20 -0700 Subject: [PATCH 12/18] sync --- .../internal/DeprecatedConfigProperties.java | 29 ++++++------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java index 1e161621b34d..4668d792d8b6 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java @@ -19,30 +19,19 @@ public final class DeprecatedConfigProperties { private static final Logger logger = Logger.getLogger(DeprecatedConfigProperties.class.getName()); - public static Boolean getBoolean( - ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent, + public static boolean getBoolean( + InstrumentationConfig config, String deprecatedPropertyName, - String newPropertyName) { - warnIfUsed(applicationEnvironmentPreparedEvent, deprecatedPropertyName, newPropertyName); - Boolean deprecatedValue = - applicationEnvironmentPreparedEvent - .getEnvironment() - .getProperty(deprecatedPropertyName, Boolean.class); - Boolean newValue = - applicationEnvironmentPreparedEvent - .getEnvironment() - .getProperty(newPropertyName, Boolean.class); - - // Return the new value if it exists, otherwise return the deprecated value - return newValue != null ? newValue : deprecatedValue; + String newPropertyName, + boolean defaultValue) { + warnIfUsed(config, deprecatedPropertyName, newPropertyName); + boolean value = config.getBoolean(deprecatedPropertyName, defaultValue); + return config.getBoolean(newPropertyName, value); } private static void warnIfUsed( - ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent, - String deprecatedPropertyName, - String newPropertyName) { - if (applicationEnvironmentPreparedEvent.getEnvironment().getProperty(deprecatedPropertyName) - != null) { + InstrumentationConfig config, String deprecatedPropertyName, String newPropertyName) { + if (config.getString(deprecatedPropertyName) != null) { logger.log( WARNING, "Deprecated property \"{0}\" was used; use the \"{1}\" property instead", From b69a47d7166864b26793d2085a2f2cfb5c47a10d Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sun, 12 Oct 2025 13:47:43 -0700 Subject: [PATCH 13/18] simple --- .../appender/v1_0/LogstashMarkerTest.java | 14 -------------- .../v1_0/LogstashStructuredArgsTest.java | 18 ------------------ 2 files changed, 32 deletions(-) diff --git a/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java b/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java index 6681c095199b..b88cebcecf55 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java @@ -9,8 +9,6 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension; -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.resources.Resource; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -28,14 +26,8 @@ public class LogstashMarkerTest { private static final LibraryInstrumentationExtension testing = LibraryInstrumentationExtension.create(); - private static Resource resource; - private static InstrumentationScopeInfo instrumentationScopeInfo; - @BeforeAll static void setupAll() { - resource = Resource.getDefault(); - instrumentationScopeInfo = InstrumentationScopeInfo.create("TestLogger"); - OpenTelemetryAppender.install(testing.getOpenTelemetry()); } @@ -56,8 +48,6 @@ void logstash() { testing.waitAndAssertLogRecords( logRecord -> logRecord - .hasResource(resource) - .hasInstrumentationScope(instrumentationScopeInfo) .hasBody("log message 1") .hasTotalAttributeCount(3) // 3 markers (event.name handled separately) .hasEventName("MyEventName") @@ -95,8 +85,6 @@ void logstashVariousValues() { testing.waitAndAssertLogRecords( logRecord -> logRecord - .hasResource(resource) - .hasInstrumentationScope(instrumentationScopeInfo) .hasBody("log message 1") // 14 fields (including map keys) .hasTotalAttributeCount(14) @@ -141,8 +129,6 @@ void logstashEmptyAndNullValues() { testing.waitAndAssertLogRecords( logRecord -> logRecord - .hasResource(resource) - .hasInstrumentationScope(instrumentationScopeInfo) .hasBody("log message 1") .hasTotalAttributeCount(0)); } diff --git a/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java b/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java index df9a06c54e9e..4c5bb7caad86 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java @@ -9,8 +9,6 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension; -import io.opentelemetry.sdk.common.InstrumentationScopeInfo; -import io.opentelemetry.sdk.resources.Resource; import net.logstash.logback.argument.StructuredArguments; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -25,14 +23,8 @@ public class LogstashStructuredArgsTest { private static final LibraryInstrumentationExtension testing = LibraryInstrumentationExtension.create(); - private static Resource resource; - private static InstrumentationScopeInfo instrumentationScopeInfo; - @BeforeAll static void setupAll() { - resource = Resource.getDefault(); - instrumentationScopeInfo = InstrumentationScopeInfo.create("TestLogger"); - OpenTelemetryAppender.install(testing.getOpenTelemetry()); } @@ -43,8 +35,6 @@ void basicStructuredArgumentWithV() { testing.waitAndAssertLogRecords( logRecord -> logRecord - .hasResource(resource) - .hasInstrumentationScope(instrumentationScopeInfo) .hasBody("Basic structured arg: 123") .hasAttributesSatisfying(equalTo(AttributeKey.stringKey("customer_id"), "123"))); } @@ -56,8 +46,6 @@ void structuredArgumentWithKeyValue() { testing.waitAndAssertLogRecords( logRecord -> logRecord - .hasResource(resource) - .hasInstrumentationScope(instrumentationScopeInfo) .hasBody("Processing order: order_id=ORD-456") .hasAttributesSatisfying(equalTo(AttributeKey.stringKey("order_id"), "ORD-456"))); } @@ -72,8 +60,6 @@ void multipleStructuredArguments() { testing.waitAndAssertLogRecords( logRecord -> logRecord - .hasResource(resource) - .hasInstrumentationScope(instrumentationScopeInfo) .hasBody("Transaction: 789 amount: 99.99") .hasAttributesSatisfying( equalTo(AttributeKey.stringKey("customer_id"), "789"), @@ -87,8 +73,6 @@ void structuredArgumentWithEventName() { testing.waitAndAssertLogRecords( logRecord -> logRecord - .hasResource(resource) - .hasInstrumentationScope(instrumentationScopeInfo) .hasBody("Event occurred: OrderPlaced") .hasEventName("OrderPlaced")); } @@ -105,8 +89,6 @@ void structuredArgumentsWithTypedValues() { testing.waitAndAssertLogRecords( logRecord -> logRecord - .hasResource(resource) - .hasInstrumentationScope(instrumentationScopeInfo) .hasAttributesSatisfying( equalTo(AttributeKey.longKey("user_id"), 12345L), equalTo(AttributeKey.longKey("timestamp"), timestamp), From 08a16d65801750e9a0e44f7dc7c4a43da4dec788 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sun, 12 Oct 2025 14:32:06 -0700 Subject: [PATCH 14/18] spotless --- .../logback/appender/v1_0/LogstashMarkerTest.java | 5 +---- .../appender/v1_0/LogstashStructuredArgsTest.java | 14 +++++--------- .../appender/v1_0/internal/LoggingEventMapper.java | 4 ++-- .../internal/DeprecatedConfigProperties.java | 1 - 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java b/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java index b88cebcecf55..f0db940fcb01 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java @@ -127,9 +127,6 @@ void logstashEmptyAndNullValues() { .log(); testing.waitAndAssertLogRecords( - logRecord -> - logRecord - .hasBody("log message 1") - .hasTotalAttributeCount(0)); + logRecord -> logRecord.hasBody("log message 1").hasTotalAttributeCount(0)); } } diff --git a/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java b/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java index 4c5bb7caad86..147f411ccf64 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java @@ -71,10 +71,7 @@ void structuredArgumentWithEventName() { logger.info("Event occurred: {}", StructuredArguments.v("event.name", "OrderPlaced")); testing.waitAndAssertLogRecords( - logRecord -> - logRecord - .hasBody("Event occurred: OrderPlaced") - .hasEventName("OrderPlaced")); + logRecord -> logRecord.hasBody("Event occurred: OrderPlaced").hasEventName("OrderPlaced")); } @Test @@ -88,10 +85,9 @@ void structuredArgumentsWithTypedValues() { testing.waitAndAssertLogRecords( logRecord -> - logRecord - .hasAttributesSatisfying( - equalTo(AttributeKey.longKey("user_id"), 12345L), - equalTo(AttributeKey.longKey("timestamp"), timestamp), - equalTo(AttributeKey.booleanKey("session_active"), true))); + logRecord.hasAttributesSatisfying( + equalTo(AttributeKey.longKey("user_id"), 12345L), + equalTo(AttributeKey.longKey("timestamp"), timestamp), + equalTo(AttributeKey.booleanKey("session_active"), true))); } } diff --git a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java index a447ff862618..fbb74ff559ca 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java @@ -736,8 +736,8 @@ public Builder setCaptureArguments(boolean captureArguments) { } /** - * @deprecated Use {@link #setCaptureLogstashMarkerAttributes(boolean)} instead. This method - * is deprecated and will be removed in a future release. + * @deprecated Use {@link #setCaptureLogstashMarkerAttributes(boolean)} instead. This method is + * deprecated and will be removed in a future release. */ @Deprecated @CanIgnoreReturnValue diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java index 4668d792d8b6..577371ea33cf 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java @@ -8,7 +8,6 @@ import static java.util.logging.Level.WARNING; import java.util.logging.Logger; -import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at From 4b770a0e7dbbbf2d1f69a55cc7cc85d1c637a83d Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sun, 12 Oct 2025 14:38:07 -0700 Subject: [PATCH 15/18] fix --- .../internal/DeprecatedConfigProperties.java | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java index 577371ea33cf..6eb2ce5bfe3f 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/DeprecatedConfigProperties.java @@ -8,6 +8,7 @@ import static java.util.logging.Level.WARNING; import java.util.logging.Logger; +import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at @@ -18,19 +19,24 @@ public final class DeprecatedConfigProperties { private static final Logger logger = Logger.getLogger(DeprecatedConfigProperties.class.getName()); - public static boolean getBoolean( - InstrumentationConfig config, + public static Boolean getBoolean( + ApplicationEnvironmentPreparedEvent event, String deprecatedPropertyName, - String newPropertyName, - boolean defaultValue) { - warnIfUsed(config, deprecatedPropertyName, newPropertyName); - boolean value = config.getBoolean(deprecatedPropertyName, defaultValue); - return config.getBoolean(newPropertyName, value); + String newPropertyName) { + warnIfUsed(event, deprecatedPropertyName, newPropertyName); + Boolean value = event.getEnvironment().getProperty(deprecatedPropertyName, Boolean.class); + if (value != null) { + return value; + } + return event.getEnvironment().getProperty(newPropertyName, Boolean.class); } private static void warnIfUsed( - InstrumentationConfig config, String deprecatedPropertyName, String newPropertyName) { - if (config.getString(deprecatedPropertyName) != null) { + ApplicationEnvironmentPreparedEvent event, + String deprecatedPropertyName, + String newPropertyName) { + String value = event.getEnvironment().getProperty(deprecatedPropertyName, String.class); + if (value != null) { logger.log( WARNING, "Deprecated property \"{0}\" was used; use the \"{1}\" property instead", From cda71d4d37c40617f7da9941a77c45c7014b81dd Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 13 Oct 2025 12:22:59 -0700 Subject: [PATCH 16/18] Update instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java Co-authored-by: Lauri Tulmin --- .../logback/appender/v1_0/LogstashMarkerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java b/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java index f0db940fcb01..2533866517ff 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/logstashMarkerTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashMarkerTest.java @@ -19,7 +19,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class LogstashMarkerTest { +class LogstashMarkerTest { private static final Logger logger = LoggerFactory.getLogger("TestLogger"); @RegisterExtension From 94953614af047eade78f790a520800111dc910b2 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 13 Oct 2025 12:23:10 -0700 Subject: [PATCH 17/18] Update instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java Co-authored-by: Lauri Tulmin --- .../logback/appender/v1_0/LogstashStructuredArgsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java b/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java index 147f411ccf64..89359af9f722 100644 --- a/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java +++ b/instrumentation/logback/logback-appender-1.0/library/src/logstashStructuredArgsTest/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogstashStructuredArgsTest.java @@ -16,7 +16,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class LogstashStructuredArgsTest { +class LogstashStructuredArgsTest { private static final Logger logger = LoggerFactory.getLogger("TestLogger"); @RegisterExtension From aad7ecb12e8e373c66d7efa5f24ad7957a9e6d84 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 13 Oct 2025 12:25:43 -0700 Subject: [PATCH 18/18] align columns --- .../logback-appender-1.0/javaagent/README.md | 22 ++++++++--------- .../logback-appender-1.0/library/README.md | 24 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/instrumentation/logback/logback-appender-1.0/javaagent/README.md b/instrumentation/logback/logback-appender-1.0/javaagent/README.md index 8ad17030a717..f683752c90af 100644 --- a/instrumentation/logback/logback-appender-1.0/javaagent/README.md +++ b/instrumentation/logback/logback-appender-1.0/javaagent/README.md @@ -1,16 +1,16 @@ # Settings for the Logback Appender instrumentation -| System property | Type | Default | Description | -|----------------------------------------------------------------------------------------|---------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `otel.instrumentation.logback-appender.experimental-log-attributes` | Boolean | `false` | Enable the capture of experimental log attributes `thread.name` and `thread.id`. | -| `otel.instrumentation.logback-appender.experimental.capture-code-attributes` | Boolean | `false` | Enable the capture of [source code attributes]. Note that capturing source code attributes at logging sites might add a performance overhead. | -| `otel.instrumentation.logback-appender.experimental.capture-marker-attribute` | Boolean | `false` | Enable the capture of Logback markers as attributes. | -| `otel.instrumentation.logback-appender.experimental.capture-key-value-pair-attributes` | Boolean | `false` | Enable the capture of Logback key value pairs as attributes. | -| `otel.instrumentation.logback-appender.experimental.capture-logger-context-attributes` | Boolean | `false` | Enable the capture of Logback logger context properties as attributes. | -| `otel.instrumentation.logback-appender.experimental.capture-arguments` | Boolean | `false` | Enable the capture of Logback logger arguments. | -| `otel.instrumentation.logback-appender.experimental.capture-logstash-marker-attributes` | Boolean | `false` | Enable the capture of Logstash markers, supported are those added to logs via `Markers.append()`, `Markers.appendEntries()`, `Markers.appendArray()` and `Markers.appendRaw()` methods. | +| System property | Type | Default | Description | +|--------------------------------------------------------------------------------------------|---------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `otel.instrumentation.logback-appender.experimental-log-attributes` | Boolean | `false` | Enable the capture of experimental log attributes `thread.name` and `thread.id`. | +| `otel.instrumentation.logback-appender.experimental.capture-code-attributes` | Boolean | `false` | Enable the capture of [source code attributes]. Note that capturing source code attributes at logging sites might add a performance overhead. | +| `otel.instrumentation.logback-appender.experimental.capture-marker-attribute` | Boolean | `false` | Enable the capture of Logback markers as attributes. | +| `otel.instrumentation.logback-appender.experimental.capture-key-value-pair-attributes` | Boolean | `false` | Enable the capture of Logback key value pairs as attributes. | +| `otel.instrumentation.logback-appender.experimental.capture-logger-context-attributes` | Boolean | `false` | Enable the capture of Logback logger context properties as attributes. | +| `otel.instrumentation.logback-appender.experimental.capture-arguments` | Boolean | `false` | Enable the capture of Logback logger arguments. | +| `otel.instrumentation.logback-appender.experimental.capture-logstash-marker-attributes` | Boolean | `false` | Enable the capture of Logstash markers, supported are those added to logs via `Markers.append()`, `Markers.appendEntries()`, `Markers.appendArray()` and `Markers.appendRaw()` methods. | | `otel.instrumentation.logback-appender.experimental.capture-logstash-structured-arguments` | Boolean | `false` | Enable the capture of Logstash StructuredArguments as attributes (e.g., `StructuredArguments.v()` and `StructuredArguments.keyValue()`). | -| `otel.instrumentation.logback-appender.experimental.capture-mdc-attributes` | String | | Comma separated list of MDC attributes to capture. Use the wildcard character `*` to capture all attributes. | -| `otel.instrumentation.logback-appender.experimental.capture-event-name` | Boolean | `false` | Enable moving the `event.name` attribute (captured by one of the other mechanisms of capturing attributes) to the log event name. | +| `otel.instrumentation.logback-appender.experimental.capture-mdc-attributes` | String | | Comma separated list of MDC attributes to capture. Use the wildcard character `*` to capture all attributes. | +| `otel.instrumentation.logback-appender.experimental.capture-event-name` | Boolean | `false` | Enable moving the `event.name` attribute (captured by one of the other mechanisms of capturing attributes) to the log event name. | [source code attributes]: https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/attributes.md#source-code-attributes diff --git a/instrumentation/logback/logback-appender-1.0/library/README.md b/instrumentation/logback/logback-appender-1.0/library/README.md index d0fd3813d538..8f91c76f624a 100644 --- a/instrumentation/logback/logback-appender-1.0/library/README.md +++ b/instrumentation/logback/logback-appender-1.0/library/README.md @@ -93,19 +93,19 @@ Settings can be configured in `logback.xml`, for example: The available settings are: -| XML Element | Type | Default | Description | -|------------------------------------|---------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `captureExperimentalAttributes` | Boolean | `false` | Enable the capture of experimental log attributes `thread.name` and `thread.id`. | -| `captureCodeAttributes` | Boolean | `false` | Enable the capture of [source code attributes]. Note that capturing source code attributes at logging sites might add a performance overhead. | -| `captureMarkerAttribute` | Boolean | `false` | Enable the capture of Logback markers as attributes. | -| `captureKeyValuePairAttributes` | Boolean | `false` | Enable the capture of Logback key value pairs as attributes. | -| `captureLoggerContext` | Boolean | `false` | Enable the capture of Logback logger context properties as attributes. | -| `captureArguments` | Boolean | `false` | Enable the capture of Logback logger arguments. | -| `captureLogstashMarkerAttributes` | Boolean | `false` | Enable the capture of Logstash markers, supported are those added to logs via `Markers.append()`, `Markers.appendEntries()`, `Markers.appendArray()` and `Markers.appendRaw()` methods. | +| XML Element | Type | Default | Description | +|--------------------------------------|---------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `captureExperimentalAttributes` | Boolean | `false` | Enable the capture of experimental log attributes `thread.name` and `thread.id`. | +| `captureCodeAttributes` | Boolean | `false` | Enable the capture of [source code attributes]. Note that capturing source code attributes at logging sites might add a performance overhead. | +| `captureMarkerAttribute` | Boolean | `false` | Enable the capture of Logback markers as attributes. | +| `captureKeyValuePairAttributes` | Boolean | `false` | Enable the capture of Logback key value pairs as attributes. | +| `captureLoggerContext` | Boolean | `false` | Enable the capture of Logback logger context properties as attributes. | +| `captureArguments` | Boolean | `false` | Enable the capture of Logback logger arguments. | +| `captureLogstashMarkerAttributes` | Boolean | `false` | Enable the capture of Logstash markers, supported are those added to logs via `Markers.append()`, `Markers.appendEntries()`, `Markers.appendArray()` and `Markers.appendRaw()` methods. | | `captureLogstashStructuredArguments` | Boolean | `false` | Enable the capture of Logstash StructuredArguments as attributes (e.g., `StructuredArguments.v()` and `StructuredArguments.keyValue()`). | -| `captureMdcAttributes` | String | | Comma separated list of MDC attributes to capture. Use the wildcard character `*` to capture all attributes. | -| `captureEventName` | Boolean | `false` | Enable moving the `event.name` attribute (captured by one of the other mechanisms of capturing attributes) to the log event name. | -| `numLogsCapturedBeforeOtelInstall` | Integer | 1000 | Log telemetry is emitted after the initialization of the OpenTelemetry Logback appender with an OpenTelemetry object. This setting allows you to modify the size of the cache used to replay the first logs. thread.id attribute is not captured. | +| `captureMdcAttributes` | String | | Comma separated list of MDC attributes to capture. Use the wildcard character `*` to capture all attributes. | +| `captureEventName` | Boolean | `false` | Enable moving the `event.name` attribute (captured by one of the other mechanisms of capturing attributes) to the log event name. | +| `numLogsCapturedBeforeOtelInstall` | Integer | 1000 | Log telemetry is emitted after the initialization of the OpenTelemetry Logback appender with an OpenTelemetry object. This setting allows you to modify the size of the cache used to replay the first logs. thread.id attribute is not captured. | [source code attributes]: https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/attributes.md#source-code-attributes