From 36af04266a660dc7f1fedb4a8ac8bfceec13331f Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Fri, 3 Mar 2023 18:32:50 +0200 Subject: [PATCH] Fix AbstractMethodError in logback instrumentation (#7967) Resolves https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/7949 Replace wrapper class with JDK proxy to ensure that all methods are implemented and delegated to the underlying event. --- .../logback/mdc/v1_0/LoggingEventWrapper.java | 118 ------------------ .../mdc/v1_0/OpenTelemetryAppender.java | 21 +++- 2 files changed, 20 insertions(+), 119 deletions(-) delete mode 100644 instrumentation/logback/logback-mdc-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/mdc/v1_0/LoggingEventWrapper.java diff --git a/instrumentation/logback/logback-mdc-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/mdc/v1_0/LoggingEventWrapper.java b/instrumentation/logback/logback-mdc-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/mdc/v1_0/LoggingEventWrapper.java deleted file mode 100644 index 8cd6a3159f..0000000000 --- a/instrumentation/logback/logback-mdc-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/mdc/v1_0/LoggingEventWrapper.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.logback.mdc.v1_0; - -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.classic.spi.IThrowableProxy; -import ch.qos.logback.classic.spi.LoggerContextVO; -import java.util.Map; -import javax.annotation.Nullable; -import org.slf4j.Marker; - -final class LoggingEventWrapper implements ILoggingEvent { - private final ILoggingEvent event; - private final Map mdcPropertyMap; - @Nullable private final LoggerContextVO vo; - - LoggingEventWrapper(ILoggingEvent event, Map mdcPropertyMap) { - this.event = event; - this.mdcPropertyMap = mdcPropertyMap; - - LoggerContextVO oldVo = event.getLoggerContextVO(); - if (oldVo != null) { - vo = new LoggerContextVO(oldVo.getName(), mdcPropertyMap, oldVo.getBirthTime()); - } else { - vo = null; - } - } - - @Override - public Object[] getArgumentArray() { - return event.getArgumentArray(); - } - - @Override - public Level getLevel() { - return event.getLevel(); - } - - @Override - public String getLoggerName() { - return event.getLoggerName(); - } - - @Override - public String getThreadName() { - return event.getThreadName(); - } - - @Override - public IThrowableProxy getThrowableProxy() { - return event.getThrowableProxy(); - } - - @Override - public void prepareForDeferredProcessing() { - event.prepareForDeferredProcessing(); - } - - @Override - public LoggerContextVO getLoggerContextVO() { - return vo; - } - - @Override - public String getMessage() { - return event.getMessage(); - } - - @Override - public long getTimeStamp() { - return event.getTimeStamp(); - } - - @Override - public StackTraceElement[] getCallerData() { - return event.getCallerData(); - } - - @Override - public boolean hasCallerData() { - return event.hasCallerData(); - } - - @Override - public Marker getMarker() { - return event.getMarker(); - } - - @Override - public String getFormattedMessage() { - return event.getFormattedMessage(); - } - - @Override - public Map getMDCPropertyMap() { - return mdcPropertyMap; - } - - /** - * A synonym for {@link #getMDCPropertyMap}. - * - * @deprecated Use {@link #getMDCPropertyMap()}. - */ - @Override - @Deprecated - public Map getMdc() { - return event.getMDCPropertyMap(); - } - - @Override - public String toString() { - return event.toString(); - } -} diff --git a/instrumentation/logback/logback-mdc-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/mdc/v1_0/OpenTelemetryAppender.java b/instrumentation/logback/logback-mdc-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/mdc/v1_0/OpenTelemetryAppender.java index caf4ea3567..17bf842f49 100644 --- a/instrumentation/logback/logback-mdc-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/mdc/v1_0/OpenTelemetryAppender.java +++ b/instrumentation/logback/logback-mdc-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/mdc/v1_0/OpenTelemetryAppender.java @@ -10,6 +10,7 @@ import static io.opentelemetry.instrumentation.api.log.LoggingContextConstants.T import static io.opentelemetry.instrumentation.api.log.LoggingContextConstants.TRACE_ID; import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.classic.spi.LoggerContextVO; import ch.qos.logback.core.Appender; import ch.qos.logback.core.UnsynchronizedAppenderBase; import ch.qos.logback.core.spi.AppenderAttachable; @@ -17,6 +18,7 @@ import ch.qos.logback.core.spi.AppenderAttachableImpl; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.instrumentation.logback.mdc.v1_0.internal.UnionMap; +import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -49,8 +51,25 @@ public class OpenTelemetryAppender extends UnsynchronizedAppenderBase(eventContext, contextData); } + Map eventContextMap = eventContext; + LoggerContextVO oldVo = event.getLoggerContextVO(); + LoggerContextVO vo = + oldVo != null + ? new LoggerContextVO(oldVo.getName(), eventContextMap, oldVo.getBirthTime()) + : null; - return new LoggingEventWrapper(event, eventContext); + return (ILoggingEvent) + Proxy.newProxyInstance( + ILoggingEvent.class.getClassLoader(), + new Class[] {ILoggingEvent.class}, + (proxy, method, args) -> { + if ("getMDCPropertyMap".equals(method.getName())) { + return eventContextMap; + } else if ("getLoggerContextVO".equals(method.getName())) { + return vo; + } + return method.invoke(event, args); + }); } @Override