-
Notifications
You must be signed in to change notification settings - Fork 879
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: instruments finagle's netty-based stack (#10141)
Co-authored-by: Lauri Tulmin <[email protected]>
- Loading branch information
Showing
31 changed files
with
1,341 additions
and
91 deletions.
There are no files selected for viewing
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
48 changes: 48 additions & 0 deletions
48
instrumentation/finagle-http-23.11/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,48 @@ | ||
plugins { | ||
id("otel.javaagent-instrumentation") | ||
id("otel.scala-conventions") | ||
} | ||
|
||
muzzle { | ||
pass { | ||
group.set("com.twitter") | ||
module.set("finagle-http_2.12") | ||
versions.set("[23.11.0,]") | ||
} | ||
|
||
pass { | ||
group.set("com.twitter") | ||
module.set("finagle-http_2.13") | ||
versions.set("[23.11.0,]") | ||
} | ||
} | ||
|
||
val finagleVersion = "23.11.0" | ||
val scalaVersion = "2.13.10" | ||
|
||
val scalaMinor = Regex("""^([0-9]+\.[0-9]+)\.?.*$""").find(scalaVersion)!!.run { | ||
val (minorVersion) = this.destructured | ||
minorVersion | ||
} | ||
|
||
val scalified = fun(pack: String): String { | ||
return "${pack}_$scalaMinor" | ||
} | ||
|
||
dependencies { | ||
library("${scalified("com.twitter:finagle-http")}:$finagleVersion") | ||
|
||
// should wire netty contexts | ||
testInstrumentation(project(":instrumentation:netty:netty-4.1:javaagent")) | ||
|
||
implementation(project(":instrumentation:netty:netty-4.1:javaagent")) | ||
implementation(project(":instrumentation:netty:netty-4.1:library")) | ||
implementation(project(":instrumentation:netty:netty-4-common:library")) | ||
} | ||
|
||
tasks { | ||
test { | ||
jvmArgs("-Dotel.instrumentation.http.client.emit-experimental-telemetry=true") | ||
jvmArgs("-Dotel.instrumentation.http.server.emit-experimental-telemetry=true") | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
...nagle-http-23.11/javaagent/src/main/java/com/twitter/finagle/ChannelTransportHelpers.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,17 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package com.twitter.finagle; | ||
|
||
import com.twitter.finagle.netty4.transport.ChannelTransport; | ||
|
||
/** Exposes the finagle-internal {@link ChannelTransport#HandlerName()}. */ | ||
public final class ChannelTransportHelpers { | ||
private ChannelTransportHelpers() {} | ||
|
||
public static String getHandlerName() { | ||
return ChannelTransport.HandlerName(); | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
....11/javaagent/src/main/java/io/netty/channel/OpenTelemetryChannelInitializerDelegate.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,22 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.netty.channel; | ||
|
||
/** Exists to correctly expose and propagate the {@link #initChannel(Channel)} calls. */ | ||
public abstract class OpenTelemetryChannelInitializerDelegate<T extends Channel> | ||
extends ChannelInitializer<T> { | ||
|
||
private final ChannelInitializer<T> initializer; | ||
|
||
public OpenTelemetryChannelInitializerDelegate(ChannelInitializer<T> initializer) { | ||
this.initializer = initializer; | ||
} | ||
|
||
@Override | ||
protected void initChannel(T t) throws Exception { | ||
initializer.initChannel(t); | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
...va/io/opentelemetry/javaagent/instrumentation/v23_11/ChannelTransportInstrumentation.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.javaagent.instrumentation.v23_11; | ||
|
||
import static net.bytebuddy.matcher.ElementMatchers.isMethod; | ||
import static net.bytebuddy.matcher.ElementMatchers.named; | ||
|
||
import io.opentelemetry.context.Context; | ||
import io.opentelemetry.context.Scope; | ||
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; | ||
import scala.Option; | ||
|
||
public class ChannelTransportInstrumentation implements TypeInstrumentation { | ||
@Override | ||
public ElementMatcher<TypeDescription> typeMatcher() { | ||
return named("com.twitter.finagle.netty4.transport.ChannelTransport"); | ||
} | ||
|
||
@Override | ||
public void transform(TypeTransformer transformer) { | ||
transformer.applyAdviceToMethod( | ||
isMethod().and(named("write")), | ||
ChannelTransportInstrumentation.class.getName() + "$WriteAdvice"); | ||
} | ||
|
||
@SuppressWarnings("unused") | ||
public static class WriteAdvice { | ||
|
||
@Advice.OnMethodEnter(suppress = Throwable.class) | ||
public static void methodEnter(@Advice.Local("otelScope") Scope scope) { | ||
Option<Context> ref = Helpers.CONTEXT_LOCAL.apply(); | ||
if (ref.isDefined()) { | ||
scope = ref.get().makeCurrent(); | ||
} | ||
} | ||
|
||
@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) | ||
public static void methodExit( | ||
@Advice.Local("otelScope") Scope scope, @Advice.Thrown Throwable thrown) { | ||
if (scope != null) { | ||
scope.close(); | ||
} | ||
} | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
...a/io/opentelemetry/javaagent/instrumentation/v23_11/FinagleCoreInstrumentationModule.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,34 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.instrumentation.v23_11; | ||
|
||
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 FinagleCoreInstrumentationModule extends InstrumentationModule { | ||
|
||
public FinagleCoreInstrumentationModule() { | ||
super("finagle-http"); | ||
} | ||
|
||
@Override | ||
public List<TypeInstrumentation> typeInstrumentations() { | ||
return Arrays.asList( | ||
new GenStreamingServerDispatcherInstrumentation(), | ||
new ChannelTransportInstrumentation(), | ||
new H2StreamChannelInitInstrumentation()); | ||
} | ||
|
||
@Override | ||
public boolean isHelperClass(String className) { | ||
return className.equals("com.twitter.finagle.ChannelTransportHelpers") | ||
|| className.equals("io.netty.channel.OpenTelemetryChannelInitializerDelegate"); | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
...lemetry/javaagent/instrumentation/v23_11/GenStreamingServerDispatcherInstrumentation.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,59 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.instrumentation.v23_11; | ||
|
||
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; | ||
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasSuperType; | ||
import static net.bytebuddy.matcher.ElementMatchers.isMethod; | ||
import static net.bytebuddy.matcher.ElementMatchers.named; | ||
|
||
import 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; | ||
|
||
public class GenStreamingServerDispatcherInstrumentation implements TypeInstrumentation { | ||
@Override | ||
public ElementMatcher<TypeDescription> typeMatcher() { | ||
return hasSuperType(named("com.twitter.finagle.http.GenStreamingSerialServerDispatcher")); | ||
} | ||
|
||
@Override | ||
public ElementMatcher<ClassLoader> classLoaderOptimization() { | ||
return hasClassesNamed("com.twitter.finagle.http.GenStreamingSerialServerDispatcher"); | ||
} | ||
|
||
@Override | ||
public void transform(TypeTransformer transformer) { | ||
transformer.applyAdviceToMethod( | ||
isMethod().and(named("loop")), | ||
GenStreamingServerDispatcherInstrumentation.class.getName() + "$LoopAdvice"); | ||
} | ||
|
||
@SuppressWarnings("unused") | ||
public static class LoopAdvice { | ||
|
||
@Advice.OnMethodEnter(suppress = Throwable.class) | ||
public static void methodEnter() { | ||
// this works bc at this point in the server evaluation, the netty | ||
// instrumentation has already gone to work and assigned the context to the | ||
// local thread; | ||
// | ||
// this works specifically in finagle's netty stack bc at this point the loop() | ||
// method is running on a netty thread with the necessary access to the | ||
// java-native ThreadLocal where the Context is stored | ||
Helpers.CONTEXT_LOCAL.update(Context.current()); | ||
} | ||
|
||
@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) | ||
public static void methodExit(@Advice.Thrown Throwable thrown) { | ||
// always clear this | ||
Helpers.CONTEXT_LOCAL.clear(); | ||
} | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
...io/opentelemetry/javaagent/instrumentation/v23_11/H2StreamChannelInitInstrumentation.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,60 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.javaagent.instrumentation.v23_11; | ||
|
||
import static net.bytebuddy.matcher.ElementMatchers.isMethod; | ||
import static net.bytebuddy.matcher.ElementMatchers.named; | ||
import static net.bytebuddy.matcher.ElementMatchers.returns; | ||
|
||
import io.netty.channel.Channel; | ||
import io.netty.channel.ChannelInitializer; | ||
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; | ||
|
||
public class H2StreamChannelInitInstrumentation implements TypeInstrumentation { | ||
@Override | ||
public ElementMatcher<TypeDescription> typeMatcher() { | ||
// scala object instance -- append $ to name | ||
return named("com.twitter.finagle.http2.transport.common.H2StreamChannelInit$"); | ||
} | ||
|
||
@Override | ||
public void transform(TypeTransformer transformer) { | ||
transformer.applyAdviceToMethod( | ||
isMethod() | ||
.and(named("initServer")) | ||
.and(returns(named("io.netty.channel.ChannelInitializer"))), | ||
H2StreamChannelInitInstrumentation.class.getName() + "$InitServerAdvice"); | ||
transformer.applyAdviceToMethod( | ||
isMethod() | ||
.and(named("initClient")) | ||
.and(returns(named("io.netty.channel.ChannelInitializer"))), | ||
H2StreamChannelInitInstrumentation.class.getName() + "$InitClientAdvice"); | ||
} | ||
|
||
@SuppressWarnings("unused") | ||
public static class InitServerAdvice { | ||
|
||
@Advice.OnMethodExit | ||
public static void handleExit( | ||
@Advice.Return(readOnly = false) ChannelInitializer<Channel> initializer) { | ||
initializer = Helpers.wrapServer(initializer); | ||
} | ||
} | ||
|
||
@SuppressWarnings("unused") | ||
public static class InitClientAdvice { | ||
|
||
@Advice.OnMethodExit | ||
public static void handleExit( | ||
@Advice.Return(readOnly = false) ChannelInitializer<Channel> initializer) { | ||
initializer = Helpers.wrapClient(initializer); | ||
} | ||
} | ||
} |
Oops, something went wrong.