Browse Source

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.
Lauri Tulmin 2 years ago
parent
commit
36af04266a

+ 0 - 118
instrumentation/logback/logback-mdc-1.0/library/src/main/java/io/opentelemetry/instrumentation/logback/mdc/v1_0/LoggingEventWrapper.java

@@ -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<String, String> mdcPropertyMap;
-  @Nullable private final LoggerContextVO vo;
-
-  LoggingEventWrapper(ILoggingEvent event, Map<String, String> 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<String, String> getMDCPropertyMap() {
-    return mdcPropertyMap;
-  }
-
-  /**
-   * A synonym for {@link #getMDCPropertyMap}.
-   *
-   * @deprecated Use {@link #getMDCPropertyMap()}.
-   */
-  @Override
-  @Deprecated
-  public Map<String, String> getMdc() {
-    return event.getMDCPropertyMap();
-  }
-
-  @Override
-  public String toString() {
-    return event.toString();
-  }
-}

+ 21 - 2
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<ILoggingEv
     } else {
       eventContext = new UnionMap<>(eventContext, contextData);
     }
-
-    return new LoggingEventWrapper(event, eventContext);
+    Map<String, String> eventContextMap = eventContext;
+    LoggerContextVO oldVo = event.getLoggerContextVO();
+    LoggerContextVO vo =
+        oldVo != null
+            ? new LoggerContextVO(oldVo.getName(), eventContextMap, oldVo.getBirthTime())
+            : null;
+
+    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