Bridge trace builder (#4090)

* Bridge tracer builder

* put api 1.4 bridging into separate moulde

* remove duplicate test

* remove testing dependencies

* use static import

* Update instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/trace/ApplicationTracerProvider.java

Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>

* rename make -> create

* replace reflection with methodhandle

Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
This commit is contained in:
Lauri Tulmin 2021-09-13 19:30:02 +03:00 committed by GitHub
parent f964a13fc9
commit 436184002c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 230 additions and 40 deletions

View File

@ -1,31 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace;
import application.io.opentelemetry.api.trace.Tracer;
import application.io.opentelemetry.api.trace.TracerProvider;
import io.opentelemetry.api.GlobalOpenTelemetry;
public class ApplicationTracerProvider implements TracerProvider {
private final io.opentelemetry.api.trace.TracerProvider agentTracerProvider;
public ApplicationTracerProvider(
io.opentelemetry.api.trace.TracerProvider applicationOriginalTracerProvider) {
this.agentTracerProvider = applicationOriginalTracerProvider;
}
@Override
public Tracer get(String instrumentationName) {
return new ApplicationTracer(agentTracerProvider.get(instrumentationName));
}
@Override
public Tracer get(String instrumentationName, String instrumentationVersion) {
return new ApplicationTracer(
GlobalOpenTelemetry.getTracerProvider().get(instrumentationName, instrumentationVersion));
}
}

View File

@ -24,7 +24,7 @@ dependencies {
compileOnly(project(path = ":opentelemetry-api-shaded-for-instrumenting", configuration = "shadow"))
compileOnly("io.opentelemetry:opentelemetry-api-metrics")
implementation(project(":instrumentation:opentelemetry-api-1.0:javaagent"))
implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.0:javaagent"))
testImplementation("com.google.guava:guava")
testImplementation("io.opentelemetry:opentelemetry-sdk-metrics")

View File

@ -34,6 +34,6 @@ dependencies {
testImplementation("io.opentelemetry:opentelemetry-extension-annotations")
testInstrumentation(project(":instrumentation:opentelemetry-annotations-1.0:javaagent"))
testImplementation(project(":instrumentation:opentelemetry-api-1.0:testing"))
testInstrumentation(project(":instrumentation:opentelemetry-api-1.0:testing"))
testImplementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.0:testing"))
testInstrumentation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.0:testing"))
}

View File

@ -25,7 +25,7 @@ public class ApplicationOpenTelemetry implements OpenTelemetry {
io.opentelemetry.api.OpenTelemetry agentOpenTelemetry =
io.opentelemetry.api.GlobalOpenTelemetry.get();
applicationTracerProvider =
new ApplicationTracerProvider(agentOpenTelemetry.getTracerProvider());
ApplicationTracerProvider.create(agentOpenTelemetry.getTracerProvider());
applicationContextPropagators =
new ApplicationContextPropagators(agentOpenTelemetry.getPropagators());
}

View File

@ -8,11 +8,11 @@ package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace;
import application.io.opentelemetry.api.trace.SpanBuilder;
import application.io.opentelemetry.api.trace.Tracer;
class ApplicationTracer implements Tracer {
public class ApplicationTracer implements Tracer {
private final io.opentelemetry.api.trace.Tracer agentTracer;
ApplicationTracer(io.opentelemetry.api.trace.Tracer agentTracer) {
public ApplicationTracer(io.opentelemetry.api.trace.Tracer agentTracer) {
this.agentTracer = agentTracer;
}

View File

@ -0,0 +1,64 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace;
import application.io.opentelemetry.api.trace.Tracer;
import application.io.opentelemetry.api.trace.TracerProvider;
import io.opentelemetry.api.GlobalOpenTelemetry;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
public class ApplicationTracerProvider implements TracerProvider {
private static final MethodHandle TRACE_PROVIDER_14 = getApplicationTracerProvider14();
protected final io.opentelemetry.api.trace.TracerProvider agentTracerProvider;
protected ApplicationTracerProvider(
io.opentelemetry.api.trace.TracerProvider agentTracerProvider) {
this.agentTracerProvider = agentTracerProvider;
}
private static MethodHandle getApplicationTracerProvider14() {
try {
// this class is defined in opentelemetry-api-1.4
Class<?> clazz =
Class.forName(
"io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_4.trace.ApplicationTracerProvider14");
return MethodHandles.lookup()
.findConstructor(
clazz,
MethodType.methodType(void.class, io.opentelemetry.api.trace.TracerProvider.class));
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException exception) {
return null;
}
}
public static TracerProvider create(
io.opentelemetry.api.trace.TracerProvider agentTracerProvider) {
if (TRACE_PROVIDER_14 != null) {
try {
return (TracerProvider) TRACE_PROVIDER_14.invoke(agentTracerProvider);
} catch (Throwable throwable) {
throw new IllegalStateException("Failed to create ApplicationTracerProvider", throwable);
}
}
return new ApplicationTracerProvider(agentTracerProvider);
}
@Override
public Tracer get(String instrumentationName) {
return new ApplicationTracer(agentTracerProvider.get(instrumentationName));
}
@Override
public Tracer get(String instrumentationName, String instrumentationVersion) {
return new ApplicationTracer(
GlobalOpenTelemetry.getTracerProvider().get(instrumentationName, instrumentationVersion));
}
}

View File

@ -332,4 +332,25 @@ class TracerTest extends AgentInstrumentationSpecification {
then:
Span.fromContext(context).getSpanContext().getSpanId() == span.getSpanContext().getSpanId()
}
// this test uses opentelemetry-api-1.4 instrumentation
def "test tracer builder"() {
when:
def tracer = GlobalOpenTelemetry.get().tracerBuilder("test").build()
def testSpan = tracer.spanBuilder("test").setSpanKind(PRODUCER).startSpan()
testSpan.end()
then:
assertTraces(1) {
trace(0, 1) {
span(0) {
name "test"
kind PRODUCER
hasNoParent()
attributes {
}
}
}
}
}
}

View File

@ -0,0 +1,8 @@
plugins {
id("otel.javaagent-instrumentation")
}
dependencies {
compileOnly(project(path = ":opentelemetry-api-shaded-for-instrumenting", configuration = "shadow"))
implementation(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.0:javaagent"))
}

View File

@ -0,0 +1,25 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_4;
import static java.util.Collections.singletonList;
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import java.util.List;
@AutoService(InstrumentationModule.class)
public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule {
public OpenTelemetryApiInstrumentationModule() {
super("opentelemetry-api-1.4", "opentelemetry-api");
}
@Override
public List<TypeInstrumentation> typeInstrumentations() {
return singletonList(new OpenTelemetryInstrumentation());
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_4;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.none;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_4.trace.ApplicationTracerProvider14;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
public class OpenTelemetryInstrumentation implements TypeInstrumentation {
@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return named("application.io.opentelemetry.api.GlobalOpenTelemetry");
}
@Override
public void transform(TypeTransformer transformer) {
transformer.applyAdviceToMethod(
none(), OpenTelemetryInstrumentation.class.getName() + "$InitAdvice");
}
@SuppressWarnings("unused")
public static class InitAdvice {
@Advice.OnMethodEnter
public static void init() {
// the sole purpose of this advice is to ensure that ApplicationTracerProvider14 is recognized
// as helper class and injected into class loader
ApplicationTracerProvider14.class.getName();
}
}
}

View File

@ -0,0 +1,36 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_4.trace;
import application.io.opentelemetry.api.trace.Tracer;
import application.io.opentelemetry.api.trace.TracerBuilder;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace.ApplicationTracer;
class ApplicationTracerBuilder implements TracerBuilder {
private final io.opentelemetry.api.trace.TracerBuilder agentTracerBuilder;
public ApplicationTracerBuilder(io.opentelemetry.api.trace.TracerBuilder agentTracerBuilder) {
this.agentTracerBuilder = agentTracerBuilder;
}
@Override
public TracerBuilder setSchemaUrl(String s) {
agentTracerBuilder.setSchemaUrl(s);
return this;
}
@Override
public TracerBuilder setInstrumentationVersion(String s) {
agentTracerBuilder.setSchemaUrl(s);
return this;
}
@Override
public Tracer build() {
return new ApplicationTracer(agentTracerBuilder.build());
}
}

View File

@ -0,0 +1,25 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_4.trace;
import application.io.opentelemetry.api.trace.TracerBuilder;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace.ApplicationTracerProvider;
// this class is used from opentelemetry-api-1.0 via reflection
public class ApplicationTracerProvider14 extends ApplicationTracerProvider {
// Our convention for accessing agent package
@SuppressWarnings("UnnecessarilyFullyQualified")
public ApplicationTracerProvider14(
io.opentelemetry.api.trace.TracerProvider agentTracerProvider) {
super(agentTracerProvider);
}
@Override
public TracerBuilder tracerBuilder(String instrumentationName) {
return new ApplicationTracerBuilder(agentTracerProvider.tracerBuilder(instrumentationName));
}
}

View File

@ -61,7 +61,8 @@ dependencies {
baseJavaagentLibs(project(":javaagent-tooling"))
baseJavaagentLibs(project(":muzzle"))
baseJavaagentLibs(project(":instrumentation:opentelemetry-annotations-1.0:javaagent"))
baseJavaagentLibs(project(":instrumentation:opentelemetry-api-1.0:javaagent"))
baseJavaagentLibs(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.0:javaagent"))
baseJavaagentLibs(project(":instrumentation:opentelemetry-api:opentelemetry-api-1.4:javaagent"))
baseJavaagentLibs(project(":instrumentation:executors:javaagent"))
baseJavaagentLibs(project(":instrumentation:internal:internal-class-loader:javaagent"))
baseJavaagentLibs(project(":instrumentation:internal:internal-eclipse-osgi-3.6:javaagent"))

View File

@ -252,8 +252,9 @@ include(":instrumentation:okhttp:okhttp-3.0:javaagent")
include(":instrumentation:okhttp:okhttp-3.0:library")
include(":instrumentation:okhttp:okhttp-3.0:testing")
include(":instrumentation:opentelemetry-annotations-1.0:javaagent")
include(":instrumentation:opentelemetry-api-1.0:javaagent")
include(":instrumentation:opentelemetry-api-1.0:testing")
include(":instrumentation:opentelemetry-api:opentelemetry-api-1.0:javaagent")
include(":instrumentation:opentelemetry-api:opentelemetry-api-1.0:testing")
include(":instrumentation:opentelemetry-api:opentelemetry-api-1.4:javaagent")
include(":instrumentation:opentelemetry-api-metrics-1.0:javaagent")
include(":instrumentation:oshi:javaagent")
include(":instrumentation:oshi:library")