Add marker attribute for Logback
MODIFY
instrumentation/logback/logback-appender-1.0/javaagent/build.gradle.kts
instrumentation/logback/logback-appender-1.0/javaagent/build.gradle.kts
@@ -56,4 +56,5 @@ tasks.withType<Test>().configureEach {
jvmArgs("-Dotel.instrumentation.logback-appender.experimental.capture-mdc-attributes=*")
jvmArgs("-Dotel.instrumentation.logback-appender.experimental-log-attributes=true")
jvmArgs("-Dotel.instrumentation.logback-appender.experimental.capture-code-attributes=true")
+ jvmArgs("-Dotel.instrumentation.logback-appender.experimental.capture-marker-attribute=true")
}

MODIFY
instrumentation/logback/logback-appender-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/logback/appender/v1_0/LogbackSingletons.java
instrumentation/logback/logback-appender-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/logback/appender/v1_0/LogbackSingletons.java
@@ -24,6 +24,9 @@ public final class LogbackSingletons {
boolean captureCodeAttributes =
config.getBoolean(
"otel.instrumentation.logback-appender.experimental.capture-code-attributes", false);
+ boolean captureMarkerAttribute =
+ config.getBoolean(
+ "otel.instrumentation.logback-appender.experimental.capture-marker-attribute", false);
List<String> captureMdcAttributes =
config.getList(
"otel.instrumentation.logback-appender.experimental.capture-mdc-attributes",
@@ -31,7 +34,10 @@ public final class LogbackSingletons {
mapper =
new LoggingEventMapper(
- captureExperimentalAttributes, captureMdcAttributes, captureCodeAttributes);
+ captureExperimentalAttributes,
+ captureMdcAttributes,
+ captureCodeAttributes,
+ captureMarkerAttribute);
}
public static LoggingEventMapper mapper() {

MODIFY
instrumentation/logback/logback-appender-1.0/javaagent/src/test/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogbackTest.java
instrumentation/logback/logback-appender-1.0/javaagent/src/test/java/io/opentelemetry/instrumentation/logback/appender/v1_0/LogbackTest.java
@@ -26,6 +26,8 @@ import org.junit.jupiter.params.provider.MethodSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
class LogbackTest extends AgentInstrumentationSpecification {
@@ -219,6 +221,25 @@ class LogbackTest extends AgentInstrumentationSpecification {
.containsEntry(SemanticAttributes.CODE_FILEPATH, "LogbackTest.java"));
}
+ @Test
+ public void testMarker() {
+
+ String markerName = "aMarker";
+ Marker marker = MarkerFactory.getMarker(markerName);
+
+ abcLogger.info(marker, "Message");
+
+ await().untilAsserted(() -> assertThat(testing.logs().size()).isEqualTo(1));
+
+ LogData log = getLogs().get(0);
+
+ assertThat(log)
+ .hasAttributesSatisfying(
+ attributes ->
+ assertThat(attributes)
+ .containsEntry(AttributeKey.stringKey("logback.marker"), markerName));
+ }
+
private static void performLogging(
Logger logger,
OneArgLoggerMethod oneArgLoggerMethod,

MODIFY
instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java
instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppender.java
@@ -26,6 +26,7 @@ public class OpenTelemetryAppender extends UnsynchronizedAppenderBase<ILoggingEv
private volatile boolean captureExperimentalAttributes = false;
private volatile boolean captureCodeAttributes = false;
+ private volatile boolean captureMarkerAttribute = false;
private volatile List<String> captureMdcAttributes = emptyList();
private volatile LoggingEventMapper mapper;
@@ -36,7 +37,10 @@ public class OpenTelemetryAppender extends UnsynchronizedAppenderBase<ILoggingEv
public void start() {
mapper =
new LoggingEventMapper(
- captureExperimentalAttributes, captureMdcAttributes, captureCodeAttributes);
+ captureExperimentalAttributes,
+ captureMdcAttributes,
+ captureCodeAttributes,
+ captureMarkerAttribute);
super.start();
}
@@ -77,6 +81,15 @@ public class OpenTelemetryAppender extends UnsynchronizedAppenderBase<ILoggingEv
this.captureCodeAttributes = captureCodeAttributes;
}
+ /**
+ * Sets whether the marker attribute should be set to logs.
+ *
+ * @param captureMarkerAttribute To enable or disable the marker attribute
+ */
+ public void setCaptureMarkerAttribute(boolean captureMarkerAttribute) {
+ this.captureMarkerAttribute = captureMarkerAttribute;
+ }
+
/** Configures the {@link MDC} attributes that will be copied to logs. */
public void setCaptureMdcAttributes(String attributes) {
if (attributes != null) {

MODIFY
instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java
instrumentation/logback/logback-appender-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapper.java
@@ -22,6 +22,7 @@ import java.io.StringWriter;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
+import org.slf4j.Marker;
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
@@ -31,18 +32,23 @@ public final class LoggingEventMapper {
private static final Cache<String, AttributeKey<String>> mdcAttributeKeys = Cache.bounded(100);
+ private static final AttributeKey<String> LOG_MARKER = AttributeKey.stringKey("logback.marker");
+
private final boolean captureExperimentalAttributes;
private final List<String> captureMdcAttributes;
private final boolean captureAllMdcAttributes;
private final boolean captureCodeAttributes;
+ private final boolean captureMarkerAttribute;
public LoggingEventMapper(
boolean captureExperimentalAttributes,
List<String> captureMdcAttributes,
- boolean captureCodeAttributes) {
+ boolean captureCodeAttributes,
+ boolean captureMarkerAttribute) {
this.captureExperimentalAttributes = captureExperimentalAttributes;
this.captureCodeAttributes = captureCodeAttributes;
this.captureMdcAttributes = captureMdcAttributes;
+ this.captureMarkerAttribute = captureMarkerAttribute;
this.captureAllMdcAttributes =
captureMdcAttributes.size() == 1 && captureMdcAttributes.get(0).equals("*");
}
@@ -125,6 +131,14 @@ public final class LoggingEventMapper {
}
}
+ if (captureMarkerAttribute) {
+ Marker marker = loggingEvent.getMarker();
+ if (marker != null) {
+ String markerName = marker.getName();
+ attributes.put(LOG_MARKER, markerName);
+ }
+ }
+
builder.setAllAttributes(attributes.build());
// span context

MODIFY
instrumentation/logback/logback-appender-1.0/library/src/test/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppenderConfigTest.java
instrumentation/logback/logback-appender-1.0/library/src/test/java/io/opentelemetry/instrumentation/logback/appender/v1_0/OpenTelemetryAppenderConfigTest.java
@@ -30,6 +30,8 @@ import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
class OpenTelemetryAppenderConfigTest {
@@ -101,7 +103,9 @@ class OpenTelemetryAppenderConfigTest {
@Test
void logWithExtras() {
Instant start = Instant.now();
- logger.info("log message 1", new IllegalStateException("Error!"));
+ String markerName = "aMarker";
+ Marker marker = MarkerFactory.getMarker(markerName);
+ logger.info(marker, "log message 1", new IllegalStateException("Error!"));
List<LogData> logDataList = logExporter.getFinishedLogItems();
assertThat(logDataList).hasSize(1);
@@ -114,7 +118,8 @@ class OpenTelemetryAppenderConfigTest {
.isLessThan(TimeUnit.MILLISECONDS.toNanos(Instant.now().toEpochMilli()));
assertThat(logData.getSeverity()).isEqualTo(Severity.INFO);
assertThat(logData.getSeverityText()).isEqualTo("INFO");
- assertThat(logData.getAttributes().size()).isEqualTo(3 + 4); // 4 code attributes
+ assertThat(logData.getAttributes().size())
+ .isEqualTo(3 + 4 + 1); // 3 exception attributes, 4 code attributes, 1 marker attribute
assertThat(logData.getAttributes().get(SemanticAttributes.EXCEPTION_TYPE))
.isEqualTo(IllegalStateException.class.getName());
assertThat(logData.getAttributes().get(SemanticAttributes.EXCEPTION_MESSAGE))
@@ -135,6 +140,9 @@ class OpenTelemetryAppenderConfigTest {
Long lineNumber = logData.getAttributes().get(SemanticAttributes.CODE_LINENO);
assertThat(lineNumber).isGreaterThan(1);
+
+ String logMarker = logData.getAttributes().get(AttributeKey.stringKey("logback.marker"));
+ assertThat(logMarker).isEqualTo(markerName);
}
@Test

MODIFY
instrumentation/logback/logback-appender-1.0/library/src/test/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapperTest.java
instrumentation/logback/logback-appender-1.0/library/src/test/java/io/opentelemetry/instrumentation/logback/appender/v1_0/internal/LoggingEventMapperTest.java
@@ -22,7 +22,7 @@ class LoggingEventMapperTest {
@Test
void testDefault() {
// given
- LoggingEventMapper mapper = new LoggingEventMapper(false, emptyList(), false);
+ LoggingEventMapper mapper = new LoggingEventMapper(false, emptyList(), false, false);
Map<String, String> contextData = new HashMap<>();
contextData.put("key1", "value1");
contextData.put("key2", "value2");
@@ -38,7 +38,7 @@ class LoggingEventMapperTest {
@Test
void testSome() {
// given
- LoggingEventMapper mapper = new LoggingEventMapper(false, singletonList("key2"), false);
+ LoggingEventMapper mapper = new LoggingEventMapper(false, singletonList("key2"), false, false);
Map<String, String> contextData = new HashMap<>();
contextData.put("key1", "value1");
contextData.put("key2", "value2");
@@ -55,7 +55,7 @@ class LoggingEventMapperTest {
@Test
void testAll() {
// given
- LoggingEventMapper mapper = new LoggingEventMapper(false, singletonList("*"), false);
+ LoggingEventMapper mapper = new LoggingEventMapper(false, singletonList("*"), false, false);
Map<String, String> contextData = new HashMap<>();
contextData.put("key1", "value1");
contextData.put("key2", "value2");

MODIFY
instrumentation/logback/logback-appender-1.0/library/src/test/resources/logback-test.xml
instrumentation/logback/logback-appender-1.0/library/src/test/resources/logback-test.xml
class="io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender">
<captureExperimentalAttributes>false</captureExperimentalAttributes>
<captureCodeAttributes>true</captureCodeAttributes>
+ <captureMarkerAttribute>true</captureMarkerAttribute>
<captureMdcAttributes>*</captureMdcAttributes>
</appender>

Add marker attribute for Logback (#6652)