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.
This commit is contained in:
Lauri Tulmin 2023-03-03 18:32:50 +02:00 committed by GitHub
parent dbb1b7ff03
commit 36af04266a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 119 deletions

View File

@ -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();
}
}

View File

@ -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);
}
Map<String, String> 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