-
Notifications
You must be signed in to change notification settings - Fork 290
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update OpenTelemetry Bridge to support OTel Java API 0.11.0 #2054
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,38 @@ | ||
ext { | ||
minJavaVersionForTests = JavaVersion.VERSION_1_8 | ||
} | ||
|
||
// Made this a variable so we can easily update to latest releases. | ||
def otelVersion = '0.3.0' | ||
def otelVersion = '0.11.0' | ||
|
||
muzzle { | ||
pass { | ||
module = 'opentelemetry-api' | ||
group = 'io.opentelemetry' | ||
versions = "[$otelVersion,0.8.0)" | ||
versions = "[$otelVersion,]" | ||
assertInverse = true | ||
// I have no idea why gradle doesn't respect the version range above | ||
// but I also have no time to figure it out for an instrumentation | ||
// that is experimental | ||
skipVersions = ['0.2.2', '0.2.3', '0.9.0'] | ||
} | ||
} | ||
|
||
apply from: "$rootDir/gradle/java.gradle" | ||
|
||
apply plugin: 'org.unbroken-dome.test-sets' | ||
|
||
testSets { | ||
latestDepTest { | ||
dirName = 'test' | ||
} | ||
} | ||
// Can't have a latest test until a new version is released. | ||
//apply plugin: 'org.unbroken-dome.test-sets' | ||
// | ||
//testSets { | ||
// latestDepTest { | ||
// dirName = 'test' | ||
// } | ||
//} | ||
|
||
dependencies { | ||
compileOnly group: 'io.opentelemetry', name: 'opentelemetry-api', version: otelVersion | ||
main_java8CompileOnly group: 'io.opentelemetry', name: 'opentelemetry-api', version: otelVersion | ||
|
||
compileOnly group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.2' | ||
compileOnly group: 'com.google.auto.value', name: 'auto-value-annotations', version: '1.6.6' | ||
main_java8CompileOnly group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.2' | ||
main_java8CompileOnly group: 'com.google.auto.value', name: 'auto-value-annotations', version: '1.6.6' | ||
|
||
testCompile group: 'io.opentelemetry', name: 'opentelemetry-api', version: otelVersion | ||
latestDepTestCompile group: 'io.opentelemetry', name: 'opentelemetry-api', version: '0.7+' | ||
// latestDepTestCompile group: 'io.opentelemetry', name: 'opentelemetry-api', version: '0.7+' | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,17 @@ | ||
package datadog.trace.instrumentation.opentelemetry; | ||
|
||
import static datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers.implementsInterface; | ||
import static java.util.Collections.singletonMap; | ||
import static net.bytebuddy.matcher.ElementMatchers.named; | ||
import static net.bytebuddy.matcher.ElementMatchers.returns; | ||
import static net.bytebuddy.matcher.ElementMatchers.takesNoArguments; | ||
|
||
import com.google.auto.service.AutoService; | ||
import datadog.trace.agent.tooling.Instrumenter; | ||
import io.opentelemetry.context.propagation.ContextPropagators; | ||
import io.opentelemetry.trace.TracerProvider; | ||
import java.util.HashMap; | ||
import datadog.trace.bootstrap.ContextStore; | ||
import datadog.trace.bootstrap.InstrumentationContext; | ||
import datadog.trace.bootstrap.instrumentation.api.AgentSpan; | ||
import io.opentelemetry.api.OpenTelemetryBuilder; | ||
import io.opentelemetry.api.trace.SpanContext; | ||
import java.util.Map; | ||
import net.bytebuddy.asm.Advice; | ||
import net.bytebuddy.description.method.MethodDescription; | ||
|
@@ -30,58 +34,47 @@ protected boolean defaultEnabled() { | |
|
||
@Override | ||
public ElementMatcher<TypeDescription> typeMatcher() { | ||
return named("io.opentelemetry.OpenTelemetry"); | ||
return implementsInterface(named("io.opentelemetry.api.OpenTelemetryBuilder")); | ||
} | ||
|
||
@Override | ||
public String[] helperClassNames() { | ||
return new String[] { | ||
packageName + ".OtelScope", | ||
packageName + ".OtelSpan", | ||
packageName + ".OtelSpan$1", // switch statement | ||
packageName + ".OtelSpanContext", | ||
packageName + ".OtelTracer", | ||
packageName + ".OtelTracer$1", // switch statement | ||
packageName + ".OtelTracerProvider", | ||
packageName + ".OtelTracer$SpanBuilder", | ||
packageName + ".OtelTracer$OtelSpanBuilder", | ||
packageName + ".OtelContextPropagators", | ||
packageName + ".OtelContextPropagators$1", // switch statement | ||
packageName + ".OtelContextPropagators$OtelHttpTextFormat", | ||
packageName + ".OtelContextPropagators$OtelTextMapPropagator", | ||
packageName + ".OtelContextPropagators$OtelSetter", | ||
packageName + ".OtelContextPropagators$OtelGetter", | ||
packageName + ".TypeConverter", | ||
packageName + ".TypeConverter$OtelSpanContext" | ||
}; | ||
} | ||
|
||
@Override | ||
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() { | ||
final Map<ElementMatcher<? super MethodDescription>, String> transformers = new HashMap<>(); | ||
transformers.put( | ||
named("getTracerProvider").and(returns(named("io.opentelemetry.trace.TracerProvider"))), | ||
OpenTelemetryInstrumentation.class.getName() + "$TracerProviderAdvice"); | ||
transformers.put( | ||
named("getPropagators") | ||
.and(returns(named("io.opentelemetry.context.propagation.ContextPropagators"))), | ||
OpenTelemetryInstrumentation.class.getName() + "$ContextPropagatorsAdvice"); | ||
return transformers; | ||
return singletonMap( | ||
named("build").and(takesNoArguments()), | ||
OpenTelemetryInstrumentation.class.getName() + "$BuilderAdvice"); | ||
} | ||
|
||
public static class TracerProviderAdvice { | ||
@Advice.OnMethodExit(suppress = Throwable.class) | ||
public static void returnProvider(@Advice.Return(readOnly = false) TracerProvider result) { | ||
result = OtelTracerProvider.INSTANCE; | ||
} | ||
@Override | ||
public Map<String, String> contextStore() { | ||
return singletonMap( | ||
"io.opentelemetry.api.trace.SpanContext", AgentSpan.Context.class.getName()); | ||
} | ||
|
||
public static class ContextPropagatorsAdvice { | ||
@Advice.OnMethodExit(suppress = Throwable.class) | ||
public static void returnProvider(@Advice.Return(readOnly = false) ContextPropagators result) { | ||
result = OtelContextPropagators.INSTANCE; | ||
} | ||
|
||
// Muzzle doesn't detect the advice method's argument type, so we have to help it a bit. | ||
public static void muzzleCheck(final ContextPropagators propagators) { | ||
propagators.getHttpTextFormat(); | ||
public static class BuilderAdvice { | ||
@Advice.OnMethodEnter(suppress = Throwable.class) | ||
public static void beforeBuild(@Advice.This OpenTelemetryBuilder builder) { | ||
ContextStore<SpanContext, AgentSpan.Context> spanContextStore = | ||
InstrumentationContext.get(SpanContext.class, AgentSpan.Context.class); | ||
builder.setTracerProvider(new OtelTracerProvider(spanContextStore)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How deeply does OTelTracerProvider & OTelContextPropagators get checked by muzzle? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see both classes enumerated in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want to know how deeply we check that OTelTracerProvider and OtelContextPropagators fit the latest OTel API. For instance, do we check that OTelTracerProvider implements all the necessary methods. Otherwise, I think this has holes where we'll activate when we shouldn't. I think that is what happened recently with servlet-3.1. Mostly, I'm just curious, and I'm fine with addressing that issue in a separate PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Muzzle is validating those classes right now, but we have known issues with the depth that muzzle validates. I don't think that is specific to this PR. I suggest we schedule a separate effort for improving muzzle. |
||
builder.setPropagators(new OtelContextPropagators(spanContextStore)); | ||
} | ||
} | ||
} |
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why. Care to elaborate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our
latestDepTest
has an assertion to verify that the version it is testing isn't the same as what is verified intest
to ensure we declare the wildcard properly. There is a new version out now (0.10.1
), so I can fix this.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that
assert
is counterproductive. I would have updated the gRPC instrumentation when I had time if it weren't for this.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before I added that, we had cases where we thought we were testing something new but were not. The assertion was an attempt to prevent a regression. Seems silly to run the same tests twice.