Migrate RMI instrumentation to Instrumenter API (#4579)
This commit is contained in:
parent
a7e3696176
commit
a9ed1ae030
|
@ -9,6 +9,9 @@ muzzle {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("com.google.auto.value:auto-value-annotations")
|
||||
annotationProcessor("com.google.auto.value:auto-value")
|
||||
|
||||
compileOnly(project(":instrumentation:rmi:bootstrap"))
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.rmi.client;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.rpc.RpcAttributesExtractor;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
final class RmiClientAttributesExtractor extends RpcAttributesExtractor<Method, Void> {
|
||||
|
||||
@Override
|
||||
protected String system(Method method) {
|
||||
return "java_rmi";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String service(Method method) {
|
||||
return method.getDeclaringClass().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String method(Method method) {
|
||||
return method.getName();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.rmi.client;
|
||||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.rpc.RpcSpanNameExtractor;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public final class RmiClientSingletons {
|
||||
|
||||
private static final Instrumenter<Method, Void> INSTRUMENTER;
|
||||
|
||||
static {
|
||||
RmiClientAttributesExtractor attributesExtractor = new RmiClientAttributesExtractor();
|
||||
|
||||
INSTRUMENTER =
|
||||
Instrumenter.<Method, Void>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
"io.opentelemetry.rmi",
|
||||
RpcSpanNameExtractor.create(attributesExtractor))
|
||||
.addAttributesExtractor(attributesExtractor)
|
||||
.newInstrumenter(SpanKindExtractor.alwaysClient());
|
||||
}
|
||||
|
||||
public static Instrumenter<Method, Void> instrumenter() {
|
||||
return INSTRUMENTER;
|
||||
}
|
||||
|
||||
private RmiClientSingletons() {}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.rmi.client;
|
||||
|
||||
import static io.opentelemetry.api.trace.SpanKind.CLIENT;
|
||||
|
||||
import io.opentelemetry.api.trace.Span;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.instrumentation.api.tracer.RpcClientTracer;
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class RmiClientTracer extends RpcClientTracer {
|
||||
private static final RmiClientTracer TRACER = new RmiClientTracer();
|
||||
|
||||
public static RmiClientTracer tracer() {
|
||||
return TRACER;
|
||||
}
|
||||
|
||||
public Context startSpan(Method method) {
|
||||
Context parentContext = Context.current();
|
||||
String serviceName = method.getDeclaringClass().getName();
|
||||
String methodName = method.getName();
|
||||
|
||||
Span span =
|
||||
spanBuilder(parentContext, serviceName + "/" + methodName, CLIENT)
|
||||
.setAttribute(SemanticAttributes.RPC_SYSTEM, getRpcSystem())
|
||||
.setAttribute(SemanticAttributes.RPC_SERVICE, serviceName)
|
||||
.setAttribute(SemanticAttributes.RPC_METHOD, methodName)
|
||||
.startSpan();
|
||||
|
||||
return parentContext.with(span);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getInstrumentationName() {
|
||||
return "io.opentelemetry.rmi";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getRpcSystem() {
|
||||
return "java_rmi";
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
package io.opentelemetry.javaagent.instrumentation.rmi.client;
|
||||
|
||||
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.extendsClass;
|
||||
import static io.opentelemetry.javaagent.instrumentation.rmi.client.RmiClientTracer.tracer;
|
||||
import static io.opentelemetry.javaagent.instrumentation.rmi.client.RmiClientSingletons.instrumenter;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||
|
@ -46,28 +46,33 @@ public class UnicastRefInstrumentation implements TypeInstrumentation {
|
|||
@Advice.Local("otelContext") Context context,
|
||||
@Advice.Local("otelScope") Scope scope) {
|
||||
|
||||
// TODO replace with client span check
|
||||
if (!Java8BytecodeBridge.currentSpan().getSpanContext().isValid()) {
|
||||
Context parentContext = Java8BytecodeBridge.currentContext();
|
||||
|
||||
// TODO replace with client span check - this is a bit different condition though, can we
|
||||
// remove it?
|
||||
if (!Java8BytecodeBridge.spanFromContext(parentContext).getSpanContext().isValid()) {
|
||||
return;
|
||||
}
|
||||
context = tracer().startSpan(method);
|
||||
if (!instrumenter().shouldStart(parentContext, method)) {
|
||||
return;
|
||||
}
|
||||
|
||||
context = instrumenter().start(parentContext, method);
|
||||
scope = context.makeCurrent();
|
||||
}
|
||||
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void stopSpan(
|
||||
@Advice.Argument(value = 1) Method method,
|
||||
@Advice.Thrown Throwable throwable,
|
||||
@Advice.Local("otelContext") Context context,
|
||||
@Advice.Local("otelScope") Scope scope) {
|
||||
|
||||
if (scope == null) {
|
||||
return;
|
||||
}
|
||||
scope.close();
|
||||
if (throwable != null) {
|
||||
tracer().endExceptionally(context, throwable);
|
||||
} else {
|
||||
tracer().end(context);
|
||||
}
|
||||
instrumenter().end(context, method, null, throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
package io.opentelemetry.javaagent.instrumentation.rmi.context;
|
||||
|
||||
import static io.opentelemetry.javaagent.instrumentation.rmi.client.RmiClientTracer.tracer;
|
||||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.propagation.TextMapGetter;
|
||||
import io.opentelemetry.context.propagation.TextMapSetter;
|
||||
|
@ -24,11 +23,9 @@ public class ContextPayload {
|
|||
private static final Logger logger = LoggerFactory.getLogger(ContextPayload.class);
|
||||
|
||||
private final Map<String, String> context;
|
||||
public static final ExtractAdapter GETTER = new ExtractAdapter();
|
||||
public static final ContextPayloadSetter SETTER = ContextPayloadSetter.INSTANCE;
|
||||
|
||||
public ContextPayload() {
|
||||
context = new HashMap<>();
|
||||
this(new HashMap<>());
|
||||
}
|
||||
|
||||
public ContextPayload(Map<String, String> context) {
|
||||
|
@ -37,7 +34,9 @@ public class ContextPayload {
|
|||
|
||||
public static ContextPayload from(Context context) {
|
||||
ContextPayload payload = new ContextPayload();
|
||||
tracer().inject(context, payload, SETTER);
|
||||
GlobalOpenTelemetry.getPropagators()
|
||||
.getTextMapPropagator()
|
||||
.inject(context, payload, ContextPayloadSetter.INSTANCE);
|
||||
return payload;
|
||||
}
|
||||
|
||||
|
@ -54,32 +53,36 @@ public class ContextPayload {
|
|||
return null;
|
||||
}
|
||||
|
||||
public Map<String, String> getSpanContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public void write(ObjectOutput out) throws IOException {
|
||||
out.writeObject(context);
|
||||
}
|
||||
|
||||
public static class ExtractAdapter implements TextMapGetter<ContextPayload> {
|
||||
public Context extract() {
|
||||
return GlobalOpenTelemetry.getPropagators()
|
||||
.getTextMapPropagator()
|
||||
.extract(Context.root(), this, ContextPayloadGetter.INSTANCE);
|
||||
}
|
||||
|
||||
private enum ContextPayloadGetter implements TextMapGetter<ContextPayload> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public Iterable<String> keys(ContextPayload contextPayload) {
|
||||
return contextPayload.getSpanContext().keySet();
|
||||
return contextPayload.context.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get(ContextPayload carrier, String key) {
|
||||
return carrier.getSpanContext().get(key);
|
||||
return carrier.context.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
enum ContextPayloadSetter implements TextMapSetter<ContextPayload> {
|
||||
private enum ContextPayloadSetter implements TextMapSetter<ContextPayload> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public void set(ContextPayload carrier, String key, String value) {
|
||||
carrier.getSpanContext().put(key, value);
|
||||
carrier.context.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,8 @@
|
|||
package io.opentelemetry.javaagent.instrumentation.rmi.context.server;
|
||||
|
||||
import static io.opentelemetry.javaagent.bootstrap.rmi.ThreadLocalContext.THREAD_LOCAL_CONTEXT;
|
||||
import static io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPayload.GETTER;
|
||||
import static io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPropagator.CONTEXT_CALL_ID;
|
||||
import static io.opentelemetry.javaagent.instrumentation.rmi.context.ContextPropagator.PROPAGATOR;
|
||||
import static io.opentelemetry.javaagent.instrumentation.rmi.server.RmiServerTracer.tracer;
|
||||
|
||||
import io.opentelemetry.api.trace.Span;
|
||||
import io.opentelemetry.api.trace.SpanContext;
|
||||
|
@ -51,7 +49,7 @@ public class ContextDispatcher implements Dispatcher {
|
|||
if (PROPAGATOR.isOperationWithPayload(operationId)) {
|
||||
ContextPayload payload = ContextPayload.read(in);
|
||||
if (payload != null) {
|
||||
Context context = tracer().extract(payload, GETTER);
|
||||
Context context = payload.extract();
|
||||
SpanContext spanContext = Span.fromContext(context).getSpanContext();
|
||||
if (spanContext.isValid()) {
|
||||
THREAD_LOCAL_CONTEXT.set(context);
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.rmi.server;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
|
||||
@AutoValue
|
||||
public abstract class ClassAndMethod {
|
||||
|
||||
public static ClassAndMethod create(Class<?> declaringClass, String methodName) {
|
||||
return new AutoValue_ClassAndMethod(declaringClass, methodName);
|
||||
}
|
||||
|
||||
public abstract Class<?> declaringClass();
|
||||
|
||||
public abstract String methodName();
|
||||
}
|
|
@ -7,7 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.rmi.server;
|
|||
|
||||
import static io.opentelemetry.javaagent.bootstrap.rmi.ThreadLocalContext.THREAD_LOCAL_CONTEXT;
|
||||
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.extendsClass;
|
||||
import static io.opentelemetry.javaagent.instrumentation.rmi.server.RmiServerTracer.tracer;
|
||||
import static io.opentelemetry.javaagent.instrumentation.rmi.server.RmiServerSingletons.instrumenter;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isStatic;
|
||||
|
@ -19,7 +19,6 @@ import io.opentelemetry.context.Scope;
|
|||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
|
||||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
|
||||
import io.opentelemetry.javaagent.instrumentation.api.CallDepth;
|
||||
import java.lang.reflect.Method;
|
||||
import java.rmi.server.RemoteServer;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
|
@ -43,10 +42,13 @@ public class RemoteServerInstrumentation implements TypeInstrumentation {
|
|||
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static void onEnter(
|
||||
@Advice.Origin Method method,
|
||||
@Advice.Origin("#t") Class<?> declaringClass,
|
||||
@Advice.Origin("#m") String methodName,
|
||||
@Advice.Local("otelCallDepth") CallDepth callDepth,
|
||||
@Advice.Local("otelRequest") ClassAndMethod request,
|
||||
@Advice.Local("otelContext") Context context,
|
||||
@Advice.Local("otelScope") Scope scope) {
|
||||
|
||||
callDepth = CallDepth.forClass(RemoteServer.class);
|
||||
if (callDepth.getAndIncrement() > 0) {
|
||||
return;
|
||||
|
@ -54,8 +56,12 @@ public class RemoteServerInstrumentation implements TypeInstrumentation {
|
|||
|
||||
// TODO review and unify with all other SERVER instrumentation
|
||||
Context parentContext = THREAD_LOCAL_CONTEXT.getAndResetContext();
|
||||
request = ClassAndMethod.create(declaringClass, methodName);
|
||||
if (!instrumenter().shouldStart(parentContext, request)) {
|
||||
return;
|
||||
}
|
||||
|
||||
context = tracer().startSpan(parentContext, method);
|
||||
context = instrumenter().start(parentContext, request);
|
||||
scope = context.makeCurrent();
|
||||
}
|
||||
|
||||
|
@ -63,18 +69,18 @@ public class RemoteServerInstrumentation implements TypeInstrumentation {
|
|||
public static void stopSpan(
|
||||
@Advice.Thrown Throwable throwable,
|
||||
@Advice.Local("otelCallDepth") CallDepth callDepth,
|
||||
@Advice.Local("otelRequest") ClassAndMethod request,
|
||||
@Advice.Local("otelContext") Context context,
|
||||
@Advice.Local("otelScope") Scope scope) {
|
||||
|
||||
if (callDepth.decrementAndGet() > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
scope.close();
|
||||
if (throwable != null) {
|
||||
RmiServerTracer.tracer().endExceptionally(context, throwable);
|
||||
} else {
|
||||
RmiServerTracer.tracer().end(context);
|
||||
if (scope == null) {
|
||||
return;
|
||||
}
|
||||
scope.close();
|
||||
instrumenter().end(context, request, null, throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.rmi.server;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.rpc.RpcAttributesExtractor;
|
||||
|
||||
final class RmiServerAttributesExtractor extends RpcAttributesExtractor<ClassAndMethod, Void> {
|
||||
|
||||
@Override
|
||||
protected String system(ClassAndMethod classAndMethod) {
|
||||
return "java_rmi";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String service(ClassAndMethod classAndMethod) {
|
||||
return classAndMethod.declaringClass().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String method(ClassAndMethod classAndMethod) {
|
||||
return classAndMethod.methodName();
|
||||
}
|
||||
}
|
|
@ -13,9 +13,9 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
|
|||
import java.util.List;
|
||||
|
||||
@AutoService(InstrumentationModule.class)
|
||||
public class RmiServerInstrumentation extends InstrumentationModule {
|
||||
public class RmiServerInstrumentationModule extends InstrumentationModule {
|
||||
|
||||
public RmiServerInstrumentation() {
|
||||
public RmiServerInstrumentationModule() {
|
||||
super("rmi", "rmi-server");
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.rmi.server;
|
||||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.rpc.RpcSpanNameExtractor;
|
||||
|
||||
public final class RmiServerSingletons {
|
||||
|
||||
private static final Instrumenter<ClassAndMethod, Void> INSTRUMENTER;
|
||||
|
||||
static {
|
||||
RmiServerAttributesExtractor attributesExtractor = new RmiServerAttributesExtractor();
|
||||
|
||||
INSTRUMENTER =
|
||||
Instrumenter.<ClassAndMethod, Void>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
"io.opentelemetry.rmi",
|
||||
RpcSpanNameExtractor.create(attributesExtractor))
|
||||
.addAttributesExtractor(attributesExtractor)
|
||||
.newInstrumenter(SpanKindExtractor.alwaysServer());
|
||||
}
|
||||
|
||||
public static Instrumenter<ClassAndMethod, Void> instrumenter() {
|
||||
return INSTRUMENTER;
|
||||
}
|
||||
|
||||
private RmiServerSingletons() {}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.rmi.server;
|
||||
|
||||
import static io.opentelemetry.api.trace.SpanKind.SERVER;
|
||||
|
||||
import io.opentelemetry.api.trace.SpanBuilder;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.context.propagation.TextMapGetter;
|
||||
import io.opentelemetry.instrumentation.api.tracer.RpcServerTracer;
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class RmiServerTracer extends RpcServerTracer {
|
||||
private static final RmiServerTracer TRACER = new RmiServerTracer();
|
||||
|
||||
public static RmiServerTracer tracer() {
|
||||
return TRACER;
|
||||
}
|
||||
|
||||
public Context startSpan(Context parentContext, Method method) {
|
||||
String serviceName = method.getDeclaringClass().getName();
|
||||
String methodName = method.getName();
|
||||
|
||||
SpanBuilder spanBuilder =
|
||||
spanBuilder(parentContext, serviceName + "/" + methodName, SERVER)
|
||||
.setAttribute(SemanticAttributes.RPC_SYSTEM, "java_rmi")
|
||||
.setAttribute(SemanticAttributes.RPC_SERVICE, serviceName)
|
||||
.setAttribute(SemanticAttributes.RPC_METHOD, methodName);
|
||||
return parentContext.with(spanBuilder.startSpan());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TextMapGetter getGetter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getInstrumentationName() {
|
||||
return "io.opentelemetry.rmi";
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue