-
Notifications
You must be signed in to change notification settings - Fork 850
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds opencensus-shim instrumentation
- Loading branch information
Showing
9 changed files
with
364 additions
and
0 deletions.
There are no files selected for viewing
20 changes: 20 additions & 0 deletions
20
instrumentation/opencensus-shim/javaagent/build.gradle.kts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
plugins { | ||
id("otel.javaagent-instrumentation") | ||
} | ||
|
||
muzzle { | ||
pass { | ||
group.set("io.opentelemetry") | ||
module.set("opentelemetry-opencensus-shim") | ||
versions.set("[1.18.0-alpha,)") | ||
} | ||
} | ||
|
||
dependencies { | ||
compileOnly("io.opentelemetry:opentelemetry-opencensus-shim") | ||
compileOnly(project(":opentelemetry-api-shaded-for-instrumenting", configuration = "shadow")) | ||
|
||
testImplementation(project(":instrumentation:opencensus-shim:testing")) | ||
testInstrumentation(project(":instrumentation:opencensus-shim:testing")) | ||
testImplementation(project(":opentelemetry-api-shaded-for-instrumenting", configuration = "shadow")) | ||
} |
14 changes: 14 additions & 0 deletions
14
.../javaagent/src/main/java/application/io/opentelemetry/api/trace/ExternSpanContextKey.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package application.io.opentelemetry.api.trace; | ||
|
||
import application.io.opentelemetry.context.ContextKey; | ||
|
||
public class ExternSpanContextKey { | ||
public static final ContextKey<Span> KEY = SpanContextKey.KEY; | ||
|
||
private ExternSpanContextKey() {} | ||
} |
139 changes: 139 additions & 0 deletions
139
...census-shim/javaagent/src/main/java/io/opentelemetry/opencensusshim/ContextExtractor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.opencensusshim; | ||
|
||
import application.io.opentelemetry.api.trace.Span; | ||
import application.io.opentelemetry.context.Context; | ||
import application.io.opentelemetry.context.ContextKey; | ||
import application.io.opentelemetry.context.ImplicitContextKeyed; | ||
import application.io.opentelemetry.context.Scope; | ||
import com.google.errorprone.annotations.MustBeClosed; | ||
import java.lang.reflect.Field; | ||
import java.util.concurrent.Callable; | ||
import java.util.concurrent.Executor; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.ScheduledExecutorService; | ||
import java.util.function.BiConsumer; | ||
import java.util.function.BiFunction; | ||
import java.util.function.Consumer; | ||
import java.util.function.Function; | ||
import java.util.function.Supplier; | ||
import javax.annotation.Nullable; | ||
|
||
// I can't begin to describe how much I dislike all this :( | ||
public final class ContextExtractor implements Context { | ||
|
||
private static final Field otelSpanField; | ||
|
||
static { | ||
try { | ||
otelSpanField = OpenTelemetrySpanImpl.class.getDeclaredField("otelSpan"); | ||
} catch (NoSuchFieldException e) { | ||
throw new IllegalStateException(e); | ||
} | ||
otelSpanField.setAccessible(true); | ||
} | ||
|
||
private final Context ref; | ||
|
||
public ContextExtractor(Context appCtx) { | ||
this.ref = appCtx; | ||
} | ||
|
||
@Override | ||
public <V> Context with(ContextKey<V> k1, V v1) { | ||
if (v1 instanceof OpenTelemetrySpanImpl) { | ||
Span otelSpan = null; | ||
try { | ||
otelSpan = (Span) otelSpanField.get(v1); | ||
} catch (IllegalAccessException e) { | ||
throw new IllegalStateException(e); | ||
} | ||
return ref.with(otelSpan); | ||
} | ||
return ref.with(k1, v1); | ||
} | ||
|
||
@Override | ||
public Context with(ImplicitContextKeyed value) { | ||
if (value instanceof OpenTelemetrySpanImpl) { | ||
Span otelSpan = null; | ||
try { | ||
otelSpan = (Span) otelSpanField.get(value); | ||
} catch (IllegalAccessException e) { | ||
throw new IllegalStateException(e); | ||
} | ||
return ref.with(otelSpan); | ||
} | ||
return ref.with(value); | ||
} | ||
|
||
// | ||
// delegates | ||
// | ||
|
||
@Nullable | ||
@Override | ||
public <V> V get(ContextKey<V> key) { | ||
return ref.get(key); | ||
} | ||
|
||
@Override | ||
@MustBeClosed | ||
public Scope makeCurrent() { | ||
return ref.makeCurrent(); | ||
} | ||
|
||
@Override | ||
public Runnable wrap(Runnable runnable) { | ||
return ref.wrap(runnable); | ||
} | ||
|
||
@Override | ||
public <T> Callable<T> wrap(Callable<T> callable) { | ||
return ref.wrap(callable); | ||
} | ||
|
||
@Override | ||
public Executor wrap(Executor executor) { | ||
return ref.wrap(executor); | ||
} | ||
|
||
@Override | ||
public ExecutorService wrap(ExecutorService executor) { | ||
return ref.wrap(executor); | ||
} | ||
|
||
@Override | ||
public ScheduledExecutorService wrap(ScheduledExecutorService executor) { | ||
return ref.wrap(executor); | ||
} | ||
|
||
@Override | ||
public <T, U> Function<T, U> wrapFunction(Function<T, U> function) { | ||
return ref.wrapFunction(function); | ||
} | ||
|
||
@Override | ||
public <T, U, V> BiFunction<T, U, V> wrapFunction(BiFunction<T, U, V> function) { | ||
return ref.wrapFunction(function); | ||
} | ||
|
||
@Override | ||
public <T> Consumer<T> wrapConsumer(Consumer<T> consumer) { | ||
return ref.wrapConsumer(consumer); | ||
} | ||
|
||
@Override | ||
public <T, U> BiConsumer<T, U> wrapConsumer(BiConsumer<T, U> consumer) { | ||
return ref.wrapConsumer(consumer); | ||
} | ||
|
||
@Override | ||
public <T> Supplier<T> wrapSupplier(Supplier<T> supplier) { | ||
return ref.wrapSupplier(supplier); | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
...aagent/src/main/java/io/opentelemetry/opencensusshim/OpenTelemetryCtxInstrumentation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.opencensusshim; | ||
|
||
import static net.bytebuddy.matcher.ElementMatchers.isConstructor; | ||
import static net.bytebuddy.matcher.ElementMatchers.named; | ||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument; | ||
|
||
import application.io.opentelemetry.context.Context; | ||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; | ||
import net.bytebuddy.asm.Advice; | ||
import net.bytebuddy.description.type.TypeDescription; | ||
import net.bytebuddy.matcher.ElementMatcher; | ||
|
||
/** | ||
* Doctors the {@link OpenTelemetryCtx} constructor to provide a delegating wrapper for the provided | ||
* {@link Context} which very specifically singles out the {@link OpenTelemetrySpanImpl} shortcoming | ||
* upon calling the {@link Context#with} methods. | ||
* | ||
* <p>The "with" methods then extract the internal otel span and pass it along for processing as | ||
* normal as, sadly, the Java Agent instrumentations all <i>require</i> the agent-generated | ||
* <i>instance</i>: interface conformance is simply not enough when the java agent is in the mix as | ||
* it uses data stored in specialized instances of {@link | ||
* application.io.opentelemetry.api.trace.Span} to perform its duties. | ||
*/ | ||
public class OpenTelemetryCtxInstrumentation implements TypeInstrumentation { | ||
@Override | ||
public ElementMatcher<TypeDescription> typeMatcher() { | ||
return named("io.opentelemetry.opencensusshim.OpenTelemetryCtx"); | ||
} | ||
|
||
@Override | ||
public void transform(TypeTransformer transformer) { | ||
transformer.applyAdviceToMethod( | ||
isConstructor() | ||
.and(takesArgument(0, named("application.io.opentelemetry.context.Context"))), | ||
OpenTelemetryCtxInstrumentation.class.getName() + "$HandleConstruction"); | ||
} | ||
|
||
@SuppressWarnings({"unused", "OtelPrivateConstructorForUtilityClass"}) | ||
public static class HandleConstruction { | ||
|
||
@Advice.OnMethodEnter(suppress = Throwable.class) | ||
public static void constructor(@Advice.Argument(value = 0, readOnly = false) Context context) { | ||
context = new ContextExtractor(context); | ||
} | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
...nt/src/main/java/io/opentelemetry/opencensusshim/OpencensusShimInstrumentationModule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.opencensusshim; | ||
|
||
import com.google.auto.service.AutoService; | ||
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; | ||
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
@AutoService(InstrumentationModule.class) | ||
public class OpencensusShimInstrumentationModule extends InstrumentationModule { | ||
|
||
public OpencensusShimInstrumentationModule() { | ||
super("opencensusshim", "io.opentelemetry.opencensusshim"); | ||
} | ||
|
||
@Override | ||
public List<TypeInstrumentation> typeInstrumentations() { | ||
return Arrays.asList(new OpenTelemetryCtxInstrumentation()); | ||
} | ||
|
||
@Override | ||
public boolean isHelperClass(String className) { | ||
return className.equals("io.opentelemetry.opencensusshim.ContextExtractor"); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
.../javaagent/src/test/java/io/opentelemetry/opencensusshim/OpenCensusShimJavaAgentTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.opencensusshim; | ||
|
||
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; | ||
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; | ||
import org.junit.jupiter.api.extension.RegisterExtension; | ||
|
||
public class OpenCensusShimJavaAgentTest extends AbstractOpenCensusShimTest { | ||
|
||
@RegisterExtension | ||
static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); | ||
|
||
@Override | ||
protected InstrumentationExtension testing() { | ||
return testing; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
plugins { | ||
id("otel.library-instrumentation") | ||
id("otel.nullaway-conventions") | ||
} | ||
|
||
dependencies { | ||
api("io.opentelemetry:opentelemetry-opencensus-shim") | ||
|
||
api(project(":testing-common")) | ||
} |
57 changes: 57 additions & 0 deletions
57
...him/testing/src/main/java/io/opentelemetry/opencensusshim/AbstractOpenCensusShimTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.opencensusshim; | ||
|
||
import io.opencensus.trace.AttributeValue; | ||
import io.opencensus.trace.Tracing; | ||
import io.opentelemetry.api.common.AttributeKey; | ||
import io.opentelemetry.api.common.Attributes; | ||
import io.opentelemetry.api.trace.Span; | ||
import io.opentelemetry.api.trace.SpanKind; | ||
import io.opentelemetry.api.trace.Tracer; | ||
import io.opentelemetry.context.Scope; | ||
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; | ||
import org.junit.jupiter.api.Test; | ||
|
||
public abstract class AbstractOpenCensusShimTest { | ||
|
||
protected abstract InstrumentationExtension testing(); | ||
|
||
@Test | ||
void testCrossOtelOcBoundary() { | ||
Tracer tracer = testing().getOpenTelemetry().getTracer("unidentified"); | ||
Span span = tracer.spanBuilder("test-span").setSpanKind(SpanKind.INTERNAL).startSpan(); | ||
Scope scope = span.makeCurrent(); | ||
try { | ||
io.opencensus.trace.Tracer ocTracer = Tracing.getTracer(); | ||
io.opencensus.trace.Span internal = ocTracer.spanBuilder("internal").startSpan(); | ||
io.opencensus.common.Scope ocScope = ocTracer.withSpan(internal); | ||
try { | ||
ocTracer | ||
.getCurrentSpan() | ||
.putAttribute("internal-only", AttributeValue.booleanAttributeValue(true)); | ||
} finally { | ||
ocScope.close(); | ||
} | ||
internal.end(); | ||
} finally { | ||
scope.close(); | ||
} | ||
span.end(); | ||
|
||
testing() | ||
.waitAndAssertTraces( | ||
traceAssert -> | ||
traceAssert.hasSpansSatisfyingExactly( | ||
spanAssert -> spanAssert.hasName("test-span").hasNoParent(), | ||
spanAssert -> | ||
spanAssert | ||
.hasName("internal") | ||
.hasParentSpanId(span.getSpanContext().getSpanId()) | ||
.hasAttributes( | ||
Attributes.of(AttributeKey.booleanKey("internal-only"), true)))); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
...m/testing/src/test/java/io/opentelemetry/opencensusshim/OpenCensusShimRegressionTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.opencensusshim; | ||
|
||
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; | ||
import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension; | ||
import org.junit.jupiter.api.extension.RegisterExtension; | ||
|
||
public class OpenCensusShimRegressionTest extends AbstractOpenCensusShimTest { | ||
|
||
@RegisterExtension | ||
static final InstrumentationExtension testing = LibraryInstrumentationExtension.create(); | ||
|
||
@Override | ||
protected InstrumentationExtension testing() { | ||
return testing; | ||
} | ||
} |