Add option to capture logback key value pairs (#8074)

Resolves
https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/8059
This commit is contained in:
Lauri Tulmin 2023-04-03 21:30:04 +03:00 committed by GitHub
parent b01996e12f
commit 1393604118
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 287 additions and 29 deletions

View File

@ -5,6 +5,7 @@
| `otel.instrumentation.logback-appender.experimental-log-attributes` | Boolean | `false` | Enable the capture of experimental span attributes `thread.name` and `thread.id`. | | `otel.instrumentation.logback-appender.experimental-log-attributes` | Boolean | `false` | Enable the capture of experimental span 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-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-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-mdc-attributes` | String | | List of MDC attributes to capture. Use the wildcard character `*` to capture all attributes. | | `otel.instrumentation.logback-appender.experimental.capture-mdc-attributes` | String | | List of MDC attributes to capture. Use the wildcard character `*` to capture all attributes. |
[source code attributes]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/span-general.md#source-code-attributes [source code attributes]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/span-general.md#source-code-attributes

View File

@ -27,6 +27,10 @@ public final class LogbackSingletons {
boolean captureMarkerAttribute = boolean captureMarkerAttribute =
config.getBoolean( config.getBoolean(
"otel.instrumentation.logback-appender.experimental.capture-marker-attribute", false); "otel.instrumentation.logback-appender.experimental.capture-marker-attribute", false);
boolean captureKeyValuePairAttributes =
config.getBoolean(
"otel.instrumentation.logback-appender.experimental.capture-key-value-pair-attributes",
false);
List<String> captureMdcAttributes = List<String> captureMdcAttributes =
config.getList( config.getList(
"otel.instrumentation.logback-appender.experimental.capture-mdc-attributes", "otel.instrumentation.logback-appender.experimental.capture-mdc-attributes",
@ -37,7 +41,8 @@ public final class LogbackSingletons {
captureExperimentalAttributes, captureExperimentalAttributes,
captureMdcAttributes, captureMdcAttributes,
captureCodeAttributes, captureCodeAttributes,
captureMarkerAttribute); captureMarkerAttribute,
captureKeyValuePairAttributes);
} }
public static LoggingEventMapper mapper() { public static LoggingEventMapper mapper() {

View File

@ -16,6 +16,7 @@ import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.util.Arrays;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.assertj.core.api.AbstractLongAssert; import org.assertj.core.api.AbstractLongAssert;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -215,7 +216,7 @@ class LogbackTest {
.hasAttributesSatisfyingExactly( .hasAttributesSatisfyingExactly(
equalTo(SemanticAttributes.THREAD_NAME, Thread.currentThread().getName()), equalTo(SemanticAttributes.THREAD_NAME, Thread.currentThread().getName()),
equalTo(SemanticAttributes.THREAD_ID, Thread.currentThread().getId()), equalTo(SemanticAttributes.THREAD_ID, Thread.currentThread().getId()),
equalTo(AttributeKey.stringKey("logback.marker"), markerName), equalTo(AttributeKey.stringArrayKey("logback.marker"), Arrays.asList(markerName)),
equalTo(SemanticAttributes.CODE_NAMESPACE, LogbackTest.class.getName()), equalTo(SemanticAttributes.CODE_NAMESPACE, LogbackTest.class.getName()),
equalTo(SemanticAttributes.CODE_FUNCTION, "testMarker"), equalTo(SemanticAttributes.CODE_FUNCTION, "testMarker"),
satisfies(SemanticAttributes.CODE_LINENO, AbstractLongAssert::isPositive), satisfies(SemanticAttributes.CODE_LINENO, AbstractLongAssert::isPositive),

View File

@ -4,17 +4,20 @@ plugins {
} }
dependencies { dependencies {
compileOnly(project(":muzzle"))
implementation("io.opentelemetry:opentelemetry-api-logs") implementation("io.opentelemetry:opentelemetry-api-logs")
// pin the version strictly to avoid overriding by dependencyManagement versions // pin the version strictly to avoid overriding by dependencyManagement versions
compileOnly("ch.qos.logback:logback-classic") { compileOnly("ch.qos.logback:logback-classic") {
version { version {
strictly("1.0.0") // compiling against newer version than the earliest supported version (1.0.0) to support
// features added in 1.3.0
strictly("1.3.0")
} }
} }
compileOnly("org.slf4j:slf4j-api") { compileOnly("org.slf4j:slf4j-api") {
version { version {
strictly("1.6.4") strictly("2.0.0")
} }
} }
@ -52,3 +55,39 @@ configurations.configureEach {
exclude("org.apache.groovy", "groovy-json") exclude("org.apache.groovy", "groovy-json")
exclude("org.spockframework", "spock-core") exclude("org.spockframework", "spock-core")
} }
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-api-logs")
implementation("io.opentelemetry:opentelemetry-sdk-logs")
implementation("io.opentelemetry:opentelemetry-sdk-testing")
if (latestDepTest) {
implementation("ch.qos.logback:logback-classic:+")
implementation("org.slf4j:slf4j-api:+")
} else {
implementation("ch.qos.logback:logback-classic") {
version {
strictly("1.3.0")
}
}
implementation("org.slf4j:slf4j-api") {
version {
strictly("2.0.0")
}
}
}
}
}
}
}
tasks {
check {
dependsOn(testing.suites)
}
}

View File

@ -18,12 +18,13 @@ import org.slf4j.MDC;
public class OpenTelemetryAppender extends UnsynchronizedAppenderBase<ILoggingEvent> { public class OpenTelemetryAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
private volatile boolean captureExperimentalAttributes = false; private boolean captureExperimentalAttributes = false;
private volatile boolean captureCodeAttributes = false; private boolean captureCodeAttributes = false;
private volatile boolean captureMarkerAttribute = false; private boolean captureMarkerAttribute = false;
private volatile List<String> captureMdcAttributes = emptyList(); private boolean captureKeyValuePairAttributes = false;
private List<String> captureMdcAttributes = emptyList();
private volatile LoggingEventMapper mapper; private LoggingEventMapper mapper;
public OpenTelemetryAppender() {} public OpenTelemetryAppender() {}
@ -34,7 +35,8 @@ public class OpenTelemetryAppender extends UnsynchronizedAppenderBase<ILoggingEv
captureExperimentalAttributes, captureExperimentalAttributes,
captureMdcAttributes, captureMdcAttributes,
captureCodeAttributes, captureCodeAttributes,
captureMarkerAttribute); captureMarkerAttribute,
captureKeyValuePairAttributes);
super.start(); super.start();
} }
@ -73,6 +75,15 @@ public class OpenTelemetryAppender extends UnsynchronizedAppenderBase<ILoggingEv
this.captureMarkerAttribute = captureMarkerAttribute; this.captureMarkerAttribute = captureMarkerAttribute;
} }
/**
* Sets whether the key value pair attributes should be set to logs.
*
* @param captureKeyValuePairAttributes To enable or disable the marker attribute
*/
public void setCaptureKeyValuePairAttributes(boolean captureKeyValuePairAttributes) {
this.captureKeyValuePairAttributes = captureKeyValuePairAttributes;
}
/** Configures the {@link MDC} attributes that will be copied to logs. */ /** Configures the {@link MDC} attributes that will be copied to logs. */
public void setCaptureMdcAttributes(String attributes) { public void setCaptureMdcAttributes(String attributes) {
if (attributes != null) { if (attributes != null) {

View File

@ -16,13 +16,16 @@ import io.opentelemetry.api.logs.LoggerProvider;
import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.logs.Severity;
import io.opentelemetry.context.Context; import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.internal.cache.Cache; import io.opentelemetry.instrumentation.api.internal.cache.Cache;
import io.opentelemetry.javaagent.tooling.muzzle.NoMuzzle;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.slf4j.Marker; import org.slf4j.Marker;
import org.slf4j.event.KeyValuePair;
/** /**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at * This class is internal and is hence not for public use. Its APIs are unstable and can change at
@ -30,25 +33,31 @@ import org.slf4j.Marker;
*/ */
public final class LoggingEventMapper { public final class LoggingEventMapper {
private static final boolean supportsKeyValuePairs = supportsKeyValuePairs();
private static final boolean supportsMultipleMarkers = supportsMultipleMarkers();
private static final Cache<String, AttributeKey<String>> mdcAttributeKeys = Cache.bounded(100); private static final Cache<String, AttributeKey<String>> mdcAttributeKeys = Cache.bounded(100);
private static final AttributeKey<String> LOG_MARKER = AttributeKey.stringKey("logback.marker"); private static final AttributeKey<List<String>> LOG_MARKER =
AttributeKey.stringArrayKey("logback.marker");
private final boolean captureExperimentalAttributes; private final boolean captureExperimentalAttributes;
private final List<String> captureMdcAttributes; private final List<String> captureMdcAttributes;
private final boolean captureAllMdcAttributes; private final boolean captureAllMdcAttributes;
private final boolean captureCodeAttributes; private final boolean captureCodeAttributes;
private final boolean captureMarkerAttribute; private final boolean captureMarkerAttribute;
private final boolean captureKeyValuePairAttributes;
public LoggingEventMapper( public LoggingEventMapper(
boolean captureExperimentalAttributes, boolean captureExperimentalAttributes,
List<String> captureMdcAttributes, List<String> captureMdcAttributes,
boolean captureCodeAttributes, boolean captureCodeAttributes,
boolean captureMarkerAttribute) { boolean captureMarkerAttribute,
boolean captureKeyValuePairAttributes) {
this.captureExperimentalAttributes = captureExperimentalAttributes; this.captureExperimentalAttributes = captureExperimentalAttributes;
this.captureCodeAttributes = captureCodeAttributes; this.captureCodeAttributes = captureCodeAttributes;
this.captureMdcAttributes = captureMdcAttributes; this.captureMdcAttributes = captureMdcAttributes;
this.captureMarkerAttribute = captureMarkerAttribute; this.captureMarkerAttribute = captureMarkerAttribute;
this.captureKeyValuePairAttributes = captureKeyValuePairAttributes;
this.captureAllMdcAttributes = this.captureAllMdcAttributes =
captureMdcAttributes.size() == 1 && captureMdcAttributes.get(0).equals("*"); captureMdcAttributes.size() == 1 && captureMdcAttributes.get(0).equals("*");
} }
@ -132,11 +141,11 @@ public final class LoggingEventMapper {
} }
if (captureMarkerAttribute) { if (captureMarkerAttribute) {
Marker marker = loggingEvent.getMarker(); captureMarkerAttribute(attributes, loggingEvent);
if (marker != null) { }
String markerName = marker.getName();
attributes.put(LOG_MARKER, markerName); if (supportsKeyValuePairs && captureKeyValuePairAttributes) {
} captureKeyValuePairAttributes(attributes, loggingEvent);
} }
builder.setAllAttributes(attributes.build()); builder.setAllAttributes(attributes.build());
@ -195,4 +204,76 @@ public final class LoggingEventMapper {
return Severity.UNDEFINED_SEVERITY_NUMBER; return Severity.UNDEFINED_SEVERITY_NUMBER;
} }
} }
@NoMuzzle
private static void captureKeyValuePairAttributes(
AttributesBuilder attributes, ILoggingEvent loggingEvent) {
List<KeyValuePair> keyValuePairs = loggingEvent.getKeyValuePairs();
if (keyValuePairs != null) {
for (KeyValuePair keyValuePair : keyValuePairs) {
if (keyValuePair.value != null) {
attributes.put(keyValuePair.key, keyValuePair.value.toString());
}
}
}
}
private static boolean supportsKeyValuePairs() {
try {
Class.forName("org.slf4j.event.KeyValuePair");
} catch (ClassNotFoundException e) {
return false;
}
try {
ILoggingEvent.class.getMethod("getKeyValuePairs");
} catch (NoSuchMethodException e) {
return false;
}
return true;
}
private static void captureMarkerAttribute(
AttributesBuilder attributes, ILoggingEvent loggingEvent) {
if (supportsMultipleMarkers && hasMultipleMarkers(loggingEvent)) {
captureMultipleMarkerAttributes(attributes, loggingEvent);
} else {
captureSingleMarkerAttribute(attributes, loggingEvent);
}
}
@Deprecated // getMarker is deprecate since 1.3.0
private static void captureSingleMarkerAttribute(
AttributesBuilder attributes, ILoggingEvent loggingEvent) {
Marker marker = loggingEvent.getMarker();
if (marker != null) {
attributes.put(LOG_MARKER, marker.getName());
}
}
@NoMuzzle
private static void captureMultipleMarkerAttributes(
AttributesBuilder attributes, ILoggingEvent loggingEvent) {
List<String> markerNames = new ArrayList<>(loggingEvent.getMarkerList().size());
for (Marker marker : loggingEvent.getMarkerList()) {
markerNames.add(marker.getName());
}
attributes.put(LOG_MARKER, markerNames.toArray(new String[0]));
}
@NoMuzzle
private static boolean hasMultipleMarkers(ILoggingEvent loggingEvent) {
List<Marker> markerList = loggingEvent.getMarkerList();
return markerList != null && markerList.size() > 1;
}
private static boolean supportsMultipleMarkers() {
try {
ILoggingEvent.class.getMethod("getMarkerList");
} catch (NoSuchMethodException e) {
return false;
}
return true;
}
} }

View File

@ -0,0 +1,94 @@
/*
* 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.assertThat;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.logs.GlobalLoggerProvider;
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.logs.export.InMemoryLogRecordExporter;
import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor;
import io.opentelemetry.sdk.resources.Resource;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MarkerFactory;
public class Slf4j2Test {
private static final Logger logger = LoggerFactory.getLogger("TestLogger");
private static InMemoryLogRecordExporter logRecordExporter;
private static Resource resource;
private static InstrumentationScopeInfo instrumentationScopeInfo;
@BeforeAll
static void setupAll() {
logRecordExporter = InMemoryLogRecordExporter.create();
resource = Resource.getDefault();
instrumentationScopeInfo = InstrumentationScopeInfo.create("TestLogger");
SdkLoggerProvider loggerProvider =
SdkLoggerProvider.builder()
.setResource(resource)
.addLogRecordProcessor(SimpleLogRecordProcessor.create(logRecordExporter))
.build();
GlobalLoggerProvider.resetForTest();
GlobalLoggerProvider.set(loggerProvider);
}
@BeforeEach
void setup() {
logRecordExporter.reset();
}
@Test
void keyValue() {
logger.atInfo().setMessage("log message 1").addKeyValue("key", "value").log();
List<LogRecordData> logDataList = logRecordExporter.getFinishedLogItems();
assertThat(logDataList).hasSize(1);
LogRecordData logData = logDataList.get(0);
assertThat(logData.getResource()).isEqualTo(resource);
assertThat(logData.getInstrumentationScopeInfo()).isEqualTo(instrumentationScopeInfo);
assertThat(logData.getBody().asString()).isEqualTo("log message 1");
assertThat(logData.getAttributes().size()).isEqualTo(5); // 4 code attributes + 1 key value pair
assertThat(logData.getAttributes())
.hasEntrySatisfying(
AttributeKey.stringKey("key"), value -> assertThat(value).isEqualTo("value"));
}
@Test
void multipleMarkers() {
String markerName1 = "aMarker1";
String markerName2 = "aMarker2";
logger
.atInfo()
.setMessage("log message 1")
.addMarker(MarkerFactory.getMarker(markerName1))
.addMarker(MarkerFactory.getMarker(markerName2))
.log();
List<LogRecordData> logDataList = logRecordExporter.getFinishedLogItems();
assertThat(logDataList).hasSize(1);
LogRecordData logData = logDataList.get(0);
assertThat(logData.getResource()).isEqualTo(resource);
assertThat(logData.getInstrumentationScopeInfo()).isEqualTo(instrumentationScopeInfo);
assertThat(logData.getBody().asString()).isEqualTo("log message 1");
assertThat(logData.getAttributes().size()).isEqualTo(5); // 4 code attributes + 1 marker
assertThat(logData.getAttributes())
.hasEntrySatisfying(
AttributeKey.stringArrayKey("logback.marker"),
value -> assertThat(value).isEqualTo(Arrays.asList(markerName1, markerName2)));
}
}

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<appender name="OpenTelemetry"
class="io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender">
<captureExperimentalAttributes>false</captureExperimentalAttributes>
<captureCodeAttributes>true</captureCodeAttributes>
<captureMarkerAttribute>true</captureMarkerAttribute>
<captureKeyValuePairAttributes>true</captureKeyValuePairAttributes>
<captureMdcAttributes>*</captureMdcAttributes>
</appender>
<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="OpenTelemetry"/>
</root>
</configuration>

View File

@ -5,7 +5,7 @@
package io.opentelemetry.instrumentation.logback.appender.v1_0; package io.opentelemetry.instrumentation.logback.appender.v1_0;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.logs.GlobalLoggerProvider; import io.opentelemetry.api.logs.GlobalLoggerProvider;
@ -22,9 +22,9 @@ import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider; import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.time.Instant; import java.time.Instant;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.assertj.core.api.AssertionsForClassTypes;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -142,8 +142,9 @@ class OpenTelemetryAppenderConfigTest {
Long lineNumber = logData.getAttributes().get(SemanticAttributes.CODE_LINENO); Long lineNumber = logData.getAttributes().get(SemanticAttributes.CODE_LINENO);
assertThat(lineNumber).isGreaterThan(1); assertThat(lineNumber).isGreaterThan(1);
String logMarker = logData.getAttributes().get(AttributeKey.stringKey("logback.marker")); List<String> logMarker =
assertThat(logMarker).isEqualTo(markerName); logData.getAttributes().get(AttributeKey.stringArrayKey("logback.marker"));
assertThat(logMarker).isEqualTo(Arrays.asList(markerName));
} }
@Test @Test
@ -163,11 +164,9 @@ class OpenTelemetryAppenderConfigTest {
assertThat(logData.getInstrumentationScopeInfo()).isEqualTo(instrumentationScopeInfo); assertThat(logData.getInstrumentationScopeInfo()).isEqualTo(instrumentationScopeInfo);
assertThat(logData.getBody().asString()).isEqualTo("log message 1"); assertThat(logData.getBody().asString()).isEqualTo("log message 1");
assertThat(logData.getAttributes().size()).isEqualTo(2 + 4); // 4 code attributes assertThat(logData.getAttributes().size()).isEqualTo(2 + 4); // 4 code attributes
AssertionsForClassTypes.assertThat( assertThat(logData.getAttributes().get(AttributeKey.stringKey("logback.mdc.key1")))
logData.getAttributes().get(AttributeKey.stringKey("logback.mdc.key1")))
.isEqualTo("val1"); .isEqualTo("val1");
AssertionsForClassTypes.assertThat( assertThat(logData.getAttributes().get(AttributeKey.stringKey("logback.mdc.key2")))
logData.getAttributes().get(AttributeKey.stringKey("logback.mdc.key2")))
.isEqualTo("val2"); .isEqualTo("val2");
} }
} }

View File

@ -22,7 +22,7 @@ class LoggingEventMapperTest {
@Test @Test
void testDefault() { void testDefault() {
// given // given
LoggingEventMapper mapper = new LoggingEventMapper(false, emptyList(), false, false); LoggingEventMapper mapper = new LoggingEventMapper(false, emptyList(), false, false, false);
Map<String, String> contextData = new HashMap<>(); Map<String, String> contextData = new HashMap<>();
contextData.put("key1", "value1"); contextData.put("key1", "value1");
contextData.put("key2", "value2"); contextData.put("key2", "value2");
@ -38,7 +38,8 @@ class LoggingEventMapperTest {
@Test @Test
void testSome() { void testSome() {
// given // given
LoggingEventMapper mapper = new LoggingEventMapper(false, singletonList("key2"), false, false); LoggingEventMapper mapper =
new LoggingEventMapper(false, singletonList("key2"), false, false, false);
Map<String, String> contextData = new HashMap<>(); Map<String, String> contextData = new HashMap<>();
contextData.put("key1", "value1"); contextData.put("key1", "value1");
contextData.put("key2", "value2"); contextData.put("key2", "value2");
@ -55,7 +56,8 @@ class LoggingEventMapperTest {
@Test @Test
void testAll() { void testAll() {
// given // given
LoggingEventMapper mapper = new LoggingEventMapper(false, singletonList("*"), false, false); LoggingEventMapper mapper =
new LoggingEventMapper(false, singletonList("*"), false, false, false);
Map<String, String> contextData = new HashMap<>(); Map<String, String> contextData = new HashMap<>();
contextData.put("key1", "value1"); contextData.put("key1", "value1");
contextData.put("key2", "value2"); contextData.put("key2", "value2");

View File

@ -28,7 +28,7 @@ import java.util.Map;
public class OpenTelemetryAppender extends UnsynchronizedAppenderBase<ILoggingEvent> public class OpenTelemetryAppender extends UnsynchronizedAppenderBase<ILoggingEvent>
implements AppenderAttachable<ILoggingEvent> { implements AppenderAttachable<ILoggingEvent> {
private volatile boolean addBaggage; private boolean addBaggage;
private final AppenderAttachableImpl<ILoggingEvent> aai = new AppenderAttachableImpl<>(); private final AppenderAttachableImpl<ILoggingEvent> aai = new AppenderAttachableImpl<>();