From a76c35e33f7cc411b7da6068172d6e3f862e1555 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Sun, 19 Dec 2021 19:32:46 -0800 Subject: [PATCH] Minor log4j instrumentation updates (#4938) * Minor log4j instrumentation updates * Remove duplicate line * Use semantic attributes for exceptions --- .../log4j/v2_16/LogEventMapper.java | 29 +++++++++---------- .../OpenTelemetryAppenderConfigTest.java | 10 +++++-- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/instrumentation/log4j/log4j-2.16/library/src/main/java/io/opentelemetry/instrumentation/log4j/v2_16/LogEventMapper.java b/instrumentation/log4j/log4j-2.16/library/src/main/java/io/opentelemetry/instrumentation/log4j/v2_16/LogEventMapper.java index a91277428a..e9323d67da 100644 --- a/instrumentation/log4j/log4j-2.16/library/src/main/java/io/opentelemetry/instrumentation/log4j/v2_16/LogEventMapper.java +++ b/instrumentation/log4j/log4j-2.16/library/src/main/java/io/opentelemetry/instrumentation/log4j/v2_16/LogEventMapper.java @@ -5,12 +5,14 @@ package io.opentelemetry.instrumentation.log4j.v2_16; -import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.appender.LogBuilder; import io.opentelemetry.instrumentation.api.appender.Severity; +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.concurrent.TimeUnit; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.LogEvent; @@ -19,10 +21,6 @@ import org.apache.logging.log4j.message.Message; final class LogEventMapper { - // Visible for testing - static final AttributeKey ATTR_THROWABLE_MESSAGE = - AttributeKey.stringKey("throwable.message"); - /** * Map the {@link LogEvent} data model onto the {@link LogBuilder}. Unmapped fields include: * @@ -31,17 +29,12 @@ final class LogEventMapper { *
  • Thread name - {@link LogEvent#getThreadName()} *
  • Thread id - {@link LogEvent#getThreadId()} *
  • Thread priority - {@link LogEvent#getThreadPriority()} - *
  • Thread priority - {@link LogEvent#getThreadPriority()} - *
  • Thrown details (stack trace, class name) - {@link LogEvent#getThrown()} *
  • Marker - {@link LogEvent#getMarker()} *
  • Nested diagnostic context - {@link LogEvent#getContextStack()} *
  • Mapped diagnostic context - {@link LogEvent#getContextData()} * */ static void mapLogEvent(LogBuilder builder, LogEvent logEvent) { - // TODO: map the LogEvent more completely when semantic conventions allow it - AttributesBuilder attributes = Attributes.builder(); - // message Message message = logEvent.getMessage(); if (message != null) { @@ -67,21 +60,27 @@ final class LogEventMapper { // throwable Throwable throwable = logEvent.getThrown(); if (throwable != null) { - attributes.put(ATTR_THROWABLE_MESSAGE, throwable.getMessage()); + AttributesBuilder attributes = Attributes.builder(); + + // TODO (trask) extract method for recording exception into instrumentation-api-appender + attributes.put(SemanticAttributes.EXCEPTION_TYPE, throwable.getClass().getName()); + attributes.put(SemanticAttributes.EXCEPTION_MESSAGE, throwable.getMessage()); + StringWriter writer = new StringWriter(); + throwable.printStackTrace(new PrintWriter(writer)); + attributes.put(SemanticAttributes.EXCEPTION_STACKTRACE, writer.toString()); + + builder.setAttributes(attributes.build()); } // span context builder.setContext(Context.current()); - - builder.setAttributes(attributes.build()); } private static Severity levelToSeverity(Level level) { switch (level.getStandardLevel()) { case ALL: - return Severity.TRACE; case TRACE: - return Severity.TRACE2; + return Severity.TRACE; case DEBUG: return Severity.DEBUG; case INFO: diff --git a/instrumentation/log4j/log4j-2.16/library/src/test/java/io/opentelemetry/instrumentation/log4j/v2_16/OpenTelemetryAppenderConfigTest.java b/instrumentation/log4j/log4j-2.16/library/src/test/java/io/opentelemetry/instrumentation/log4j/v2_16/OpenTelemetryAppenderConfigTest.java index 7fd46b6bb3..4811548d36 100644 --- a/instrumentation/log4j/log4j-2.16/library/src/test/java/io/opentelemetry/instrumentation/log4j/v2_16/OpenTelemetryAppenderConfigTest.java +++ b/instrumentation/log4j/log4j-2.16/library/src/test/java/io/opentelemetry/instrumentation/log4j/v2_16/OpenTelemetryAppenderConfigTest.java @@ -5,7 +5,6 @@ package io.opentelemetry.instrumentation.log4j.v2_16; -import static io.opentelemetry.instrumentation.log4j.v2_16.LogEventMapper.ATTR_THROWABLE_MESSAGE; import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; import io.opentelemetry.api.common.Attributes; @@ -22,6 +21,7 @@ import io.opentelemetry.sdk.logs.export.InMemoryLogExporter; import io.opentelemetry.sdk.logs.export.SimpleLogProcessor; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; import java.time.Instant; import java.util.List; import java.util.concurrent.TimeUnit; @@ -116,6 +116,12 @@ class OpenTelemetryAppenderConfigTest { .isLessThan(TimeUnit.MILLISECONDS.toNanos(Instant.now().toEpochMilli())); assertThat(logData.getSeverity()).isEqualTo(Severity.INFO); assertThat(logData.getSeverityText()).isEqualTo("INFO"); - assertThat(logData.getAttributes()).isEqualTo(Attributes.of(ATTR_THROWABLE_MESSAGE, "Error!")); + assertThat(logData.getAttributes().size()).isEqualTo(3); + assertThat(logData.getAttributes().get(SemanticAttributes.EXCEPTION_TYPE)) + .isEqualTo(IllegalStateException.class.getName()); + assertThat(logData.getAttributes().get(SemanticAttributes.EXCEPTION_MESSAGE)) + .isEqualTo("Error!"); + assertThat(logData.getAttributes().get(SemanticAttributes.EXCEPTION_STACKTRACE)) + .contains("logWithExtras"); } }