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:
parent
dbb1b7ff03
commit
36af04266a
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue