From 4dd52a9ff72a6f7b6d2c285614a5357d622f3d0d Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 10 Jun 2024 11:34:57 +0200 Subject: [PATCH 01/44] hibernate + minimal doc --- docs/contributing/writing-instrumentation-module.md | 11 +++++++++++ .../v3_3/HibernateInstrumentationModule.java | 9 ++++++++- .../v4_0/HibernateInstrumentationModule.java | 10 +++++----- .../v6_0/HibernateInstrumentationModule.java | 10 +++++----- .../v4_3/HibernateInstrumentationModule.java | 9 ++++++++- 5 files changed, 37 insertions(+), 12 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 8fc336989187..e7b4407e38db 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -360,3 +360,14 @@ For example: ``` [suppress]: https://opentelemetry.io/docs/instrumentation/java/automatic/agent-config/#suppressing-specific-auto-instrumentation + +## Use non-inlined advice code with `invokedynamic` + +### shared classes and common classloader + +By default, all the advices of an instrumentation module will be loaded into isolated classloaders, +one per instrumentation module. Some instrumentations require to use a common classloader in order +to preserve the semantics of `static` fields and share interfaces and classes. + +In order to load multiple `InstrumentationModule` implementations in the same classloader, you need to +override the `ExperimentalInstrumentationModule#getModuleGroup` to return an identical value. diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java index d9f6d5a919ac..8a9dd3a82040 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java @@ -11,11 +11,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class HibernateInstrumentationModule extends InstrumentationModule { +public class HibernateInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public HibernateInstrumentationModule() { super("hibernate", "hibernate-3.3"); @@ -30,6 +32,11 @@ public ElementMatcher.Junction classLoaderMatcher() { "org.hibernate.transaction.JBossTransactionManagerLookup"); } + @Override + public String getModuleGroup() { + return "hibernate"; + } + @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java index 9685997529c2..e8a919d13c37 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java @@ -11,11 +11,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class HibernateInstrumentationModule extends InstrumentationModule { +public class HibernateInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public HibernateInstrumentationModule() { super("hibernate", "hibernate-4.0"); @@ -31,10 +33,8 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public boolean isIndyModule() { - // shares classes with hibernate-procedure-call-4.3, these classes should be in the same class - // loader - return false; + public String getModuleGroup() { + return "hibernate"; } @Override diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java index b8c8a34dd120..83af9e7b0f90 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java @@ -11,11 +11,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class HibernateInstrumentationModule extends InstrumentationModule { +public class HibernateInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public HibernateInstrumentationModule() { super("hibernate", "hibernate-6.0"); @@ -29,10 +31,8 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public boolean isIndyModule() { - // shares classes with hibernate-procedure-call-4.3, these classes should be in the same class - // loader - return false; + public String getModuleGroup() { + return "hibernate"; } @Override diff --git a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java index 11b04b34903e..51dd5f92821a 100644 --- a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java @@ -11,11 +11,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class HibernateInstrumentationModule extends InstrumentationModule { +public class HibernateInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public HibernateInstrumentationModule() { super("hibernate-procedure-call", "hibernate-procedure-call-4.3", "hibernate"); } @@ -32,6 +34,11 @@ public boolean isIndyModule() { return false; } + @Override + public String getModuleGroup() { + return "hibernate"; + } + @Override public List typeInstrumentations() { return asList(new ProcedureCallInstrumentation(), new SessionInstrumentation()); From 7766f355044191ec01b7ff0dd9bc04ef08085620 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 10 Jun 2024 13:53:24 +0200 Subject: [PATCH 02/44] awk sdk --- .../awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java | 8 +++++--- .../awssdk/v1_11/AwsSdkInstrumentationModule.java | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java index a3aa56398c7d..533165618711 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java @@ -13,11 +13,13 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import java.util.List; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; // TODO: Copy & paste with only trivial adaptions from v2 -abstract class AbstractAwsSdkInstrumentationModule extends InstrumentationModule { +abstract class AbstractAwsSdkInstrumentationModule extends InstrumentationModule implements + ExperimentalInstrumentationModule { protected AbstractAwsSdkInstrumentationModule(String additionalInstrumentationName) { super("aws-sdk", "aws-sdk-1.11", additionalInstrumentationName); @@ -29,8 +31,8 @@ public boolean isHelperClass(String className) { } @Override - public boolean isIndyModule() { - return false; + public String getModuleGroup() { + return "aws-sdk"; } @Override diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java index d5ba3d2c5add..234ec013d5d5 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java @@ -10,10 +10,12 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; @AutoService(InstrumentationModule.class) -public class AwsSdkInstrumentationModule extends InstrumentationModule { +public class AwsSdkInstrumentationModule extends InstrumentationModule implements + ExperimentalInstrumentationModule { public AwsSdkInstrumentationModule() { super("aws-sdk", "aws-sdk-1.11", "aws-sdk-1.11-core"); } @@ -24,8 +26,8 @@ public boolean isHelperClass(String className) { } @Override - public boolean isIndyModule() { - return false; + public String getModuleGroup() { + return "aws-sdk"; } @Override From 07a5f9062136da2c71020390c94861413de9a6a4 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 10 Jun 2024 14:06:44 +0200 Subject: [PATCH 03/44] spotless --- docs/contributing/writing-instrumentation-module.md | 2 +- .../server/AkkaHttpServerInstrumentationModule.java | 10 +++++----- .../AkkaHttpServerRouteInstrumentationModule.java | 10 +++++----- .../v1_11/AbstractAwsSdkInstrumentationModule.java | 6 +++--- .../awssdk/v1_11/AwsSdkInstrumentationModule.java | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index e7b4407e38db..04e63f258345 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -369,5 +369,5 @@ By default, all the advices of an instrumentation module will be loaded into iso one per instrumentation module. Some instrumentations require to use a common classloader in order to preserve the semantics of `static` fields and share interfaces and classes. -In order to load multiple `InstrumentationModule` implementations in the same classloader, you need to +In order to load multiple `InstrumentationModule` implementations in the same classloader, you need to override the `ExperimentalInstrumentationModule#getModuleGroup` to return an identical value. diff --git a/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/AkkaHttpServerInstrumentationModule.java b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/AkkaHttpServerInstrumentationModule.java index b84f85f78816..48ad1a42b0fb 100644 --- a/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/AkkaHttpServerInstrumentationModule.java +++ b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/AkkaHttpServerInstrumentationModule.java @@ -11,11 +11,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class AkkaHttpServerInstrumentationModule extends InstrumentationModule { +public class AkkaHttpServerInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public AkkaHttpServerInstrumentationModule() { super("akka-http", "akka-http-10.0", "akka-http-server"); } @@ -28,10 +30,8 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public boolean isIndyModule() { - // AkkaHttpServerInstrumentationModule and AkkaHttpServerRouteInstrumentationModule share - // AkkaRouteHolder class - return false; + public String getModuleGroup() { + return "akka-http"; } @Override diff --git a/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/route/AkkaHttpServerRouteInstrumentationModule.java b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/route/AkkaHttpServerRouteInstrumentationModule.java index 6c484eb968ed..169c9253f895 100644 --- a/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/route/AkkaHttpServerRouteInstrumentationModule.java +++ b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/route/AkkaHttpServerRouteInstrumentationModule.java @@ -10,6 +10,7 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; /** @@ -17,16 +18,15 @@ * AkkaHttpServerInstrumentationModule applies to classes in akka-http-core.jar */ @AutoService(InstrumentationModule.class) -public class AkkaHttpServerRouteInstrumentationModule extends InstrumentationModule { +public class AkkaHttpServerRouteInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public AkkaHttpServerRouteInstrumentationModule() { super("akka-http", "akka-http-10.0", "akka-http-server", "akka-http-server-route"); } @Override - public boolean isIndyModule() { - // AkkaHttpServerInstrumentationModule and AkkaHttpServerRouteInstrumentationModule share - // AkkaRouteHolder class - return false; + public String getModuleGroup() { + return "akka-http"; } @Override diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java index 533165618711..ff02429b910c 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java @@ -12,14 +12,14 @@ import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; -import java.util.List; import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; +import java.util.List; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; // TODO: Copy & paste with only trivial adaptions from v2 -abstract class AbstractAwsSdkInstrumentationModule extends InstrumentationModule implements - ExperimentalInstrumentationModule { +abstract class AbstractAwsSdkInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { protected AbstractAwsSdkInstrumentationModule(String additionalInstrumentationName) { super("aws-sdk", "aws-sdk-1.11", additionalInstrumentationName); diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java index 234ec013d5d5..89a4a6c8f673 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java @@ -14,8 +14,8 @@ import java.util.List; @AutoService(InstrumentationModule.class) -public class AwsSdkInstrumentationModule extends InstrumentationModule implements - ExperimentalInstrumentationModule { +public class AwsSdkInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public AwsSdkInstrumentationModule() { super("aws-sdk", "aws-sdk-1.11", "aws-sdk-1.11-core"); } From c1ba53b5fc14cbaa6d65a9b384b18da5e853199c Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 10 Jun 2024 14:19:23 +0200 Subject: [PATCH 04/44] remove leftover --- .../hibernate/v4_3/HibernateInstrumentationModule.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java index 51dd5f92821a..3e914808d004 100644 --- a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java @@ -27,13 +27,6 @@ public ElementMatcher.Junction classLoaderMatcher() { return hasClassesNamed("org.hibernate.procedure.ProcedureCall"); } - @Override - public boolean isIndyModule() { - // uses SessionInfo class from hibernate common which is now in separate class loader for all - // instrumentations - return false; - } - @Override public String getModuleGroup() { return "hibernate"; From b7b3676eb8595914c486d706530b15c468331e72 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 10 Jun 2024 14:31:32 +0200 Subject: [PATCH 05/44] add elasticsearch --- .../ElasticsearchApiClientInstrumentationModule.java | 10 +++++----- .../v7_0/ElasticsearchRest7InstrumentationModule.java | 9 +++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/apiclient/ElasticsearchApiClientInstrumentationModule.java b/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/apiclient/ElasticsearchApiClientInstrumentationModule.java index a0082f7a0888..75cad4dee6fd 100644 --- a/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/apiclient/ElasticsearchApiClientInstrumentationModule.java +++ b/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/apiclient/ElasticsearchApiClientInstrumentationModule.java @@ -12,11 +12,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class ElasticsearchApiClientInstrumentationModule extends InstrumentationModule { +public class ElasticsearchApiClientInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public ElasticsearchApiClientInstrumentationModule() { super("elasticsearch-api-client", "elasticsearch-api-client-7.16", "elasticsearch"); } @@ -31,10 +33,8 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public boolean isIndyModule() { - // java.lang.ClassCastException: class - // io.opentelemetry.javaagent.shaded.instrumentation.elasticsearch.rest.internal.ElasticsearchEndpointDefinition cannot be cast to class io.opentelemetry.javaagent.shaded.instrumentation.elasticsearch.rest.internal.ElasticsearchEndpointDefinition (io.opentelemetry.javaagent.shaded.instrumentation.elasticsearch.rest.internal.ElasticsearchEndpointDefinition is in unnamed module of loader io.opentelemetry.javaagent.tooling.instrumentation.indy.InstrumentationModuleClassLoader @6baee63b; io.opentelemetry.javaagent.shaded.instrumentation.elasticsearch.rest.internal.ElasticsearchEndpointDefinition is in unnamed module of loader 'app') - return false; + public String getModuleGroup() { + return "elasticsearch"; } @Override diff --git a/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7InstrumentationModule.java b/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7InstrumentationModule.java index 919a8318b359..22d00be64dbd 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7InstrumentationModule.java +++ b/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7InstrumentationModule.java @@ -12,11 +12,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class ElasticsearchRest7InstrumentationModule extends InstrumentationModule { +public class ElasticsearchRest7InstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public ElasticsearchRest7InstrumentationModule() { super("elasticsearch-rest", "elasticsearch-rest-7.0", "elasticsearch"); } @@ -33,9 +35,8 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public boolean isIndyModule() { - // shares a virtual field with elasticsearch-api-client - return false; + public String getModuleGroup() { + return "elasticsearch"; } @Override From 41abb88407d961e362c99f92a6447b3fc726f230 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 10 Jun 2024 14:31:48 +0200 Subject: [PATCH 06/44] add netty --- .../netty/v3_8/NettyInstrumentationModule.java | 9 ++++++++- .../netty/v4_0/NettyInstrumentationModule.java | 9 ++++++++- .../netty/v4_1/NettyInstrumentationModule.java | 10 +++++----- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java b/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java index 54b65990b13f..a6cb34099421 100644 --- a/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java +++ b/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java @@ -11,11 +11,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class NettyInstrumentationModule extends InstrumentationModule { +public class NettyInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public NettyInstrumentationModule() { super("netty", "netty-3.8"); } @@ -25,6 +27,11 @@ public ElementMatcher.Junction classLoaderMatcher() { return hasClassesNamed("org.jboss.netty.handler.codec.http.HttpMessage"); } + @Override + public String getModuleGroup() { + return "netty"; + } + @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java b/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java index 1d2151795892..a20246a5d1e3 100644 --- a/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java +++ b/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java @@ -12,12 +12,14 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import io.opentelemetry.javaagent.instrumentation.netty.v4.common.NettyFutureInstrumentation; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class NettyInstrumentationModule extends InstrumentationModule { +public class NettyInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public NettyInstrumentationModule() { super("netty", "netty-4.0"); } @@ -31,6 +33,11 @@ public ElementMatcher.Junction classLoaderMatcher() { not(hasClassesNamed("io.netty.handler.codec.http.CombinedHttpHeaders"))); } + @Override + public String getModuleGroup() { + return "netty"; + } + @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java b/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java index 6f5f5a28038b..9d9c71505726 100644 --- a/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java +++ b/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java @@ -11,12 +11,14 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import io.opentelemetry.javaagent.instrumentation.netty.v4.common.NettyFutureInstrumentation; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class NettyInstrumentationModule extends InstrumentationModule { +public class NettyInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public NettyInstrumentationModule() { super("netty", "netty-4.1"); } @@ -29,10 +31,8 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public boolean isIndyModule() { - // netty instrumentation classes are used in other instrumentations which causes class cast - // exceptions - return false; + public String getModuleGroup() { + return "netty"; } @Override From b03321b33da7079f248a86f0d91e8ffc67072eec Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 11 Jun 2024 09:53:59 +0200 Subject: [PATCH 07/44] inline aws --- .../awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java | 5 +++++ .../awssdk/v1_11/AwsClientInstrumentation.java | 2 +- .../awssdk/v1_11/AwsHttpClientInstrumentation.java | 2 +- .../awssdk/v1_11/AwsSdkInstrumentationModule.java | 5 +++++ .../awssdk/v1_11/RequestExecutorInstrumentation.java | 2 +- .../awssdk/v1_11/SqsInstrumentationModule.java | 5 +++++ .../awssdk/v2_2/AbstractAwsSdkInstrumentationModule.java | 5 +++++ 7 files changed, 23 insertions(+), 3 deletions(-) diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java index ff02429b910c..c5842d5d01a0 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java @@ -35,6 +35,11 @@ public String getModuleGroup() { return "aws-sdk"; } + @Override + public boolean isIndyModule() { + return true; + } + @Override public ElementMatcher.Junction classLoaderMatcher() { // We don't actually transform it but want to make sure we only apply the instrumentation when diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsClientInstrumentation.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsClientInstrumentation.java index 0c613139f5de..b2929fe18537 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsClientInstrumentation.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsClientInstrumentation.java @@ -39,7 +39,7 @@ public void transform(TypeTransformer transformer) { public static class AwsClientAdvice { // Since we're instrumenting the constructor, we can't add onThrowable. - @Advice.OnMethodExit(suppress = Throwable.class) + @Advice.OnMethodExit(suppress = Throwable.class, inline = false) public static void addHandler( @Advice.FieldValue("requestHandler2s") List handlers) { boolean hasAgentHandler = false; diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsHttpClientInstrumentation.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsHttpClientInstrumentation.java index f76d02d35279..36742a5bb237 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsHttpClientInstrumentation.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsHttpClientInstrumentation.java @@ -49,7 +49,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class HttpClientAdvice { - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) public static void methodExit( @Advice.Argument(value = 0) Request request, @Advice.Return Response response, diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java index 89a4a6c8f673..06f2fec9b35f 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java @@ -30,6 +30,11 @@ public String getModuleGroup() { return "aws-sdk"; } + @Override + public boolean isIndyModule() { + return true; + } + @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/RequestExecutorInstrumentation.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/RequestExecutorInstrumentation.java index 9913d8aaf550..dfa2888bd719 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/RequestExecutorInstrumentation.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/RequestExecutorInstrumentation.java @@ -44,7 +44,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class RequestExecutorAdvice { - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) public static void methodExit( @Advice.FieldValue("request") Request request, @Advice.Return Response response, diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/SqsInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/SqsInstrumentationModule.java index cc61cf6d9cc0..ae2ad432a394 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/SqsInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/SqsInstrumentationModule.java @@ -26,6 +26,11 @@ public void doTransform(TypeTransformer transformer) { none(), SqsInstrumentationModule.class.getName() + "$RegisterAdvice"); } + @Override + public boolean isIndyModule() { + return true; + } + @SuppressWarnings("unused") public static class RegisterAdvice { @Advice.OnMethodExit(suppress = Throwable.class) diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AbstractAwsSdkInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AbstractAwsSdkInstrumentationModule.java index 3138429d4fc9..43b3750d4691 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AbstractAwsSdkInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AbstractAwsSdkInstrumentationModule.java @@ -29,6 +29,11 @@ public String getModuleGroup() { return "aws-sdk-v2"; } + @Override + public boolean isIndyModule() { + return true; + } + @Override public boolean isHelperClass(String className) { return className.startsWith("io.opentelemetry.contrib.awsxray."); From 8827c1e3eff104f56654120ef6147b25893dc20b Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:33:44 +0200 Subject: [PATCH 08/44] hibernate-3 --- .../v3_3/CriteriaInstrumentation.java | 43 ++++------- .../v3_3/HibernateInstrumentationModule.java | 5 ++ .../hibernate/v3_3/QueryInstrumentation.java | 38 +++------- .../v3_3/SessionFactoryInstrumentation.java | 2 +- .../v3_3/TransactionInstrumentation.java | 42 ++++------- .../hibernate/HibernateOperationScope.java | 75 +++++++++++++++++++ 6 files changed, 120 insertions(+), 85 deletions(-) create mode 100644 instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/HibernateOperationScope.java diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java index e995738cd723..23d344807c20 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java @@ -13,13 +13,13 @@ import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; +import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -49,18 +49,13 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class CriteriaMethodAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void startMethod( - @Advice.This Criteria criteria, - @Advice.Origin("#m") String name, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + public static Object startMethod( + @Advice.This Criteria criteria, @Advice.Origin("#m") String name) { - callDepth = CallDepth.forClass(HibernateOperation.class); + CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return; + return callDepth; } String entityName = null; @@ -73,31 +68,21 @@ public static void startMethod( SessionInfo sessionInfo = criteriaVirtualField.get(criteria); Context parentContext = Java8BytecodeBridge.currentContext(); - hibernateOperation = new HibernateOperation("Criteria." + name, entityName, sessionInfo); + HibernateOperation hibernateOperation = + new HibernateOperation("Criteria." + name, entityName, sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return; + return callDepth; } - context = instrumenter().start(parentContext, hibernateOperation); - scope = context.makeCurrent(); + return HibernateOperationScope.startNew( + callDepth, hibernateOperation, parentContext, instrumenter()); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) public static void endMethod( - @Advice.Thrown Throwable throwable, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - - if (callDepth.decrementAndGet() > 0) { - return; - } + @Advice.Thrown Throwable throwable, @Advice.Enter Object enterScope) { - if (scope != null) { - scope.close(); - instrumenter().end(context, hibernateOperation, null, throwable); - } + HibernateOperationScope.end(enterScope, instrumenter(), throwable); } } } diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java index 8a9dd3a82040..66efb8007082 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java @@ -37,6 +37,11 @@ public String getModuleGroup() { return "hibernate"; } + @Override + public boolean isIndyModule() { + return true; + } + @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java index 5a9742dcbcd0..b95c2fbc62d4 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java @@ -14,13 +14,13 @@ import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; +import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -49,17 +49,12 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class QueryMethodAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void startMethod( - @Advice.This Query query, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + public static Object startMethod(@Advice.This Query query) { - callDepth = CallDepth.forClass(HibernateOperation.class); + CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return; + return callDepth; } VirtualField queryVirtualField = @@ -67,32 +62,21 @@ public static void startMethod( SessionInfo sessionInfo = queryVirtualField.get(query); Context parentContext = Java8BytecodeBridge.currentContext(); - hibernateOperation = + HibernateOperation hibernateOperation = new HibernateOperation(getOperationNameForQuery(query.getQueryString()), sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return; + return callDepth; } - context = instrumenter().start(parentContext, hibernateOperation); - scope = context.makeCurrent(); + return HibernateOperationScope.startNew( + callDepth, hibernateOperation, parentContext, instrumenter()); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( - @Advice.Thrown Throwable throwable, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.Thrown Throwable throwable, @Advice.Enter Object enterScope) { - if (callDepth.decrementAndGet() > 0) { - return; - } - - if (scope != null) { - scope.close(); - instrumenter().end(context, hibernateOperation, null, throwable); - } + HibernateOperationScope.end(enterScope, instrumenter(), throwable); } } } diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/SessionFactoryInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/SessionFactoryInstrumentation.java index 4f23948d32f5..3aa48c7a8db7 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/SessionFactoryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/SessionFactoryInstrumentation.java @@ -51,7 +51,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class SessionFactoryAdvice { - @Advice.OnMethodExit(suppress = Throwable.class) + @Advice.OnMethodExit(suppress = Throwable.class, inline = false) public static void openSession(@Advice.Return Object session) { if (session instanceof Session) { diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java index c9f8631f54b8..f27925b629ec 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java @@ -13,14 +13,15 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; +import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; +import javax.annotation.Nullable; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -48,17 +49,12 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class TransactionCommitAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void startCommit( - @Advice.This Transaction transaction, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + public static Object startCommit(@Advice.This Transaction transaction) { - callDepth = CallDepth.forClass(HibernateOperation.class); + CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return; + return callDepth; } VirtualField transactionVirtualField = @@ -66,31 +62,21 @@ public static void startCommit( SessionInfo sessionInfo = transactionVirtualField.get(transaction); Context parentContext = Java8BytecodeBridge.currentContext(); - hibernateOperation = new HibernateOperation("Transaction.commit", sessionInfo); + HibernateOperation hibernateOperation = + new HibernateOperation("Transaction.commit", sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return; + return callDepth; } - context = instrumenter().start(parentContext, hibernateOperation); - scope = context.makeCurrent(); + return HibernateOperationScope.startNew( + callDepth, hibernateOperation, parentContext, instrumenter()); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) public static void endCommit( - @Advice.Thrown Throwable throwable, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.Thrown Throwable throwable, @Advice.Enter @Nullable Object enterScope) { - if (callDepth.decrementAndGet() > 0) { - return; - } - - if (scope != null) { - scope.close(); - instrumenter().end(context, hibernateOperation, null, throwable); - } + HibernateOperationScope.end(enterScope, instrumenter(), throwable); } } } diff --git a/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/HibernateOperationScope.java b/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/HibernateOperationScope.java new file mode 100644 index 000000000000..a68547463ff6 --- /dev/null +++ b/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/HibernateOperationScope.java @@ -0,0 +1,75 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.hibernate; + +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.javaagent.bootstrap.CallDepth; + +public class HibernateOperationScope { + + private final CallDepth callDepth; + private final HibernateOperation hibernateOperation; + private final Context context; + private final Scope scope; + + private HibernateOperationScope( + CallDepth callDepth, HibernateOperation hibernateOperation, Context context, Scope scope) { + this.callDepth = callDepth; + this.hibernateOperation = hibernateOperation; + this.context = context; + this.scope = scope; + } + + /** + * Starts operation scope + * + * @param callDepth call depth + * @param hibernateOperation hibernate operation + * @param parentContext parent context + * @param instrumenter instrumenter + * @return operation scope, to be ended with {@link #end(Object, Instrumenter, Throwable)} on exit + * advice + */ + public static HibernateOperationScope startNew( + CallDepth callDepth, + HibernateOperation hibernateOperation, + Context parentContext, + Instrumenter instrumenter) { + + Context context = instrumenter.start(parentContext, hibernateOperation); + return new HibernateOperationScope( + callDepth, hibernateOperation, context, context.makeCurrent()); + } + + /** + * Ends operation scope + * + * @param o {@link HibernateOperationScope} or {@link CallDepth} from enter advice + * @param instrumenter instrumenter + * @param throwable thrown exception + */ + public static void end( + Object o, Instrumenter instrumenter, Throwable throwable) { + if (o instanceof CallDepth) { + ((CallDepth) o).decrementAndGet(); + return; + } + + if (!(o instanceof HibernateOperationScope)) { + throw new IllegalArgumentException("unexpected argument"); + } + + HibernateOperationScope state = (HibernateOperationScope) o; + int depth = state.callDepth.decrementAndGet(); + if (depth != 0) { + throw new IllegalStateException("unexpected call depth " + depth); + } + state.scope.close(); + instrumenter.end(state.context, state.hibernateOperation, null, throwable); + } +} From 9efaf2d1528586adb589ba4ddbad3faf4e2f252e Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:38:42 +0200 Subject: [PATCH 09/44] hibernate-4 --- .../v4_0/CriteriaInstrumentation.java | 43 ++++++----------- .../v4_0/HibernateInstrumentationModule.java | 5 ++ .../hibernate/v4_0/QueryInstrumentation.java | 40 +++++----------- .../v4_0/SessionFactoryInstrumentation.java | 2 +- .../v4_0/SessionInstrumentation.java | 47 +++++++------------ .../v4_0/TransactionInstrumentation.java | 41 +++++----------- 6 files changed, 61 insertions(+), 117 deletions(-) diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java index aec640bc6b07..a7fd89f38296 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java @@ -13,13 +13,13 @@ import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; +import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -49,18 +49,13 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class CriteriaMethodAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void startMethod( - @Advice.This Criteria criteria, - @Advice.Origin("#m") String name, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + public static Object startMethod( + @Advice.This Criteria criteria, @Advice.Origin("#m") String name) { - callDepth = CallDepth.forClass(HibernateOperation.class); + CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return; + return callDepth; } String entityName = null; @@ -73,31 +68,21 @@ public static void startMethod( SessionInfo sessionInfo = criteriaVirtualField.get(criteria); Context parentContext = Java8BytecodeBridge.currentContext(); - hibernateOperation = new HibernateOperation("Criteria." + name, entityName, sessionInfo); + HibernateOperation hibernateOperation = + new HibernateOperation("Criteria." + name, entityName, sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return; + return callDepth; } - context = instrumenter().start(parentContext, hibernateOperation); - scope = context.makeCurrent(); + return HibernateOperationScope.startNew( + callDepth, hibernateOperation, parentContext, instrumenter()); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) public static void endMethod( - @Advice.Thrown Throwable throwable, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - - if (callDepth.decrementAndGet() > 0) { - return; - } + @Advice.Thrown Throwable throwable, @Advice.Enter Object enterState) { - if (scope != null) { - scope.close(); - instrumenter().end(context, hibernateOperation, null, throwable); - } + HibernateOperationScope.end(enterState, instrumenter(), throwable); } } } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java index e8a919d13c37..6526c136c5c4 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java @@ -37,6 +37,11 @@ public String getModuleGroup() { return "hibernate"; } + @Override + public boolean isIndyModule() { + return true; + } + @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java index af0618e6c773..7c87389c2a3d 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java @@ -14,13 +14,13 @@ import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; +import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -49,17 +49,12 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class QueryMethodAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void startMethod( - @Advice.This Query query, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + public static Object startMethod(@Advice.This Query query) { - callDepth = CallDepth.forClass(HibernateOperation.class); + CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return; + return callDepth; } VirtualField queryVirtualField = @@ -67,32 +62,21 @@ public static void startMethod( SessionInfo sessionInfo = queryVirtualField.get(query); Context parentContext = Java8BytecodeBridge.currentContext(); - hibernateOperation = + HibernateOperation hibernateOperation = new HibernateOperation(getOperationNameForQuery(query.getQueryString()), sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return; + return callDepth; } - context = instrumenter().start(parentContext, hibernateOperation); - scope = context.makeCurrent(); + return HibernateOperationScope.startNew( + callDepth, hibernateOperation, parentContext, instrumenter()); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) public static void endMethod( - @Advice.Thrown Throwable throwable, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.Thrown Throwable throwable, @Advice.Enter Object enterState) { - if (callDepth.decrementAndGet() > 0) { - return; - } - - if (scope != null) { - scope.close(); - instrumenter().end(context, hibernateOperation, null, throwable); - } + HibernateOperationScope.end(enterState, instrumenter(), throwable); } } } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionFactoryInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionFactoryInstrumentation.java index 5f82adf80b00..c75bb0b5f26e 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionFactoryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionFactoryInstrumentation.java @@ -47,7 +47,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class SessionFactoryAdvice { - @Advice.OnMethodExit(suppress = Throwable.class) + @Advice.OnMethodExit(suppress = Throwable.class, inline = false) public static void openSession(@Advice.Return SharedSessionContract session) { VirtualField virtualField = diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java index e5e9fbc5116e..6d1c4e42e1e4 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java @@ -18,13 +18,13 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; +import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -95,21 +95,17 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class SessionMethodAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void startMethod( + @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + public static Object startMethod( @Advice.This SharedSessionContract session, @Advice.Origin("#m") String name, @Advice.Origin("#d") String descriptor, @Advice.Argument(0) Object arg0, - @Advice.Argument(value = 1, optional = true) Object arg1, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.Argument(value = 1, optional = true) Object arg1) { - callDepth = CallDepth.forClass(HibernateOperation.class); + CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return; + return callDepth; } VirtualField virtualField = @@ -119,39 +115,28 @@ public static void startMethod( Context parentContext = Java8BytecodeBridge.currentContext(); String entityName = getEntityName(descriptor, arg0, arg1, EntityNameUtil.bestGuessEntityName(session)); - hibernateOperation = + HibernateOperation hibernateOperation = new HibernateOperation(getSessionMethodOperationName(name), entityName, sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return; + return callDepth; } - context = instrumenter().start(parentContext, hibernateOperation); - scope = context.makeCurrent(); + return HibernateOperationScope.startNew( + callDepth, hibernateOperation, parentContext, instrumenter()); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) public static void endMethod( - @Advice.Thrown Throwable throwable, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - - if (callDepth.decrementAndGet() > 0) { - return; - } + @Advice.Thrown Throwable throwable, @Advice.Enter Object enterState) { - if (scope != null) { - scope.close(); - instrumenter().end(context, hibernateOperation, null, throwable); - } + HibernateOperationScope.end(enterState, instrumenter(), throwable); } } @SuppressWarnings("unused") public static class GetQueryAdvice { - @Advice.OnMethodExit(suppress = Throwable.class) + @Advice.OnMethodExit(suppress = Throwable.class, inline = false) public static void getQuery( @Advice.This SharedSessionContract session, @Advice.Return Query query) { @@ -167,7 +152,7 @@ public static void getQuery( @SuppressWarnings("unused") public static class GetTransactionAdvice { - @Advice.OnMethodExit(suppress = Throwable.class) + @Advice.OnMethodExit(suppress = Throwable.class, inline = false) public static void getTransaction( @Advice.This SharedSessionContract session, @Advice.Return Transaction transaction) { @@ -183,7 +168,7 @@ public static void getTransaction( @SuppressWarnings("unused") public static class GetCriteriaAdvice { - @Advice.OnMethodExit(suppress = Throwable.class) + @Advice.OnMethodExit(suppress = Throwable.class, inline = false) public static void getCriteria( @Advice.This SharedSessionContract session, @Advice.Return Criteria criteria) { diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java index 16be5e006ad9..7aba64c051d7 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java @@ -13,13 +13,13 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; +import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -48,17 +48,12 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class TransactionCommitAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void startCommit( - @Advice.This Transaction transaction, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + public static Object startCommit(@Advice.This Transaction transaction) { - callDepth = CallDepth.forClass(HibernateOperation.class); + CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return; + return callDepth; } VirtualField transactionVirtualField = @@ -66,31 +61,21 @@ public static void startCommit( SessionInfo sessionInfo = transactionVirtualField.get(transaction); Context parentContext = Java8BytecodeBridge.currentContext(); - hibernateOperation = new HibernateOperation("Transaction.commit", sessionInfo); + HibernateOperation hibernateOperation = + new HibernateOperation("Transaction.commit", sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return; + return callDepth; } - context = instrumenter().start(parentContext, hibernateOperation); - scope = context.makeCurrent(); + return HibernateOperationScope.startNew( + callDepth, hibernateOperation, parentContext, instrumenter()); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) public static void endCommit( - @Advice.Thrown Throwable throwable, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.Thrown Throwable throwable, @Advice.Enter Object enterScope) { - if (callDepth.decrementAndGet() > 0) { - return; - } - - if (scope != null) { - scope.close(); - instrumenter().end(context, hibernateOperation, null, throwable); - } + HibernateOperationScope.end(enterScope, instrumenter(), throwable); } } } From bcaeaf40c0571af3916c0d53bd6bea14b28568ca Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:53:09 +0200 Subject: [PATCH 10/44] document advice local variables --- .../writing-instrumentation-module.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 04e63f258345..4a591fb0d9de 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -371,3 +371,25 @@ to preserve the semantics of `static` fields and share interfaces and classes. In order to load multiple `InstrumentationModule` implementations in the same classloader, you need to override the `ExperimentalInstrumentationModule#getModuleGroup` to return an identical value. + +### advice local variables + +With inlined advices, declaring an advice method argument with `@Advice.Local` allows to define +a variable that is local to the advice execution for communication between the enter and exit advices. + +When advices are not inlined, usage of `@Advice.Local` is not possible. It is however possible to +return a value from the enter advice and get the value in the exit advice with a parameter annotated +with `@Advice.Enter`, for example: + +```java +@Advice.OnMethodEnter(suppress = Throwable.class, inline = false) +public static Object onEnter(@Advice.Argument(1) Object request) { + return "enterValue"; +} + +@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class, inline = false) +public static void onExit(@Advice.Argument(1) Object request, + @Advice.Enter Object enterValue) { + // do something with enterValue +} +``` From 8dbccdcdafb4f48a98de1d2ced8997d123301567 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 11 Jun 2024 14:25:24 +0200 Subject: [PATCH 11/44] document indy modules --- .../writing-instrumentation-module.md | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 4a591fb0d9de..d3a8bc7e8013 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -363,11 +363,34 @@ For example: ## Use non-inlined advice code with `invokedynamic` +Using non-inlined advice code is possible thanks to the `invokedynamic` instruction, this strategy +is referred as "indy" in reference to this, by extension "indy modules" are the instrumentation +modules using this instrumentation strategy. + +### indy modules and transition + +Instrumentation modules that use "indy" must have their `InstrumentationModule#isIndyModule` +implementation return `true`. Also, all the instrumentation advice methods annotated with +`@Advice.OnMethodEnter` or `@Advice.OnMethodExit` must have the `inlined = false` explicitly set. + +The end goal is to use indy modules whenever possible, but during the transition process we have +three sets of instrumentation modules: +- `isIndyModule` always returns `true`: module converted to indy module and non-inlined advices +- `isIndyModule` might return `true` when `otel.javaagent.experimental.indy` is set through automatic conversion, but false otherwise. +- `isIndyModule` always returns `false`: opt-out for instrumentation modules that are known to not + support automatic conversion. + +Setting the `otel.javaagent.experimental.indy=true` configuration option will enable +`io.opentelemetry.javaagent.tooling.instrumentation.indy.AdviceTransformer` that will attempt to +convert advices automatically. This configuration is automatically enabled in CI when `test indy` +label is added to a pull-request or when the `-PtestIndy=true` parameter is added to gradle. +This configuration has no effect on instrumentation modules that explicitly return `true` or `false`. + ### shared classes and common classloader By default, all the advices of an instrumentation module will be loaded into isolated classloaders, one per instrumentation module. Some instrumentations require to use a common classloader in order -to preserve the semantics of `static` fields and share interfaces and classes. +to preserve the semantics of `static` fields and to share classes. In order to load multiple `InstrumentationModule` implementations in the same classloader, you need to override the `ExperimentalInstrumentationModule#getModuleGroup` to return an identical value. From c012aac246e1ebd35366e2aa3428174cc819edd8 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 11 Jun 2024 14:53:27 +0200 Subject: [PATCH 12/44] hibernate-6 --- .../v6_0/HibernateInstrumentationModule.java | 5 +++ .../hibernate/v6_0/QueryInstrumentation.java | 40 ++++++------------- .../v6_0/SessionFactoryInstrumentation.java | 2 +- .../v6_0/SessionInstrumentation.java | 10 ++--- .../v6_0/TransactionInstrumentation.java | 39 ++++++------------ 5 files changed, 35 insertions(+), 61 deletions(-) diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java index 83af9e7b0f90..810ca2b085fc 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java @@ -35,6 +35,11 @@ public String getModuleGroup() { return "hibernate"; } + @Override + public boolean isIndyModule() { + return true; + } + @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/QueryInstrumentation.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/QueryInstrumentation.java index 141175c30269..ae2a83304a27 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/QueryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/QueryInstrumentation.java @@ -14,13 +14,13 @@ import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; +import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -63,17 +63,12 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class QueryMethodAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void startMethod( - @Advice.This CommonQueryContract query, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + public static Object startMethod(@Advice.This CommonQueryContract query) { - callDepth = CallDepth.forClass(HibernateOperation.class); + CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return; + return callDepth; } String queryString = null; @@ -93,32 +88,21 @@ public static void startMethod( SessionInfo sessionInfo = queryVirtualField.get(query); Context parentContext = Java8BytecodeBridge.currentContext(); - hibernateOperation = + HibernateOperation hibernateOperation = new HibernateOperation(getOperationNameForQuery(queryString), sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return; + return callDepth; } - context = instrumenter().start(parentContext, hibernateOperation); - scope = context.makeCurrent(); + return HibernateOperationScope.startNew( + callDepth, hibernateOperation, parentContext, instrumenter()); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) public static void endMethod( - @Advice.Thrown Throwable throwable, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - - if (callDepth.decrementAndGet() > 0) { - return; - } + @Advice.Thrown Throwable throwable, @Advice.Enter Object enterScope) { - if (scope != null) { - scope.close(); - instrumenter().end(context, hibernateOperation, null, throwable); - } + HibernateOperationScope.end(enterScope, instrumenter(), throwable); } } } diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/SessionFactoryInstrumentation.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/SessionFactoryInstrumentation.java index ae5807c5b8a9..c4a5d6fcf818 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/SessionFactoryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/SessionFactoryInstrumentation.java @@ -52,7 +52,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class SessionFactoryAdvice { - @Advice.OnMethodExit(suppress = Throwable.class) + @Advice.OnMethodExit(suppress = Throwable.class, inline = false) public static void openSession(@Advice.Return SharedSessionContract session) { VirtualField virtualField = diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/SessionInstrumentation.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/SessionInstrumentation.java index fde18f963d42..b349c4e2d57c 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/SessionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/SessionInstrumentation.java @@ -94,7 +94,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class SessionMethodAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) + @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) public static void startMethod( @Advice.This SharedSessionContract session, @Advice.Origin("#m") String name, @@ -128,7 +128,7 @@ public static void startMethod( scope = context.makeCurrent(); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) public static void endMethod( @Advice.Thrown Throwable throwable, @Advice.Local("otelCallDepth") CallDepth callDepth, @@ -150,7 +150,7 @@ public static void endMethod( @SuppressWarnings("unused") public static class GetQueryAdvice { - @Advice.OnMethodExit(suppress = Throwable.class) + @Advice.OnMethodExit(suppress = Throwable.class, inline = false) public static void getQuery( @Advice.This SharedSessionContract session, @Advice.Return Object queryObject) { if (!(queryObject instanceof CommonQueryContract)) { @@ -170,7 +170,7 @@ public static void getQuery( @SuppressWarnings("unused") public static class GetTransactionAdvice { - @Advice.OnMethodExit(suppress = Throwable.class) + @Advice.OnMethodExit(suppress = Throwable.class, inline = false) public static void getTransaction( @Advice.This SharedSessionContract session, @Advice.Return Transaction transaction) { @@ -186,7 +186,7 @@ public static void getTransaction( @SuppressWarnings("unused") public static class GetCriteriaAdvice { - @Advice.OnMethodExit(suppress = Throwable.class) + @Advice.OnMethodExit(suppress = Throwable.class, inline = false) public static void getCriteria( @Advice.This SharedSessionContract session, @Advice.Return CriteriaQuery criteria) { diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/TransactionInstrumentation.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/TransactionInstrumentation.java index 711773e4e5b4..ac0261750400 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/TransactionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/TransactionInstrumentation.java @@ -13,13 +13,13 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; +import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -48,17 +48,12 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class TransactionCommitAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void startCommit( - @Advice.This Transaction transaction, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + public static Object startCommit(@Advice.This Transaction transaction) { - callDepth = CallDepth.forClass(HibernateOperation.class); + CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return; + return callDepth; } VirtualField transactionVirtualField = @@ -66,31 +61,21 @@ public static void startCommit( SessionInfo sessionInfo = transactionVirtualField.get(transaction); Context parentContext = Java8BytecodeBridge.currentContext(); - hibernateOperation = new HibernateOperation("Transaction.commit", sessionInfo); + HibernateOperation hibernateOperation = + new HibernateOperation("Transaction.commit", sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return; + return callDepth; } - context = instrumenter().start(parentContext, hibernateOperation); - scope = context.makeCurrent(); + return HibernateOperationScope.startNew( + callDepth, hibernateOperation, parentContext, instrumenter()); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endCommit( - @Advice.Thrown Throwable throwable, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.Thrown Throwable throwable, @Advice.Enter Object enterScope) { - if (callDepth.decrementAndGet() > 0) { - return; - } - - if (scope != null) { - scope.close(); - instrumenter().end(context, hibernateOperation, null, throwable); - } + HibernateOperationScope.end(enterScope, instrumenter(), throwable); } } } From 27e36cde95bb0d64f4951b407e1228c8a9cfea4a Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 11 Jun 2024 15:06:45 +0200 Subject: [PATCH 13/44] hibernate-procedure-call --- .../v4_3/HibernateInstrumentationModule.java | 5 +++ .../v4_3/ProcedureCallInstrumentation.java | 42 ++++++------------- .../v4_3/SessionInstrumentation.java | 2 +- 3 files changed, 19 insertions(+), 30 deletions(-) diff --git a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java index 3e914808d004..e80b1bc6e8f4 100644 --- a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java @@ -32,6 +32,11 @@ public String getModuleGroup() { return "hibernate"; } + @Override + public boolean isIndyModule() { + return true; + } + @Override public List typeInstrumentations() { return asList(new ProcedureCallInstrumentation(), new SessionInstrumentation()); diff --git a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java index ed9671808c2f..76f6d9192984 100644 --- a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java +++ b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java @@ -12,13 +12,13 @@ import static net.bytebuddy.matcher.ElementMatchers.named; import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; +import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -47,18 +47,13 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class ProcedureCallMethodAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void startMethod( - @Advice.This ProcedureCall call, - @Advice.Origin("#m") String name, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + public static Object startMethod( + @Advice.This ProcedureCall call, @Advice.Origin("#m") String name) { - callDepth = CallDepth.forClass(HibernateOperation.class); + CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return; + return callDepth; } VirtualField criteriaVirtualField = @@ -66,32 +61,21 @@ public static void startMethod( SessionInfo sessionInfo = criteriaVirtualField.get(call); Context parentContext = Java8BytecodeBridge.currentContext(); - hibernateOperation = + HibernateOperation hibernateOperation = new HibernateOperation("ProcedureCall." + name, call.getProcedureName(), sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return; + return callDepth; } - context = instrumenter().start(parentContext, hibernateOperation); - scope = context.makeCurrent(); + return HibernateOperationScope.startNew( + callDepth, hibernateOperation, parentContext, instrumenter()); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) public static void endMethod( - @Advice.Thrown Throwable throwable, - @Advice.Local("otelCallDepth") CallDepth callDepth, - @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.Thrown Throwable throwable, @Advice.Enter Object enterScope) { - if (callDepth.decrementAndGet() > 0) { - return; - } - - if (scope != null) { - scope.close(); - instrumenter().end(context, hibernateOperation, null, throwable); - } + HibernateOperationScope.end(enterScope, instrumenter(), throwable); } } } diff --git a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/SessionInstrumentation.java b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/SessionInstrumentation.java index 58d7c8d675d0..5ca9e13529a5 100644 --- a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/SessionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/SessionInstrumentation.java @@ -44,7 +44,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class GetProcedureCallAdvice { - @Advice.OnMethodExit(suppress = Throwable.class) + @Advice.OnMethodExit(suppress = Throwable.class, inline = false) public static void getProcedureCall( @Advice.This SharedSessionContract session, @Advice.Return ProcedureCall returned) { From 98f74d0356e0bad04dbb387591f5264439a2c215 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 11 Jun 2024 16:58:59 +0200 Subject: [PATCH 14/44] aws remove explicit inline --- .../awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java | 5 ----- .../awssdk/v1_11/AwsClientInstrumentation.java | 2 +- .../awssdk/v1_11/AwsHttpClientInstrumentation.java | 2 +- .../awssdk/v1_11/AwsSdkInstrumentationModule.java | 5 ----- .../awssdk/v1_11/RequestExecutorInstrumentation.java | 2 +- .../awssdk/v1_11/SqsInstrumentationModule.java | 5 ----- .../awssdk/v2_2/AbstractAwsSdkInstrumentationModule.java | 5 ----- 7 files changed, 3 insertions(+), 23 deletions(-) diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java index c5842d5d01a0..ff02429b910c 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java @@ -35,11 +35,6 @@ public String getModuleGroup() { return "aws-sdk"; } - @Override - public boolean isIndyModule() { - return true; - } - @Override public ElementMatcher.Junction classLoaderMatcher() { // We don't actually transform it but want to make sure we only apply the instrumentation when diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsClientInstrumentation.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsClientInstrumentation.java index b2929fe18537..0c613139f5de 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsClientInstrumentation.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsClientInstrumentation.java @@ -39,7 +39,7 @@ public void transform(TypeTransformer transformer) { public static class AwsClientAdvice { // Since we're instrumenting the constructor, we can't add onThrowable. - @Advice.OnMethodExit(suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(suppress = Throwable.class) public static void addHandler( @Advice.FieldValue("requestHandler2s") List handlers) { boolean hasAgentHandler = false; diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsHttpClientInstrumentation.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsHttpClientInstrumentation.java index 36742a5bb237..f76d02d35279 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsHttpClientInstrumentation.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsHttpClientInstrumentation.java @@ -49,7 +49,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class HttpClientAdvice { - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void methodExit( @Advice.Argument(value = 0) Request request, @Advice.Return Response response, diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java index 06f2fec9b35f..89a4a6c8f673 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java @@ -30,11 +30,6 @@ public String getModuleGroup() { return "aws-sdk"; } - @Override - public boolean isIndyModule() { - return true; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/RequestExecutorInstrumentation.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/RequestExecutorInstrumentation.java index dfa2888bd719..9913d8aaf550 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/RequestExecutorInstrumentation.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/RequestExecutorInstrumentation.java @@ -44,7 +44,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class RequestExecutorAdvice { - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void methodExit( @Advice.FieldValue("request") Request request, @Advice.Return Response response, diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/SqsInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/SqsInstrumentationModule.java index ae2ad432a394..cc61cf6d9cc0 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/SqsInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/SqsInstrumentationModule.java @@ -26,11 +26,6 @@ public void doTransform(TypeTransformer transformer) { none(), SqsInstrumentationModule.class.getName() + "$RegisterAdvice"); } - @Override - public boolean isIndyModule() { - return true; - } - @SuppressWarnings("unused") public static class RegisterAdvice { @Advice.OnMethodExit(suppress = Throwable.class) diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AbstractAwsSdkInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AbstractAwsSdkInstrumentationModule.java index 43b3750d4691..3138429d4fc9 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AbstractAwsSdkInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AbstractAwsSdkInstrumentationModule.java @@ -29,11 +29,6 @@ public String getModuleGroup() { return "aws-sdk-v2"; } - @Override - public boolean isIndyModule() { - return true; - } - @Override public boolean isHelperClass(String className) { return className.startsWith("io.opentelemetry.contrib.awsxray."); From 957a7b86ed9f96e29135225590ddce2198e0a631 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 11 Jun 2024 17:27:16 +0200 Subject: [PATCH 15/44] reword documentation with transition proposal --- .../writing-instrumentation-module.md | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index d3a8bc7e8013..050046f9220d 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -367,24 +367,37 @@ Using non-inlined advice code is possible thanks to the `invokedynamic` instruct is referred as "indy" in reference to this, by extension "indy modules" are the instrumentation modules using this instrumentation strategy. -### indy modules and transition +The most common way to instrument code with bytebuddy relies on inlining, this strategy will be +referred as "inlined" strategy in opposition to "indy". -Instrumentation modules that use "indy" must have their `InstrumentationModule#isIndyModule` +### Indy modules and transition + +Having all instrumentation rely on native "indy" instrumentation is a tedious task and can't be +achieved in a "big bang" step, we thus have to use intermediate steps. + +Instrumentation modules that are "indy native" must have their `InstrumentationModule#isIndyModule` implementation return `true`. Also, all the instrumentation advice methods annotated with `@Advice.OnMethodEnter` or `@Advice.OnMethodExit` must have the `inlined = false` explicitly set. -The end goal is to use indy modules whenever possible, but during the transition process we have -three sets of instrumentation modules: -- `isIndyModule` always returns `true`: module converted to indy module and non-inlined advices -- `isIndyModule` might return `true` when `otel.javaagent.experimental.indy` is set through automatic conversion, but false otherwise. -- `isIndyModule` always returns `false`: opt-out for instrumentation modules that are known to not - support automatic conversion. +The `otel.javaagent.experimental.indy` (default `false`) configuration option allows to opt-in for +using "indy". When set to `true`, the `io.opentelemetry.javaagent.tooling.instrumentation.indy.AdviceTransformer` +will transform advices automatically to make them "indy native". + +This configuration is automatically enabled in CI when `test indy` label is added to a pull-request +or when the `-PtestIndy=true` parameter is added to gradle. + +In order to preserve compatibility with both instrumentation strategies, we have to omit the `inlined = false` +from the advice method annotations. -Setting the `otel.javaagent.experimental.indy=true` configuration option will enable -`io.opentelemetry.javaagent.tooling.instrumentation.indy.AdviceTransformer` that will attempt to -convert advices automatically. This configuration is automatically enabled in CI when `test indy` -label is added to a pull-request or when the `-PtestIndy=true` parameter is added to gradle. -This configuration has no effect on instrumentation modules that explicitly return `true` or `false`. +We have two sets of instrumentation modules: +- "indy compatible": compatible with both "indy" and "inlined", do not override `isIndyModule` +- "inlined only": only compatible with "inlined", `isIndyModule` returns `false`. + +The first step of the migration is to move all the "inlined only" to the "indy compatible" category +by refactoring them with the limitations described below. + +Once everything is "indy compatible", we can evaluate changing the default value of `otel.javaagent.experimental.indy` +to `true` and make it non-experimental. ### shared classes and common classloader @@ -405,12 +418,12 @@ return a value from the enter advice and get the value in the exit advice with a with `@Advice.Enter`, for example: ```java -@Advice.OnMethodEnter(suppress = Throwable.class, inline = false) +@Advice.OnMethodEnter(suppress = Throwable.class) public static Object onEnter(@Advice.Argument(1) Object request) { return "enterValue"; } -@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class, inline = false) +@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) public static void onExit(@Advice.Argument(1) Object request, @Advice.Enter Object enterValue) { // do something with enterValue From 25660bdc7358a535ade9f7b23da8c36469ee80bd Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 11 Jun 2024 18:20:13 +0200 Subject: [PATCH 16/44] revert indy module for hibernate-* --- .../hibernate/v3_3/CriteriaInstrumentation.java | 4 ++-- .../hibernate/v3_3/HibernateInstrumentationModule.java | 5 ----- .../hibernate/v3_3/QueryInstrumentation.java | 2 +- .../hibernate/v3_3/SessionFactoryInstrumentation.java | 2 +- .../hibernate/v3_3/TransactionInstrumentation.java | 4 ++-- .../hibernate/v4_0/CriteriaInstrumentation.java | 4 ++-- .../hibernate/v4_0/HibernateInstrumentationModule.java | 5 ----- .../hibernate/v4_0/QueryInstrumentation.java | 4 ++-- .../hibernate/v4_0/SessionFactoryInstrumentation.java | 2 +- .../hibernate/v4_0/SessionInstrumentation.java | 10 +++++----- .../hibernate/v4_0/TransactionInstrumentation.java | 4 ++-- .../hibernate/v6_0/HibernateInstrumentationModule.java | 5 ----- .../hibernate/v6_0/QueryInstrumentation.java | 4 ++-- .../hibernate/v6_0/SessionFactoryInstrumentation.java | 2 +- .../hibernate/v6_0/SessionInstrumentation.java | 10 +++++----- .../hibernate/v6_0/TransactionInstrumentation.java | 2 +- .../hibernate/v4_3/HibernateInstrumentationModule.java | 5 ----- .../hibernate/v4_3/ProcedureCallInstrumentation.java | 4 ++-- .../hibernate/v4_3/SessionInstrumentation.java | 2 +- 19 files changed, 30 insertions(+), 50 deletions(-) diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java index 23d344807c20..96e1dc97b6ca 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java @@ -49,7 +49,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class CriteriaMethodAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + @Advice.OnMethodEnter(suppress = Throwable.class) public static Object startMethod( @Advice.This Criteria criteria, @Advice.Origin("#m") String name) { @@ -78,7 +78,7 @@ public static Object startMethod( callDepth, hibernateOperation, parentContext, instrumenter()); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( @Advice.Thrown Throwable throwable, @Advice.Enter Object enterScope) { diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java index 66efb8007082..8a9dd3a82040 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java @@ -37,11 +37,6 @@ public String getModuleGroup() { return "hibernate"; } - @Override - public boolean isIndyModule() { - return true; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java index b95c2fbc62d4..d7e36084dd22 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java @@ -49,7 +49,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class QueryMethodAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + @Advice.OnMethodEnter(suppress = Throwable.class) public static Object startMethod(@Advice.This Query query) { CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/SessionFactoryInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/SessionFactoryInstrumentation.java index 3aa48c7a8db7..4f23948d32f5 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/SessionFactoryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/SessionFactoryInstrumentation.java @@ -51,7 +51,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class SessionFactoryAdvice { - @Advice.OnMethodExit(suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(suppress = Throwable.class) public static void openSession(@Advice.Return Object session) { if (session instanceof Session) { diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java index f27925b629ec..3963d8f7164f 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java @@ -49,7 +49,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class TransactionCommitAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + @Advice.OnMethodEnter(suppress = Throwable.class) public static Object startCommit(@Advice.This Transaction transaction) { CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); @@ -72,7 +72,7 @@ public static Object startCommit(@Advice.This Transaction transaction) { callDepth, hibernateOperation, parentContext, instrumenter()); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endCommit( @Advice.Thrown Throwable throwable, @Advice.Enter @Nullable Object enterScope) { diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java index a7fd89f38296..3b04e060d761 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java @@ -49,7 +49,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class CriteriaMethodAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + @Advice.OnMethodEnter(suppress = Throwable.class) public static Object startMethod( @Advice.This Criteria criteria, @Advice.Origin("#m") String name) { @@ -78,7 +78,7 @@ public static Object startMethod( callDepth, hibernateOperation, parentContext, instrumenter()); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( @Advice.Thrown Throwable throwable, @Advice.Enter Object enterState) { diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java index 6526c136c5c4..e8a919d13c37 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java @@ -37,11 +37,6 @@ public String getModuleGroup() { return "hibernate"; } - @Override - public boolean isIndyModule() { - return true; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java index 7c87389c2a3d..fce5cc9dc5fd 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java @@ -49,7 +49,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class QueryMethodAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + @Advice.OnMethodEnter(suppress = Throwable.class) public static Object startMethod(@Advice.This Query query) { CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); @@ -72,7 +72,7 @@ public static Object startMethod(@Advice.This Query query) { callDepth, hibernateOperation, parentContext, instrumenter()); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( @Advice.Thrown Throwable throwable, @Advice.Enter Object enterState) { diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionFactoryInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionFactoryInstrumentation.java index c75bb0b5f26e..5f82adf80b00 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionFactoryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionFactoryInstrumentation.java @@ -47,7 +47,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class SessionFactoryAdvice { - @Advice.OnMethodExit(suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(suppress = Throwable.class) public static void openSession(@Advice.Return SharedSessionContract session) { VirtualField virtualField = diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java index 6d1c4e42e1e4..55765c442765 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java @@ -95,7 +95,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class SessionMethodAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + @Advice.OnMethodEnter(suppress = Throwable.class) public static Object startMethod( @Advice.This SharedSessionContract session, @Advice.Origin("#m") String name, @@ -125,7 +125,7 @@ public static Object startMethod( callDepth, hibernateOperation, parentContext, instrumenter()); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( @Advice.Thrown Throwable throwable, @Advice.Enter Object enterState) { @@ -136,7 +136,7 @@ public static void endMethod( @SuppressWarnings("unused") public static class GetQueryAdvice { - @Advice.OnMethodExit(suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(suppress = Throwable.class) public static void getQuery( @Advice.This SharedSessionContract session, @Advice.Return Query query) { @@ -152,7 +152,7 @@ public static void getQuery( @SuppressWarnings("unused") public static class GetTransactionAdvice { - @Advice.OnMethodExit(suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(suppress = Throwable.class) public static void getTransaction( @Advice.This SharedSessionContract session, @Advice.Return Transaction transaction) { @@ -168,7 +168,7 @@ public static void getTransaction( @SuppressWarnings("unused") public static class GetCriteriaAdvice { - @Advice.OnMethodExit(suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(suppress = Throwable.class) public static void getCriteria( @Advice.This SharedSessionContract session, @Advice.Return Criteria criteria) { diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java index 7aba64c051d7..0d9af9407d53 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java @@ -48,7 +48,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class TransactionCommitAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + @Advice.OnMethodEnter(suppress = Throwable.class) public static Object startCommit(@Advice.This Transaction transaction) { CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); @@ -71,7 +71,7 @@ public static Object startCommit(@Advice.This Transaction transaction) { callDepth, hibernateOperation, parentContext, instrumenter()); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endCommit( @Advice.Thrown Throwable throwable, @Advice.Enter Object enterScope) { diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java index 810ca2b085fc..83af9e7b0f90 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java @@ -35,11 +35,6 @@ public String getModuleGroup() { return "hibernate"; } - @Override - public boolean isIndyModule() { - return true; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/QueryInstrumentation.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/QueryInstrumentation.java index ae2a83304a27..5d940522723a 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/QueryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/QueryInstrumentation.java @@ -63,7 +63,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class QueryMethodAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + @Advice.OnMethodEnter(suppress = Throwable.class) public static Object startMethod(@Advice.This CommonQueryContract query) { CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); @@ -98,7 +98,7 @@ public static Object startMethod(@Advice.This CommonQueryContract query) { callDepth, hibernateOperation, parentContext, instrumenter()); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( @Advice.Thrown Throwable throwable, @Advice.Enter Object enterScope) { diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/SessionFactoryInstrumentation.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/SessionFactoryInstrumentation.java index c4a5d6fcf818..ae5807c5b8a9 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/SessionFactoryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/SessionFactoryInstrumentation.java @@ -52,7 +52,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class SessionFactoryAdvice { - @Advice.OnMethodExit(suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(suppress = Throwable.class) public static void openSession(@Advice.Return SharedSessionContract session) { VirtualField virtualField = diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/SessionInstrumentation.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/SessionInstrumentation.java index b349c4e2d57c..fde18f963d42 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/SessionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/SessionInstrumentation.java @@ -94,7 +94,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class SessionMethodAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + @Advice.OnMethodEnter(suppress = Throwable.class) public static void startMethod( @Advice.This SharedSessionContract session, @Advice.Origin("#m") String name, @@ -128,7 +128,7 @@ public static void startMethod( scope = context.makeCurrent(); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( @Advice.Thrown Throwable throwable, @Advice.Local("otelCallDepth") CallDepth callDepth, @@ -150,7 +150,7 @@ public static void endMethod( @SuppressWarnings("unused") public static class GetQueryAdvice { - @Advice.OnMethodExit(suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(suppress = Throwable.class) public static void getQuery( @Advice.This SharedSessionContract session, @Advice.Return Object queryObject) { if (!(queryObject instanceof CommonQueryContract)) { @@ -170,7 +170,7 @@ public static void getQuery( @SuppressWarnings("unused") public static class GetTransactionAdvice { - @Advice.OnMethodExit(suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(suppress = Throwable.class) public static void getTransaction( @Advice.This SharedSessionContract session, @Advice.Return Transaction transaction) { @@ -186,7 +186,7 @@ public static void getTransaction( @SuppressWarnings("unused") public static class GetCriteriaAdvice { - @Advice.OnMethodExit(suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(suppress = Throwable.class) public static void getCriteria( @Advice.This SharedSessionContract session, @Advice.Return CriteriaQuery criteria) { diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/TransactionInstrumentation.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/TransactionInstrumentation.java index ac0261750400..ee6ae0b8c67f 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/TransactionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/TransactionInstrumentation.java @@ -48,7 +48,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class TransactionCommitAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + @Advice.OnMethodEnter(suppress = Throwable.class) public static Object startCommit(@Advice.This Transaction transaction) { CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); diff --git a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java index e80b1bc6e8f4..3e914808d004 100644 --- a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java @@ -32,11 +32,6 @@ public String getModuleGroup() { return "hibernate"; } - @Override - public boolean isIndyModule() { - return true; - } - @Override public List typeInstrumentations() { return asList(new ProcedureCallInstrumentation(), new SessionInstrumentation()); diff --git a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java index 76f6d9192984..a7b72496b5b4 100644 --- a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java +++ b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java @@ -47,7 +47,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class ProcedureCallMethodAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) + @Advice.OnMethodEnter(suppress = Throwable.class) public static Object startMethod( @Advice.This ProcedureCall call, @Advice.Origin("#m") String name) { @@ -71,7 +71,7 @@ public static Object startMethod( callDepth, hibernateOperation, parentContext, instrumenter()); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( @Advice.Thrown Throwable throwable, @Advice.Enter Object enterScope) { diff --git a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/SessionInstrumentation.java b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/SessionInstrumentation.java index 5ca9e13529a5..58d7c8d675d0 100644 --- a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/SessionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/SessionInstrumentation.java @@ -44,7 +44,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class GetProcedureCallAdvice { - @Advice.OnMethodExit(suppress = Throwable.class, inline = false) + @Advice.OnMethodExit(suppress = Throwable.class) public static void getProcedureCall( @Advice.This SharedSessionContract session, @Advice.Return ProcedureCall returned) { From ac0e649275ba0ef94946b47414f199da1e6703f3 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 11 Jun 2024 18:55:17 +0200 Subject: [PATCH 17/44] move aws-sdk to #11552 --- .../awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java | 8 +++----- .../awssdk/v1_11/AwsSdkInstrumentationModule.java | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java index ff02429b910c..a3aa56398c7d 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java @@ -12,14 +12,12 @@ import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; -import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; // TODO: Copy & paste with only trivial adaptions from v2 -abstract class AbstractAwsSdkInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +abstract class AbstractAwsSdkInstrumentationModule extends InstrumentationModule { protected AbstractAwsSdkInstrumentationModule(String additionalInstrumentationName) { super("aws-sdk", "aws-sdk-1.11", additionalInstrumentationName); @@ -31,8 +29,8 @@ public boolean isHelperClass(String className) { } @Override - public String getModuleGroup() { - return "aws-sdk"; + public boolean isIndyModule() { + return false; } @Override diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java index 89a4a6c8f673..d5ba3d2c5add 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java @@ -10,12 +10,10 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; @AutoService(InstrumentationModule.class) -public class AwsSdkInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class AwsSdkInstrumentationModule extends InstrumentationModule { public AwsSdkInstrumentationModule() { super("aws-sdk", "aws-sdk-1.11", "aws-sdk-1.11-core"); } @@ -26,8 +24,8 @@ public boolean isHelperClass(String className) { } @Override - public String getModuleGroup() { - return "aws-sdk"; + public boolean isIndyModule() { + return false; } @Override From f48e20340954d885c04d4a069ef3d1f42c2e97aa Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 11 Jun 2024 19:12:55 +0200 Subject: [PATCH 18/44] move hibernate to #11553 --- .../v3_3/CriteriaInstrumentation.java | 41 ++++++---- .../v3_3/HibernateInstrumentationModule.java | 9 +-- .../hibernate/v3_3/QueryInstrumentation.java | 36 ++++++--- .../v3_3/TransactionInstrumentation.java | 38 +++++++--- .../v4_0/CriteriaInstrumentation.java | 41 ++++++---- .../v4_0/HibernateInstrumentationModule.java | 10 +-- .../hibernate/v4_0/QueryInstrumentation.java | 36 ++++++--- .../v4_0/SessionInstrumentation.java | 37 ++++++--- .../v4_0/TransactionInstrumentation.java | 37 ++++++--- .../v6_0/HibernateInstrumentationModule.java | 10 +-- .../hibernate/v6_0/QueryInstrumentation.java | 38 +++++++--- .../v6_0/TransactionInstrumentation.java | 37 ++++++--- .../hibernate/HibernateOperationScope.java | 75 ------------------- .../v4_3/HibernateInstrumentationModule.java | 10 +-- .../v4_3/ProcedureCallInstrumentation.java | 38 +++++++--- 15 files changed, 282 insertions(+), 211 deletions(-) delete mode 100644 instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/HibernateOperationScope.java diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java index 96e1dc97b6ca..e995738cd723 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java @@ -13,13 +13,13 @@ import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; -import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -50,12 +50,17 @@ public void transform(TypeTransformer transformer) { public static class CriteriaMethodAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static Object startMethod( - @Advice.This Criteria criteria, @Advice.Origin("#m") String name) { - - CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); + public static void startMethod( + @Advice.This Criteria criteria, + @Advice.Origin("#m") String name, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + + callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return callDepth; + return; } String entityName = null; @@ -68,21 +73,31 @@ public static Object startMethod( SessionInfo sessionInfo = criteriaVirtualField.get(criteria); Context parentContext = Java8BytecodeBridge.currentContext(); - HibernateOperation hibernateOperation = - new HibernateOperation("Criteria." + name, entityName, sessionInfo); + hibernateOperation = new HibernateOperation("Criteria." + name, entityName, sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return callDepth; + return; } - return HibernateOperationScope.startNew( - callDepth, hibernateOperation, parentContext, instrumenter()); + context = instrumenter().start(parentContext, hibernateOperation); + scope = context.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( - @Advice.Thrown Throwable throwable, @Advice.Enter Object enterScope) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + + if (callDepth.decrementAndGet() > 0) { + return; + } - HibernateOperationScope.end(enterScope, instrumenter(), throwable); + if (scope != null) { + scope.close(); + instrumenter().end(context, hibernateOperation, null, throwable); + } } } } diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java index 8a9dd3a82040..d9f6d5a919ac 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java @@ -11,13 +11,11 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class HibernateInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class HibernateInstrumentationModule extends InstrumentationModule { public HibernateInstrumentationModule() { super("hibernate", "hibernate-3.3"); @@ -32,11 +30,6 @@ public ElementMatcher.Junction classLoaderMatcher() { "org.hibernate.transaction.JBossTransactionManagerLookup"); } - @Override - public String getModuleGroup() { - return "hibernate"; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java index d7e36084dd22..5a9742dcbcd0 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java @@ -14,13 +14,13 @@ import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; -import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -50,11 +50,16 @@ public void transform(TypeTransformer transformer) { public static class QueryMethodAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static Object startMethod(@Advice.This Query query) { + public static void startMethod( + @Advice.This Query query, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); + callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return callDepth; + return; } VirtualField queryVirtualField = @@ -62,21 +67,32 @@ public static Object startMethod(@Advice.This Query query) { SessionInfo sessionInfo = queryVirtualField.get(query); Context parentContext = Java8BytecodeBridge.currentContext(); - HibernateOperation hibernateOperation = + hibernateOperation = new HibernateOperation(getOperationNameForQuery(query.getQueryString()), sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return callDepth; + return; } - return HibernateOperationScope.startNew( - callDepth, hibernateOperation, parentContext, instrumenter()); + context = instrumenter().start(parentContext, hibernateOperation); + scope = context.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( - @Advice.Thrown Throwable throwable, @Advice.Enter Object enterScope) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - HibernateOperationScope.end(enterScope, instrumenter(), throwable); + if (callDepth.decrementAndGet() > 0) { + return; + } + + if (scope != null) { + scope.close(); + instrumenter().end(context, hibernateOperation, null, throwable); + } } } } diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java index 3963d8f7164f..c9f8631f54b8 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java @@ -13,15 +13,14 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; -import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; -import javax.annotation.Nullable; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -50,11 +49,16 @@ public void transform(TypeTransformer transformer) { public static class TransactionCommitAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static Object startCommit(@Advice.This Transaction transaction) { + public static void startCommit( + @Advice.This Transaction transaction, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); + callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return callDepth; + return; } VirtualField transactionVirtualField = @@ -62,21 +66,31 @@ public static Object startCommit(@Advice.This Transaction transaction) { SessionInfo sessionInfo = transactionVirtualField.get(transaction); Context parentContext = Java8BytecodeBridge.currentContext(); - HibernateOperation hibernateOperation = - new HibernateOperation("Transaction.commit", sessionInfo); + hibernateOperation = new HibernateOperation("Transaction.commit", sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return callDepth; + return; } - return HibernateOperationScope.startNew( - callDepth, hibernateOperation, parentContext, instrumenter()); + context = instrumenter().start(parentContext, hibernateOperation); + scope = context.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endCommit( - @Advice.Thrown Throwable throwable, @Advice.Enter @Nullable Object enterScope) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - HibernateOperationScope.end(enterScope, instrumenter(), throwable); + if (callDepth.decrementAndGet() > 0) { + return; + } + + if (scope != null) { + scope.close(); + instrumenter().end(context, hibernateOperation, null, throwable); + } } } } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java index 3b04e060d761..aec640bc6b07 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java @@ -13,13 +13,13 @@ import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; -import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -50,12 +50,17 @@ public void transform(TypeTransformer transformer) { public static class CriteriaMethodAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static Object startMethod( - @Advice.This Criteria criteria, @Advice.Origin("#m") String name) { - - CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); + public static void startMethod( + @Advice.This Criteria criteria, + @Advice.Origin("#m") String name, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + + callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return callDepth; + return; } String entityName = null; @@ -68,21 +73,31 @@ public static Object startMethod( SessionInfo sessionInfo = criteriaVirtualField.get(criteria); Context parentContext = Java8BytecodeBridge.currentContext(); - HibernateOperation hibernateOperation = - new HibernateOperation("Criteria." + name, entityName, sessionInfo); + hibernateOperation = new HibernateOperation("Criteria." + name, entityName, sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return callDepth; + return; } - return HibernateOperationScope.startNew( - callDepth, hibernateOperation, parentContext, instrumenter()); + context = instrumenter().start(parentContext, hibernateOperation); + scope = context.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( - @Advice.Thrown Throwable throwable, @Advice.Enter Object enterState) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + + if (callDepth.decrementAndGet() > 0) { + return; + } - HibernateOperationScope.end(enterState, instrumenter(), throwable); + if (scope != null) { + scope.close(); + instrumenter().end(context, hibernateOperation, null, throwable); + } } } } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java index e8a919d13c37..9685997529c2 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java @@ -11,13 +11,11 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class HibernateInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class HibernateInstrumentationModule extends InstrumentationModule { public HibernateInstrumentationModule() { super("hibernate", "hibernate-4.0"); @@ -33,8 +31,10 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public String getModuleGroup() { - return "hibernate"; + public boolean isIndyModule() { + // shares classes with hibernate-procedure-call-4.3, these classes should be in the same class + // loader + return false; } @Override diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java index fce5cc9dc5fd..af0618e6c773 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java @@ -14,13 +14,13 @@ import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; -import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -50,11 +50,16 @@ public void transform(TypeTransformer transformer) { public static class QueryMethodAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static Object startMethod(@Advice.This Query query) { + public static void startMethod( + @Advice.This Query query, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); + callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return callDepth; + return; } VirtualField queryVirtualField = @@ -62,21 +67,32 @@ public static Object startMethod(@Advice.This Query query) { SessionInfo sessionInfo = queryVirtualField.get(query); Context parentContext = Java8BytecodeBridge.currentContext(); - HibernateOperation hibernateOperation = + hibernateOperation = new HibernateOperation(getOperationNameForQuery(query.getQueryString()), sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return callDepth; + return; } - return HibernateOperationScope.startNew( - callDepth, hibernateOperation, parentContext, instrumenter()); + context = instrumenter().start(parentContext, hibernateOperation); + scope = context.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( - @Advice.Thrown Throwable throwable, @Advice.Enter Object enterState) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - HibernateOperationScope.end(enterState, instrumenter(), throwable); + if (callDepth.decrementAndGet() > 0) { + return; + } + + if (scope != null) { + scope.close(); + instrumenter().end(context, hibernateOperation, null, throwable); + } } } } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java index 55765c442765..e5e9fbc5116e 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java @@ -18,13 +18,13 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; -import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -96,16 +96,20 @@ public void transform(TypeTransformer transformer) { public static class SessionMethodAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static Object startMethod( + public static void startMethod( @Advice.This SharedSessionContract session, @Advice.Origin("#m") String name, @Advice.Origin("#d") String descriptor, @Advice.Argument(0) Object arg0, - @Advice.Argument(value = 1, optional = true) Object arg1) { + @Advice.Argument(value = 1, optional = true) Object arg1, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); + callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return callDepth; + return; } VirtualField virtualField = @@ -115,21 +119,32 @@ public static Object startMethod( Context parentContext = Java8BytecodeBridge.currentContext(); String entityName = getEntityName(descriptor, arg0, arg1, EntityNameUtil.bestGuessEntityName(session)); - HibernateOperation hibernateOperation = + hibernateOperation = new HibernateOperation(getSessionMethodOperationName(name), entityName, sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return callDepth; + return; } - return HibernateOperationScope.startNew( - callDepth, hibernateOperation, parentContext, instrumenter()); + context = instrumenter().start(parentContext, hibernateOperation); + scope = context.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( - @Advice.Thrown Throwable throwable, @Advice.Enter Object enterState) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + + if (callDepth.decrementAndGet() > 0) { + return; + } - HibernateOperationScope.end(enterState, instrumenter(), throwable); + if (scope != null) { + scope.close(); + instrumenter().end(context, hibernateOperation, null, throwable); + } } } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java index 0d9af9407d53..16be5e006ad9 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java @@ -13,13 +13,13 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; -import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -49,11 +49,16 @@ public void transform(TypeTransformer transformer) { public static class TransactionCommitAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static Object startCommit(@Advice.This Transaction transaction) { + public static void startCommit( + @Advice.This Transaction transaction, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); + callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return callDepth; + return; } VirtualField transactionVirtualField = @@ -61,21 +66,31 @@ public static Object startCommit(@Advice.This Transaction transaction) { SessionInfo sessionInfo = transactionVirtualField.get(transaction); Context parentContext = Java8BytecodeBridge.currentContext(); - HibernateOperation hibernateOperation = - new HibernateOperation("Transaction.commit", sessionInfo); + hibernateOperation = new HibernateOperation("Transaction.commit", sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return callDepth; + return; } - return HibernateOperationScope.startNew( - callDepth, hibernateOperation, parentContext, instrumenter()); + context = instrumenter().start(parentContext, hibernateOperation); + scope = context.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endCommit( - @Advice.Thrown Throwable throwable, @Advice.Enter Object enterScope) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - HibernateOperationScope.end(enterScope, instrumenter(), throwable); + if (callDepth.decrementAndGet() > 0) { + return; + } + + if (scope != null) { + scope.close(); + instrumenter().end(context, hibernateOperation, null, throwable); + } } } } diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java index 83af9e7b0f90..b8c8a34dd120 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java @@ -11,13 +11,11 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class HibernateInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class HibernateInstrumentationModule extends InstrumentationModule { public HibernateInstrumentationModule() { super("hibernate", "hibernate-6.0"); @@ -31,8 +29,10 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public String getModuleGroup() { - return "hibernate"; + public boolean isIndyModule() { + // shares classes with hibernate-procedure-call-4.3, these classes should be in the same class + // loader + return false; } @Override diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/QueryInstrumentation.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/QueryInstrumentation.java index 5d940522723a..141175c30269 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/QueryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/QueryInstrumentation.java @@ -14,13 +14,13 @@ import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; -import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -64,11 +64,16 @@ public void transform(TypeTransformer transformer) { public static class QueryMethodAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static Object startMethod(@Advice.This CommonQueryContract query) { - - CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); + public static void startMethod( + @Advice.This CommonQueryContract query, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + + callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return callDepth; + return; } String queryString = null; @@ -88,21 +93,32 @@ public static Object startMethod(@Advice.This CommonQueryContract query) { SessionInfo sessionInfo = queryVirtualField.get(query); Context parentContext = Java8BytecodeBridge.currentContext(); - HibernateOperation hibernateOperation = + hibernateOperation = new HibernateOperation(getOperationNameForQuery(queryString), sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return callDepth; + return; } - return HibernateOperationScope.startNew( - callDepth, hibernateOperation, parentContext, instrumenter()); + context = instrumenter().start(parentContext, hibernateOperation); + scope = context.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( - @Advice.Thrown Throwable throwable, @Advice.Enter Object enterScope) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + + if (callDepth.decrementAndGet() > 0) { + return; + } - HibernateOperationScope.end(enterScope, instrumenter(), throwable); + if (scope != null) { + scope.close(); + instrumenter().end(context, hibernateOperation, null, throwable); + } } } } diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/TransactionInstrumentation.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/TransactionInstrumentation.java index ee6ae0b8c67f..711773e4e5b4 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/TransactionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/TransactionInstrumentation.java @@ -13,13 +13,13 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; -import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -49,11 +49,16 @@ public void transform(TypeTransformer transformer) { public static class TransactionCommitAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static Object startCommit(@Advice.This Transaction transaction) { + public static void startCommit( + @Advice.This Transaction transaction, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); + callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return callDepth; + return; } VirtualField transactionVirtualField = @@ -61,21 +66,31 @@ public static Object startCommit(@Advice.This Transaction transaction) { SessionInfo sessionInfo = transactionVirtualField.get(transaction); Context parentContext = Java8BytecodeBridge.currentContext(); - HibernateOperation hibernateOperation = - new HibernateOperation("Transaction.commit", sessionInfo); + hibernateOperation = new HibernateOperation("Transaction.commit", sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return callDepth; + return; } - return HibernateOperationScope.startNew( - callDepth, hibernateOperation, parentContext, instrumenter()); + context = instrumenter().start(parentContext, hibernateOperation); + scope = context.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endCommit( - @Advice.Thrown Throwable throwable, @Advice.Enter Object enterScope) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - HibernateOperationScope.end(enterScope, instrumenter(), throwable); + if (callDepth.decrementAndGet() > 0) { + return; + } + + if (scope != null) { + scope.close(); + instrumenter().end(context, hibernateOperation, null, throwable); + } } } } diff --git a/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/HibernateOperationScope.java b/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/HibernateOperationScope.java deleted file mode 100644 index a68547463ff6..000000000000 --- a/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/HibernateOperationScope.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.hibernate; - -import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.javaagent.bootstrap.CallDepth; - -public class HibernateOperationScope { - - private final CallDepth callDepth; - private final HibernateOperation hibernateOperation; - private final Context context; - private final Scope scope; - - private HibernateOperationScope( - CallDepth callDepth, HibernateOperation hibernateOperation, Context context, Scope scope) { - this.callDepth = callDepth; - this.hibernateOperation = hibernateOperation; - this.context = context; - this.scope = scope; - } - - /** - * Starts operation scope - * - * @param callDepth call depth - * @param hibernateOperation hibernate operation - * @param parentContext parent context - * @param instrumenter instrumenter - * @return operation scope, to be ended with {@link #end(Object, Instrumenter, Throwable)} on exit - * advice - */ - public static HibernateOperationScope startNew( - CallDepth callDepth, - HibernateOperation hibernateOperation, - Context parentContext, - Instrumenter instrumenter) { - - Context context = instrumenter.start(parentContext, hibernateOperation); - return new HibernateOperationScope( - callDepth, hibernateOperation, context, context.makeCurrent()); - } - - /** - * Ends operation scope - * - * @param o {@link HibernateOperationScope} or {@link CallDepth} from enter advice - * @param instrumenter instrumenter - * @param throwable thrown exception - */ - public static void end( - Object o, Instrumenter instrumenter, Throwable throwable) { - if (o instanceof CallDepth) { - ((CallDepth) o).decrementAndGet(); - return; - } - - if (!(o instanceof HibernateOperationScope)) { - throw new IllegalArgumentException("unexpected argument"); - } - - HibernateOperationScope state = (HibernateOperationScope) o; - int depth = state.callDepth.decrementAndGet(); - if (depth != 0) { - throw new IllegalStateException("unexpected call depth " + depth); - } - state.scope.close(); - instrumenter.end(state.context, state.hibernateOperation, null, throwable); - } -} diff --git a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java index 3e914808d004..11b04b34903e 100644 --- a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/HibernateInstrumentationModule.java @@ -11,13 +11,11 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class HibernateInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class HibernateInstrumentationModule extends InstrumentationModule { public HibernateInstrumentationModule() { super("hibernate-procedure-call", "hibernate-procedure-call-4.3", "hibernate"); } @@ -28,8 +26,10 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public String getModuleGroup() { - return "hibernate"; + public boolean isIndyModule() { + // uses SessionInfo class from hibernate common which is now in separate class loader for all + // instrumentations + return false; } @Override diff --git a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java index a7b72496b5b4..ed9671808c2f 100644 --- a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java +++ b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java @@ -12,13 +12,13 @@ import static net.bytebuddy.matcher.ElementMatchers.named; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.javaagent.bootstrap.CallDepth; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperation; -import io.opentelemetry.javaagent.instrumentation.hibernate.HibernateOperationScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionInfo; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; @@ -48,12 +48,17 @@ public void transform(TypeTransformer transformer) { public static class ProcedureCallMethodAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static Object startMethod( - @Advice.This ProcedureCall call, @Advice.Origin("#m") String name) { + public static void startMethod( + @Advice.This ProcedureCall call, + @Advice.Origin("#m") String name, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - CallDepth callDepth = CallDepth.forClass(HibernateOperation.class); + callDepth = CallDepth.forClass(HibernateOperation.class); if (callDepth.getAndIncrement() > 0) { - return callDepth; + return; } VirtualField criteriaVirtualField = @@ -61,21 +66,32 @@ public static Object startMethod( SessionInfo sessionInfo = criteriaVirtualField.get(call); Context parentContext = Java8BytecodeBridge.currentContext(); - HibernateOperation hibernateOperation = + hibernateOperation = new HibernateOperation("ProcedureCall." + name, call.getProcedureName(), sessionInfo); if (!instrumenter().shouldStart(parentContext, hibernateOperation)) { - return callDepth; + return; } - return HibernateOperationScope.startNew( - callDepth, hibernateOperation, parentContext, instrumenter()); + context = instrumenter().start(parentContext, hibernateOperation); + scope = context.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( - @Advice.Thrown Throwable throwable, @Advice.Enter Object enterScope) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelHibernateOperation") HibernateOperation hibernateOperation, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - HibernateOperationScope.end(enterScope, instrumenter(), throwable); + if (callDepth.decrementAndGet() > 0) { + return; + } + + if (scope != null) { + scope.close(); + instrumenter().end(context, hibernateOperation, null, throwable); + } } } } From 9aaf6282d760f8984b610a6a8bc6af38cf010f5f Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 11 Jun 2024 22:06:29 +0200 Subject: [PATCH 19/44] move elasticsearch to #11554 --- .../ElasticsearchApiClientInstrumentationModule.java | 10 +++++----- .../v7_0/ElasticsearchRest7InstrumentationModule.java | 9 ++++----- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/apiclient/ElasticsearchApiClientInstrumentationModule.java b/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/apiclient/ElasticsearchApiClientInstrumentationModule.java index 75cad4dee6fd..a0082f7a0888 100644 --- a/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/apiclient/ElasticsearchApiClientInstrumentationModule.java +++ b/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/apiclient/ElasticsearchApiClientInstrumentationModule.java @@ -12,13 +12,11 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class ElasticsearchApiClientInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class ElasticsearchApiClientInstrumentationModule extends InstrumentationModule { public ElasticsearchApiClientInstrumentationModule() { super("elasticsearch-api-client", "elasticsearch-api-client-7.16", "elasticsearch"); } @@ -33,8 +31,10 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public String getModuleGroup() { - return "elasticsearch"; + public boolean isIndyModule() { + // java.lang.ClassCastException: class + // io.opentelemetry.javaagent.shaded.instrumentation.elasticsearch.rest.internal.ElasticsearchEndpointDefinition cannot be cast to class io.opentelemetry.javaagent.shaded.instrumentation.elasticsearch.rest.internal.ElasticsearchEndpointDefinition (io.opentelemetry.javaagent.shaded.instrumentation.elasticsearch.rest.internal.ElasticsearchEndpointDefinition is in unnamed module of loader io.opentelemetry.javaagent.tooling.instrumentation.indy.InstrumentationModuleClassLoader @6baee63b; io.opentelemetry.javaagent.shaded.instrumentation.elasticsearch.rest.internal.ElasticsearchEndpointDefinition is in unnamed module of loader 'app') + return false; } @Override diff --git a/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7InstrumentationModule.java b/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7InstrumentationModule.java index 22d00be64dbd..919a8318b359 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7InstrumentationModule.java +++ b/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7InstrumentationModule.java @@ -12,13 +12,11 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class ElasticsearchRest7InstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class ElasticsearchRest7InstrumentationModule extends InstrumentationModule { public ElasticsearchRest7InstrumentationModule() { super("elasticsearch-rest", "elasticsearch-rest-7.0", "elasticsearch"); } @@ -35,8 +33,9 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public String getModuleGroup() { - return "elasticsearch"; + public boolean isIndyModule() { + // shares a virtual field with elasticsearch-api-client + return false; } @Override From cd8523847583b0b98ec9856efb13c9345f639bfd Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 11 Jun 2024 22:42:10 +0200 Subject: [PATCH 20/44] document params, return value and fields --- .../writing-instrumentation-module.md | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 050046f9220d..5eb6c7d3e2c7 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -429,3 +429,60 @@ public static void onExit(@Advice.Argument(1) Object request, // do something with enterValue } ``` + +### modifying method arguments + +With inlined advices, using the `@Advice.Argument` annotation on method parameter with `readOnly = false` +allows to modify instrumented method arguments. + +When using non-inlined advices, reading the argument values is still done with `@Advice.Argument` +annotated parameters, however modifying the values is done through the advice method return value +and `@Advice.AssignReturned.ToArguments` annotation: + +```java +@Advice.OnMethodEnter(suppress = Throwable.class) +@Advice.AssignReturned.ToArguments(@ToArgument(1)) +public static Object onEnter(@Advice.Argument(1) Object request) { + return "hello"; +} +``` + +It is possible to modify multiple arguments at once by using an array, see usages of +`@Advice.AssignReturned.ToArguments` for detailed examples. + +### modifying method return value + +With inlined advices, using the `@Advice.Return` annotation on method parameter with `readOnly = false` +allows to modify instrumented method return value on exit advice. + +When using non-inlined advices, reading the original return value is still done with `@Advice.Return` +annotated parameter, however modifying the value is done through the advice method return value +and `@Advice.AssignReturned.ToReturned` + +```java +@Advice.OnMethodExit(suppress = Throwable.class) +@Advice.AssignReturned.ToReturned +public static Object onEnter(@Advice.Return Object returnValue) { + return "hello"; +} +``` + +### writing to internal class fields + +With inlined advices, using the `@Advice.FieldValue(value = "fieldName", readOnly = false)` annotation +on advice method parameter allows to modify the `fieldName` field of the instrumented class. + +When using non-inlined advices, reading the original field value is still done with `@Advice.FieldValue` +annotated parameter, however modifying the value is done through the advice method return value +and `@Advice.AssignReturned.ToFields` annotation: + +```java +@Advice.OnMethodExit(suppress = Throwable.class) +@Advice.AssignReturned.ToFields(@ToField(value = "fieldName")) +public static Object onEnter(@Advice.FieldValue("fieldName") Object originalFieldValue) { + return "newFieldValue"; +} +``` + +It is possible to modify multiple fields at once by using an array, see usages of +`@Advice.AssignReturned.ToFields` for detailed examples. From ae8760338a1c578e66d9629e1310ebae98f1686c Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 12 Jun 2024 09:54:40 +0200 Subject: [PATCH 21/44] move netty-* to #11559 --- .../netty/v3_8/NettyInstrumentationModule.java | 9 +-------- .../netty/v4_0/NettyInstrumentationModule.java | 9 +-------- .../netty/v4_1/NettyInstrumentationModule.java | 10 +++++----- 3 files changed, 7 insertions(+), 21 deletions(-) diff --git a/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java b/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java index a6cb34099421..54b65990b13f 100644 --- a/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java +++ b/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java @@ -11,13 +11,11 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class NettyInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class NettyInstrumentationModule extends InstrumentationModule { public NettyInstrumentationModule() { super("netty", "netty-3.8"); } @@ -27,11 +25,6 @@ public ElementMatcher.Junction classLoaderMatcher() { return hasClassesNamed("org.jboss.netty.handler.codec.http.HttpMessage"); } - @Override - public String getModuleGroup() { - return "netty"; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java b/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java index a20246a5d1e3..1d2151795892 100644 --- a/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java +++ b/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java @@ -12,14 +12,12 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import io.opentelemetry.javaagent.instrumentation.netty.v4.common.NettyFutureInstrumentation; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class NettyInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class NettyInstrumentationModule extends InstrumentationModule { public NettyInstrumentationModule() { super("netty", "netty-4.0"); } @@ -33,11 +31,6 @@ public ElementMatcher.Junction classLoaderMatcher() { not(hasClassesNamed("io.netty.handler.codec.http.CombinedHttpHeaders"))); } - @Override - public String getModuleGroup() { - return "netty"; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java b/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java index 9d9c71505726..6f5f5a28038b 100644 --- a/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java +++ b/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java @@ -11,14 +11,12 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import io.opentelemetry.javaagent.instrumentation.netty.v4.common.NettyFutureInstrumentation; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class NettyInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class NettyInstrumentationModule extends InstrumentationModule { public NettyInstrumentationModule() { super("netty", "netty-4.1"); } @@ -31,8 +29,10 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public String getModuleGroup() { - return "netty"; + public boolean isIndyModule() { + // netty instrumentation classes are used in other instrumentations which causes class cast + // exceptions + return false; } @Override From 7fc8e151a25693034aefd02bd73ff8012b37c93e Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 12 Jun 2024 09:57:46 +0200 Subject: [PATCH 22/44] revert changes for akka --- .../server/AkkaHttpServerInstrumentationModule.java | 10 +++++----- .../AkkaHttpServerRouteInstrumentationModule.java | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/AkkaHttpServerInstrumentationModule.java b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/AkkaHttpServerInstrumentationModule.java index 48ad1a42b0fb..b84f85f78816 100644 --- a/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/AkkaHttpServerInstrumentationModule.java +++ b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/AkkaHttpServerInstrumentationModule.java @@ -11,13 +11,11 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class AkkaHttpServerInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class AkkaHttpServerInstrumentationModule extends InstrumentationModule { public AkkaHttpServerInstrumentationModule() { super("akka-http", "akka-http-10.0", "akka-http-server"); } @@ -30,8 +28,10 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public String getModuleGroup() { - return "akka-http"; + public boolean isIndyModule() { + // AkkaHttpServerInstrumentationModule and AkkaHttpServerRouteInstrumentationModule share + // AkkaRouteHolder class + return false; } @Override diff --git a/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/route/AkkaHttpServerRouteInstrumentationModule.java b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/route/AkkaHttpServerRouteInstrumentationModule.java index 169c9253f895..6c484eb968ed 100644 --- a/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/route/AkkaHttpServerRouteInstrumentationModule.java +++ b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/server/route/AkkaHttpServerRouteInstrumentationModule.java @@ -10,7 +10,6 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; /** @@ -18,15 +17,16 @@ * AkkaHttpServerInstrumentationModule applies to classes in akka-http-core.jar */ @AutoService(InstrumentationModule.class) -public class AkkaHttpServerRouteInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class AkkaHttpServerRouteInstrumentationModule extends InstrumentationModule { public AkkaHttpServerRouteInstrumentationModule() { super("akka-http", "akka-http-10.0", "akka-http-server", "akka-http-server-route"); } @Override - public String getModuleGroup() { - return "akka-http"; + public boolean isIndyModule() { + // AkkaHttpServerInstrumentationModule and AkkaHttpServerRouteInstrumentationModule share + // AkkaRouteHolder class + return false; } @Override From c477985594d6f8dfb85ff0fce021a2cb47b4bcae Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 12 Jun 2024 15:26:49 +0200 Subject: [PATCH 23/44] add indy/inline clarification --- docs/contributing/writing-instrumentation-module.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 5eb6c7d3e2c7..daf0f0f3c452 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -370,6 +370,15 @@ modules using this instrumentation strategy. The most common way to instrument code with bytebuddy relies on inlining, this strategy will be referred as "inlined" strategy in opposition to "indy". +For inlined advices, the advice code is directly copied into the instrumented method. +In addition, all helper classes are injected into the classloader of the instrumented classes. + +For indy, advice classes are not inlined. Instead, they loaded alongside with all helper classes +into a special `InstrumentationModuleClassloader`, which sees the classes from both the instrumented +application classloader and the agent classloader. +The instrumented classes call the advice classes residing in the `InstrumentationModuleClassloader` via +invokedynamic bytecode instructions. + ### Indy modules and transition Having all instrumentation rely on native "indy" instrumentation is a tedious task and can't be @@ -436,7 +445,7 @@ With inlined advices, using the `@Advice.Argument` annotation on method paramete allows to modify instrumented method arguments. When using non-inlined advices, reading the argument values is still done with `@Advice.Argument` -annotated parameters, however modifying the values is done through the advice method return value +annotated parameters, however modifying the values is done through the advice method return value and `@Advice.AssignReturned.ToArguments` annotation: ```java From fc0be198350271f25f3be8c9f53ef2811a378f9f Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:31:25 +0200 Subject: [PATCH 24/44] post-review changes --- .../writing-instrumentation-module.md | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index daf0f0f3c452..97d8a2cf08bd 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -381,19 +381,22 @@ invokedynamic bytecode instructions. ### Indy modules and transition -Having all instrumentation rely on native "indy" instrumentation is a tedious task and can't be -achieved in a "big bang" step, we thus have to use intermediate steps. +Making an instrumentation "indy" compatible (or native "indy") is not as straightforward as making it "inlined". +However, bytebuddy provides a set of tools and APIs that are mentioned below to make the process as smooth as possible. -Instrumentation modules that are "indy native" must have their `InstrumentationModule#isIndyModule` -implementation return `true`. Also, all the instrumentation advice methods annotated with -`@Advice.OnMethodEnter` or `@Advice.OnMethodExit` must have the `inlined = false` explicitly set. +Due to the changes needed on most of the instrumentation modules the migration can't be achieved in a single step, +we thus have to use intermediate steps. + +Instrumentation modules that are "indy native" must have: +- `InstrumentationModule#isIndyModule` implementation return `true` +- advice methods annotated with `@Advice.OnMethodEnter` or `@Advice.OnMethodExit` with `inlined = false` explicitly set. The `otel.javaagent.experimental.indy` (default `false`) configuration option allows to opt-in for using "indy". When set to `true`, the `io.opentelemetry.javaagent.tooling.instrumentation.indy.AdviceTransformer` -will transform advices automatically to make them "indy native". +will transform advices automatically to make them "indy native". Using this option is temporary and will +be removed once all the instrumentations are "indy native". -This configuration is automatically enabled in CI when `test indy` label is added to a pull-request -or when the `-PtestIndy=true` parameter is added to gradle. +This configuration is automatically enabled in CI with `testIndy*` checks or when the `-PtestIndy=true` parameter is added to gradle. In order to preserve compatibility with both instrumentation strategies, we have to omit the `inlined = false` from the advice method annotations. @@ -466,12 +469,12 @@ allows to modify instrumented method return value on exit advice. When using non-inlined advices, reading the original return value is still done with `@Advice.Return` annotated parameter, however modifying the value is done through the advice method return value -and `@Advice.AssignReturned.ToReturned` +and `@Advice.AssignReturned.ToReturned`. ```java @Advice.OnMethodExit(suppress = Throwable.class) @Advice.AssignReturned.ToReturned -public static Object onEnter(@Advice.Return Object returnValue) { +public static Object onExit(@Advice.Return Object returnValue) { return "hello"; } ``` From cfefa13c1f568bf4a972e1db12c16ec0eaca20a3 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 26 Jun 2024 15:43:07 +0200 Subject: [PATCH 25/44] clarify with 3 buckets --- docs/contributing/writing-instrumentation-module.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 97d8a2cf08bd..10566f06fe7b 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -401,9 +401,10 @@ This configuration is automatically enabled in CI with `testIndy*` checks or whe In order to preserve compatibility with both instrumentation strategies, we have to omit the `inlined = false` from the advice method annotations. -We have two sets of instrumentation modules: -- "indy compatible": compatible with both "indy" and "inlined", do not override `isIndyModule` +We have three sets of instrumentation modules: - "inlined only": only compatible with "inlined", `isIndyModule` returns `false`. +- "indy compatible": compatible with both "indy" and "inlined", do not override `isIndyModule`, advices are modified with `AdviceTransformer` to be made "indy native" or "inlined" at runtime. +- "indy native": only compatible with "indy" `isIndyModule` returns `true`. The first step of the migration is to move all the "inlined only" to the "indy compatible" category by refactoring them with the limitations described below. From 530609c19462f1a24eecf3a34e6851e9a72dd4bb Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 26 Jun 2024 15:48:00 +0200 Subject: [PATCH 26/44] document for indy native + comment for indy compat --- .../writing-instrumentation-module.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 10566f06fe7b..2367f8f09c64 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -431,12 +431,14 @@ return a value from the enter advice and get the value in the exit advice with a with `@Advice.Enter`, for example: ```java -@Advice.OnMethodEnter(suppress = Throwable.class) +// for "indy compatible", "inlined = false" needs to be omitted +@Advice.OnMethodEnter(suppress = Throwable.class, inlined = false) public static Object onEnter(@Advice.Argument(1) Object request) { return "enterValue"; } -@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) +// for "indy compatible", "inlined = false" needs to be omitted +@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class, inlined = false) public static void onExit(@Advice.Argument(1) Object request, @Advice.Enter Object enterValue) { // do something with enterValue @@ -453,7 +455,8 @@ annotated parameters, however modifying the values is done through the advice me and `@Advice.AssignReturned.ToArguments` annotation: ```java -@Advice.OnMethodEnter(suppress = Throwable.class) +// for "indy compatible", "inlined = false" needs to be omitted +@Advice.OnMethodEnter(suppress = Throwable.class, inlined = false) @Advice.AssignReturned.ToArguments(@ToArgument(1)) public static Object onEnter(@Advice.Argument(1) Object request) { return "hello"; @@ -473,7 +476,8 @@ annotated parameter, however modifying the value is done through the advice meth and `@Advice.AssignReturned.ToReturned`. ```java -@Advice.OnMethodExit(suppress = Throwable.class) +// for "indy compatible", "inlined = false" needs to be omitted +@Advice.OnMethodExit(suppress = Throwable.class, inlined = false) @Advice.AssignReturned.ToReturned public static Object onExit(@Advice.Return Object returnValue) { return "hello"; @@ -490,7 +494,8 @@ annotated parameter, however modifying the value is done through the advice meth and `@Advice.AssignReturned.ToFields` annotation: ```java -@Advice.OnMethodExit(suppress = Throwable.class) +// for "indy compatible", "inlined = false" needs to be omitted +@Advice.OnMethodExit(suppress = Throwable.class, inlined = false) @Advice.AssignReturned.ToFields(@ToField(value = "fieldName")) public static Object onEnter(@Advice.FieldValue("fieldName") Object originalFieldValue) { return "newFieldValue"; From ce07791cc87da52fe31fc45438b8fb439182016b Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:12:37 +0200 Subject: [PATCH 27/44] add clarification on typing --- .../writing-instrumentation-module.md | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 2367f8f09c64..1d204e7506be 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -454,10 +454,14 @@ When using non-inlined advices, reading the argument values is still done with ` annotated parameters, however modifying the values is done through the advice method return value and `@Advice.AssignReturned.ToArguments` annotation: +The advice method return value must be `Object` unless it's a type that is provided by the JDK. +Also, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct bytebuddy to properly cast the +value to the appropriate type. + ```java // for "indy compatible", "inlined = false" needs to be omitted @Advice.OnMethodEnter(suppress = Throwable.class, inlined = false) -@Advice.AssignReturned.ToArguments(@ToArgument(1)) +@Advice.AssignReturned.ToArguments(@ToArgument(value = 1, typing = Assigner.Typing.DYNAMIC)) public static Object onEnter(@Advice.Argument(1) Object request) { return "hello"; } @@ -475,10 +479,14 @@ When using non-inlined advices, reading the original return value is still done annotated parameter, however modifying the value is done through the advice method return value and `@Advice.AssignReturned.ToReturned`. +The advice method return value must be `Object` unless it's a type that is provided by the JDK. +Also, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct bytebuddy to properly cast the +value to the appropriate type. + ```java // for "indy compatible", "inlined = false" needs to be omitted @Advice.OnMethodExit(suppress = Throwable.class, inlined = false) -@Advice.AssignReturned.ToReturned +@Advice.AssignReturned.ToReturned(typing = Assigner.Typing.DYNAMIC) public static Object onExit(@Advice.Return Object returnValue) { return "hello"; } @@ -491,12 +499,16 @@ on advice method parameter allows to modify the `fieldName` field of the instrum When using non-inlined advices, reading the original field value is still done with `@Advice.FieldValue` annotated parameter, however modifying the value is done through the advice method return value -and `@Advice.AssignReturned.ToFields` annotation: +and `@Advice.AssignReturned.ToFields` annotation. + +The advice method return value must be `Object` unless it's a type that is provided by the JDK. +Also, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct bytebuddy to properly cast the +value to the appropriate type. ```java // for "indy compatible", "inlined = false" needs to be omitted @Advice.OnMethodExit(suppress = Throwable.class, inlined = false) -@Advice.AssignReturned.ToFields(@ToField(value = "fieldName")) +@Advice.AssignReturned.ToFields(@ToField(value = "fieldName", typing = Assigner.Typing.DYNAMIC)) public static Object onEnter(@Advice.FieldValue("fieldName") Object originalFieldValue) { return "newFieldValue"; } From 2d73c74b556d336b2463073fbc92421a6eca4507 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:22:19 +0200 Subject: [PATCH 28/44] loading classes in app CL --- docs/contributing/writing-instrumentation-module.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 1d204e7506be..991b8c740e7d 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -421,6 +421,15 @@ to preserve the semantics of `static` fields and to share classes. In order to load multiple `InstrumentationModule` implementations in the same classloader, you need to override the `ExperimentalInstrumentationModule#getModuleGroup` to return an identical value. +### classes injected in application classloader + +Injecting classes in the application classloader is possible by implementing the +`ExperimentalInstrumentationModule#injectedClassNames` method. All the class names listed by the +returned value will be loaded in the application classloader instead of the agent or instrumentation +module classloader. + +This allows for example to access package-private methods that would not be accessible otherwise. + ### advice local variables With inlined advices, declaring an advice method argument with `@Advice.Local` allows to define From 9c9a1a233084f5bc6568df97a24b6295b0a71116 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:11:43 +0200 Subject: [PATCH 29/44] post-review fix inconsistency --- docs/contributing/writing-instrumentation-module.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 991b8c740e7d..fe9d67be3468 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -516,7 +516,7 @@ value to the appropriate type. ```java // for "indy compatible", "inlined = false" needs to be omitted -@Advice.OnMethodExit(suppress = Throwable.class, inlined = false) +@Advice.OnMethodEnter(suppress = Throwable.class, inlined = false) @Advice.AssignReturned.ToFields(@ToField(value = "fieldName", typing = Assigner.Typing.DYNAMIC)) public static Object onEnter(@Advice.FieldValue("fieldName") Object originalFieldValue) { return "newFieldValue"; From f976a12e96b364268113b414446a7003e3a375a9 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 1 Jul 2024 14:35:27 +0200 Subject: [PATCH 30/44] remove redundant comment on indy inlined --- docs/contributing/writing-instrumentation-module.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index fe9d67be3468..401ef16b3656 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -440,13 +440,11 @@ return a value from the enter advice and get the value in the exit advice with a with `@Advice.Enter`, for example: ```java -// for "indy compatible", "inlined = false" needs to be omitted @Advice.OnMethodEnter(suppress = Throwable.class, inlined = false) public static Object onEnter(@Advice.Argument(1) Object request) { return "enterValue"; } -// for "indy compatible", "inlined = false" needs to be omitted @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class, inlined = false) public static void onExit(@Advice.Argument(1) Object request, @Advice.Enter Object enterValue) { @@ -468,7 +466,6 @@ Also, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct bytebuddy to value to the appropriate type. ```java -// for "indy compatible", "inlined = false" needs to be omitted @Advice.OnMethodEnter(suppress = Throwable.class, inlined = false) @Advice.AssignReturned.ToArguments(@ToArgument(value = 1, typing = Assigner.Typing.DYNAMIC)) public static Object onEnter(@Advice.Argument(1) Object request) { @@ -493,7 +490,6 @@ Also, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct bytebuddy to value to the appropriate type. ```java -// for "indy compatible", "inlined = false" needs to be omitted @Advice.OnMethodExit(suppress = Throwable.class, inlined = false) @Advice.AssignReturned.ToReturned(typing = Assigner.Typing.DYNAMIC) public static Object onExit(@Advice.Return Object returnValue) { @@ -515,7 +511,6 @@ Also, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct bytebuddy to value to the appropriate type. ```java -// for "indy compatible", "inlined = false" needs to be omitted @Advice.OnMethodEnter(suppress = Throwable.class, inlined = false) @Advice.AssignReturned.ToFields(@ToField(value = "fieldName", typing = Assigner.Typing.DYNAMIC)) public static Object onEnter(@Advice.FieldValue("fieldName") Object originalFieldValue) { From bf298974776345aceb2a05f6e64d75421f719a2c Mon Sep 17 00:00:00 2001 From: SylvainJuge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 1 Jul 2024 14:38:06 +0200 Subject: [PATCH 31/44] Update docs/contributing/writing-instrumentation-module.md Co-authored-by: jackshirazi --- docs/contributing/writing-instrumentation-module.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 401ef16b3656..05b0effda6d0 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -379,6 +379,12 @@ application classloader and the agent classloader. The instrumented classes call the advice classes residing in the `InstrumentationModuleClassloader` via invokedynamic bytecode instructions. +Making the instrumentation indy + +- allows instrumentations to have breakpoints set in them and be debugged using standard debugging techniques +- provides clean isolation of instrumentation advice from the application and other instrumentations +- allows advice classes to contain non-static fields and method - in fact generally good development practices are enabled (whereas inlined advices are [restricted in how they can be implemented](#use-advice-classes-to-write-code-that-will-get-injected-to-the-instrumented-library-classes)) + ### Indy modules and transition Making an instrumentation "indy" compatible (or native "indy") is not as straightforward as making it "inlined". From 8287992fd4bb3e523741b24392b475683efdc47b Mon Sep 17 00:00:00 2001 From: SylvainJuge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 1 Jul 2024 14:52:31 +0200 Subject: [PATCH 32/44] Apply suggestions from code review Co-authored-by: jackshirazi --- .../writing-instrumentation-module.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 05b0effda6d0..4fe078f88279 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -364,16 +364,16 @@ For example: ## Use non-inlined advice code with `invokedynamic` Using non-inlined advice code is possible thanks to the `invokedynamic` instruction, this strategy -is referred as "indy" in reference to this, by extension "indy modules" are the instrumentation +is referred as "indy" in reference to this. By extension "indy modules" are the instrumentation modules using this instrumentation strategy. The most common way to instrument code with bytebuddy relies on inlining, this strategy will be -referred as "inlined" strategy in opposition to "indy". +referred as "inlined" strategy as opposed to "indy". For inlined advices, the advice code is directly copied into the instrumented method. In addition, all helper classes are injected into the classloader of the instrumented classes. -For indy, advice classes are not inlined. Instead, they loaded alongside with all helper classes +For indy, advice classes are not inlined. Instead, they are loaded alongside all helper classes into a special `InstrumentationModuleClassloader`, which sees the classes from both the instrumented application classloader and the agent classloader. The instrumented classes call the advice classes residing in the `InstrumentationModuleClassloader` via @@ -383,7 +383,7 @@ Making the instrumentation indy - allows instrumentations to have breakpoints set in them and be debugged using standard debugging techniques - provides clean isolation of instrumentation advice from the application and other instrumentations -- allows advice classes to contain non-static fields and method - in fact generally good development practices are enabled (whereas inlined advices are [restricted in how they can be implemented](#use-advice-classes-to-write-code-that-will-get-injected-to-the-instrumented-library-classes)) +- allows advice classes to contain non-static fields and methods - in fact generally good development practices are enabled (whereas inlined advices are [restricted in how they can be implemented](#use-advice-classes-to-write-code-that-will-get-injected-to-the-instrumented-library-classes)) ### Indy modules and transition @@ -438,7 +438,7 @@ This allows for example to access package-private methods that would not be acce ### advice local variables -With inlined advices, declaring an advice method argument with `@Advice.Local` allows to define +With inlined advices, declaring an advice method argument with `@Advice.Local` allows defining a variable that is local to the advice execution for communication between the enter and exit advices. When advices are not inlined, usage of `@Advice.Local` is not possible. It is however possible to @@ -461,7 +461,7 @@ public static void onExit(@Advice.Argument(1) Object request, ### modifying method arguments With inlined advices, using the `@Advice.Argument` annotation on method parameter with `readOnly = false` -allows to modify instrumented method arguments. +allows modifying instrumented method arguments. When using non-inlined advices, reading the argument values is still done with `@Advice.Argument` annotated parameters, however modifying the values is done through the advice method return value @@ -485,9 +485,9 @@ It is possible to modify multiple arguments at once by using an array, see usage ### modifying method return value With inlined advices, using the `@Advice.Return` annotation on method parameter with `readOnly = false` -allows to modify instrumented method return value on exit advice. +allows modifying instrumented method return value on exit advice. -When using non-inlined advices, reading the original return value is still done with `@Advice.Return` +When using non-inlined advices, reading the original return value is still done with the `@Advice.Return` annotated parameter, however modifying the value is done through the advice method return value and `@Advice.AssignReturned.ToReturned`. From 0a6bbc12ed3b3f6e66527e5e6d926b435dfcc773 Mon Sep 17 00:00:00 2001 From: SylvainJuge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 1 Jul 2024 14:54:51 +0200 Subject: [PATCH 33/44] Apply suggestions from code review Co-authored-by: jackshirazi --- docs/contributing/writing-instrumentation-module.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 4fe078f88279..57333bb35558 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -506,9 +506,9 @@ public static Object onExit(@Advice.Return Object returnValue) { ### writing to internal class fields With inlined advices, using the `@Advice.FieldValue(value = "fieldName", readOnly = false)` annotation -on advice method parameter allows to modify the `fieldName` field of the instrumented class. +on advice method parameters allows modifying the `fieldName` field of the instrumented class. -When using non-inlined advices, reading the original field value is still done with `@Advice.FieldValue` +When using non-inlined advices, reading the original field value is still done with the `@Advice.FieldValue` annotated parameter, however modifying the value is done through the advice method return value and `@Advice.AssignReturned.ToFields` annotation. From 547d422eeab1a37f9f88fe33df1bdb731aede34b Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 9 Jul 2024 11:56:39 +0200 Subject: [PATCH 34/44] docuemnt advice method signature limitations --- .../writing-instrumentation-module.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 401ef16b3656..1e986cc5bb5a 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -430,6 +430,40 @@ module classloader. This allows for example to access package-private methods that would not be accessible otherwise. +### advice method signatures + +With inlined advices, the advice method signature does not have any limitations. It enables to refer +to types in the OpenTelemetry API, SDK or instrumentation helper classes directly because those +are injected in the target classloader or the bootstrap classloader for visibility. + +With indy advices however, the advice method signature can't introduce types that are not already +visible from the instrumented method. +In practice, two sets of types can be used in the advice method signature: +- types from the JDK in the bootstrap classloader like `Object` +- types already visible from the instrumented code + +For example, when trying to instrument a method that has `HttpServletRequest` as argument: +- the `HttpServletRequest` type can be used as it's part of the instrumented code +- the `HttpServletRequestScope` is part of instrumentation and has to be of type `Object` from enter return value and exit argument. + +```java +@Advice.OnMethodEnter(suppress = Throwable.class, inlined = false) +public static Object onEnter(@Advice.Argument(1) HttpServletRequest request) { + // custom type from the instrumentation module, has to be returned as Object + return new HttpServletRequestScope(request); +} + +@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class, inlined = false) +public static void onExit(@Advice.Argument(1) Object request, + @Advice.Enter Object enterScope) { + // enter scope provided as Object so we have to check type and cast + if (!(enterScope instanceof HttpServletRequestScope)) { + return; + } + HttpServletRequestScope requestScope = (HttpServletRequestScope)enterScope; +} +``` + ### advice local variables With inlined advices, declaring an advice method argument with `@Advice.Local` allows to define From e1bdfafccdb14c060038a70b3d915492c8de8e4a Mon Sep 17 00:00:00 2001 From: SylvainJuge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 10 Jul 2024 17:28:48 +0200 Subject: [PATCH 35/44] Apply suggestions from code review Co-authored-by: jackshirazi --- docs/contributing/writing-instrumentation-module.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 49c9b9fe8b14..20fd96387acf 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -438,19 +438,19 @@ This allows for example to access package-private methods that would not be acce ### advice method signatures -With inlined advices, the advice method signature does not have any limitations. It enables to refer +With inlined advices, the advice method signature does not have any limitations. It enables referring to types in the OpenTelemetry API, SDK or instrumentation helper classes directly because those are injected in the target classloader or the bootstrap classloader for visibility. -With indy advices however, the advice method signature can't introduce types that are not already -visible from the instrumented method. +With indy advices however, the advice method signature can't introduce types that are only +visible in the advice classes. In practice, two sets of types can be used in the advice method signature: - types from the JDK in the bootstrap classloader like `Object` - types already visible from the instrumented code For example, when trying to instrument a method that has `HttpServletRequest` as argument: - the `HttpServletRequest` type can be used as it's part of the instrumented code -- the `HttpServletRequestScope` is part of instrumentation and has to be of type `Object` from enter return value and exit argument. +- the `HttpServletRequestScope` is part of instrumentation and has to be of type `Object` for both the enter return value and the exit argument. ```java @Advice.OnMethodEnter(suppress = Throwable.class, inlined = false) From ac90f56935fb78ef005606756739e7e871d2aa7e Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 18 Jul 2024 15:30:07 +0200 Subject: [PATCH 36/44] bytebuddy -> ByteBuddy --- docs/agent-features.md | 2 +- docs/contributing/writing-instrumentation-module.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/agent-features.md b/docs/agent-features.md index 9548c58d8047..22ad81e25be9 100644 --- a/docs/agent-features.md +++ b/docs/agent-features.md @@ -30,7 +30,7 @@ provides. - Can set different defaults for properties - Can customize tracer configuration programmatically - Can provide custom exporter, propagator, sampler - - Can hook into bytebuddy to customize bytecode manipulation + - Can hook into ByteBuddy to customize bytecode manipulation - Noteworthy instrumentation - Log injection of IDs (logback, log4j2, log4j) - Automatic context propagation across `Executor`s diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 20fd96387acf..8826d13f4b5a 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -367,7 +367,7 @@ Using non-inlined advice code is possible thanks to the `invokedynamic` instruct is referred as "indy" in reference to this. By extension "indy modules" are the instrumentation modules using this instrumentation strategy. -The most common way to instrument code with bytebuddy relies on inlining, this strategy will be +The most common way to instrument code with ByteBuddy relies on inlining, this strategy will be referred as "inlined" strategy as opposed to "indy". For inlined advices, the advice code is directly copied into the instrumented method. @@ -388,7 +388,7 @@ Making the instrumentation indy ### Indy modules and transition Making an instrumentation "indy" compatible (or native "indy") is not as straightforward as making it "inlined". -However, bytebuddy provides a set of tools and APIs that are mentioned below to make the process as smooth as possible. +However, ByteBuddy provides a set of tools and APIs that are mentioned below to make the process as smooth as possible. Due to the changes needed on most of the instrumentation modules the migration can't be achieved in a single step, we thus have to use intermediate steps. @@ -502,7 +502,7 @@ annotated parameters, however modifying the values is done through the advice me and `@Advice.AssignReturned.ToArguments` annotation: The advice method return value must be `Object` unless it's a type that is provided by the JDK. -Also, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct bytebuddy to properly cast the +Also, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct ByteBuddy to properly cast the value to the appropriate type. ```java @@ -526,7 +526,7 @@ annotated parameter, however modifying the value is done through the advice meth and `@Advice.AssignReturned.ToReturned`. The advice method return value must be `Object` unless it's a type that is provided by the JDK. -Also, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct bytebuddy to properly cast the +Also, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct ByteBuddy to properly cast the value to the appropriate type. ```java @@ -547,7 +547,7 @@ annotated parameter, however modifying the value is done through the advice meth and `@Advice.AssignReturned.ToFields` annotation. The advice method return value must be `Object` unless it's a type that is provided by the JDK. -Also, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct bytebuddy to properly cast the +Also, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct ByteBuddy to properly cast the value to the appropriate type. ```java From f2548878235824fb341a42cad545cf8e15b2caed Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 12 Aug 2024 13:41:25 +0200 Subject: [PATCH 37/44] remove advice method signature limitation --- .../writing-instrumentation-module.md | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 8826d13f4b5a..736d795bcac6 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -436,40 +436,6 @@ module classloader. This allows for example to access package-private methods that would not be accessible otherwise. -### advice method signatures - -With inlined advices, the advice method signature does not have any limitations. It enables referring -to types in the OpenTelemetry API, SDK or instrumentation helper classes directly because those -are injected in the target classloader or the bootstrap classloader for visibility. - -With indy advices however, the advice method signature can't introduce types that are only -visible in the advice classes. -In practice, two sets of types can be used in the advice method signature: -- types from the JDK in the bootstrap classloader like `Object` -- types already visible from the instrumented code - -For example, when trying to instrument a method that has `HttpServletRequest` as argument: -- the `HttpServletRequest` type can be used as it's part of the instrumented code -- the `HttpServletRequestScope` is part of instrumentation and has to be of type `Object` for both the enter return value and the exit argument. - -```java -@Advice.OnMethodEnter(suppress = Throwable.class, inlined = false) -public static Object onEnter(@Advice.Argument(1) HttpServletRequest request) { - // custom type from the instrumentation module, has to be returned as Object - return new HttpServletRequestScope(request); -} - -@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class, inlined = false) -public static void onExit(@Advice.Argument(1) Object request, - @Advice.Enter Object enterScope) { - // enter scope provided as Object so we have to check type and cast - if (!(enterScope instanceof HttpServletRequestScope)) { - return; - } - HttpServletRequestScope requestScope = (HttpServletRequestScope)enterScope; -} -``` - ### advice local variables With inlined advices, declaring an advice method argument with `@Advice.Local` allows defining From fe702b7ca76fbe3c85d3fe63c8f06070b2e2c04f Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 12 Aug 2024 13:46:23 +0200 Subject: [PATCH 38/44] remove limitation on advice return type --- docs/contributing/writing-instrumentation-module.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 736d795bcac6..f44030eccbb4 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -467,8 +467,7 @@ When using non-inlined advices, reading the argument values is still done with ` annotated parameters, however modifying the values is done through the advice method return value and `@Advice.AssignReturned.ToArguments` annotation: -The advice method return value must be `Object` unless it's a type that is provided by the JDK. -Also, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct ByteBuddy to properly cast the +For return type, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct ByteBuddy to properly cast the value to the appropriate type. ```java @@ -491,8 +490,7 @@ When using non-inlined advices, reading the original return value is still done annotated parameter, however modifying the value is done through the advice method return value and `@Advice.AssignReturned.ToReturned`. -The advice method return value must be `Object` unless it's a type that is provided by the JDK. -Also, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct ByteBuddy to properly cast the +For return type, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct ByteBuddy to properly cast the value to the appropriate type. ```java @@ -512,8 +510,7 @@ When using non-inlined advices, reading the original field value is still done w annotated parameter, however modifying the value is done through the advice method return value and `@Advice.AssignReturned.ToFields` annotation. -The advice method return value must be `Object` unless it's a type that is provided by the JDK. -Also, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct ByteBuddy to properly cast the +For return type, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct ByteBuddy to properly cast the value to the appropriate type. ```java From 5625aa14ffb86f4dbcd9cb190aa87f71054d6feb Mon Sep 17 00:00:00 2001 From: SylvainJuge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 14 Aug 2024 11:19:56 +0200 Subject: [PATCH 39/44] Apply suggestions from code review Co-authored-by: Trask Stalnaker --- docs/contributing/writing-instrumentation-module.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index f44030eccbb4..5fd1e45bbdb4 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -379,7 +379,7 @@ application classloader and the agent classloader. The instrumented classes call the advice classes residing in the `InstrumentationModuleClassloader` via invokedynamic bytecode instructions. -Making the instrumentation indy +Using indy instrumentation has these advantages: - allows instrumentations to have breakpoints set in them and be debugged using standard debugging techniques - provides clean isolation of instrumentation advice from the application and other instrumentations @@ -391,11 +391,10 @@ Making an instrumentation "indy" compatible (or native "indy") is not as straigh However, ByteBuddy provides a set of tools and APIs that are mentioned below to make the process as smooth as possible. Due to the changes needed on most of the instrumentation modules the migration can't be achieved in a single step, -we thus have to use intermediate steps. +we thus have to implement it in two steps: -Instrumentation modules that are "indy native" must have: -- `InstrumentationModule#isIndyModule` implementation return `true` -- advice methods annotated with `@Advice.OnMethodEnter` or `@Advice.OnMethodExit` with `inlined = false` explicitly set. +- `InstrumentationModule#isIndyModule` implementation return `true` (and changes needed to make it indy compatible) +- set `inlined = false` on advice methods annotated with `@Advice.OnMethodEnter` or `@Advice.OnMethodExit` The `otel.javaagent.experimental.indy` (default `false`) configuration option allows to opt-in for using "indy". When set to `true`, the `io.opentelemetry.javaagent.tooling.instrumentation.indy.AdviceTransformer` From a1d30a988c0d793327618b1992ea3786eb6a5137 Mon Sep 17 00:00:00 2001 From: SylvainJuge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:29:58 +0200 Subject: [PATCH 40/44] Apply suggestions from code review Co-authored-by: Jonas Kunz --- docs/contributing/writing-instrumentation-module.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 5fd1e45bbdb4..fbca60fdbaf6 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -383,7 +383,7 @@ Using indy instrumentation has these advantages: - allows instrumentations to have breakpoints set in them and be debugged using standard debugging techniques - provides clean isolation of instrumentation advice from the application and other instrumentations -- allows advice classes to contain non-static fields and methods - in fact generally good development practices are enabled (whereas inlined advices are [restricted in how they can be implemented](#use-advice-classes-to-write-code-that-will-get-injected-to-the-instrumented-library-classes)) +- allows advice classes to contain static fields and methods which can be accessed from the advice entry points - in fact generally good development practices are enabled (whereas inlined advices are [restricted in how they can be implemented](#use-advice-classes-to-write-code-that-will-get-injected-to-the-instrumented-library-classes)) ### Indy modules and transition @@ -466,12 +466,12 @@ When using non-inlined advices, reading the argument values is still done with ` annotated parameters, however modifying the values is done through the advice method return value and `@Advice.AssignReturned.ToArguments` annotation: -For return type, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct ByteBuddy to properly cast the +Note that independent of the static return type of the advice method, all assignments done `@Advice.AssignReturned` will use explicit casts to the type of target field or variable. We explicitly override the `typing` parameter in those annotations in our agent. value to the appropriate type. ```java @Advice.OnMethodEnter(suppress = Throwable.class, inlined = false) -@Advice.AssignReturned.ToArguments(@ToArgument(value = 1, typing = Assigner.Typing.DYNAMIC)) +@Advice.AssignReturned.ToArguments(@ToArgument(1)) public static Object onEnter(@Advice.Argument(1) Object request) { return "hello"; } @@ -494,7 +494,7 @@ value to the appropriate type. ```java @Advice.OnMethodExit(suppress = Throwable.class, inlined = false) -@Advice.AssignReturned.ToReturned(typing = Assigner.Typing.DYNAMIC) +@Advice.AssignReturned.ToReturned public static Object onExit(@Advice.Return Object returnValue) { return "hello"; } @@ -514,7 +514,7 @@ value to the appropriate type. ```java @Advice.OnMethodEnter(suppress = Throwable.class, inlined = false) -@Advice.AssignReturned.ToFields(@ToField(value = "fieldName", typing = Assigner.Typing.DYNAMIC)) +@Advice.AssignReturned.ToFields(@ToField("fieldName")) public static Object onEnter(@Advice.FieldValue("fieldName") Object originalFieldValue) { return "newFieldValue"; } From 89624af6cf633e71e00077e3f1ad8737f27d095c Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:31:18 +0200 Subject: [PATCH 41/44] remove dynamic assignment requirement --- docs/contributing/writing-instrumentation-module.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index fbca60fdbaf6..3bf1d230ba81 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -489,9 +489,6 @@ When using non-inlined advices, reading the original return value is still done annotated parameter, however modifying the value is done through the advice method return value and `@Advice.AssignReturned.ToReturned`. -For return type, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct ByteBuddy to properly cast the -value to the appropriate type. - ```java @Advice.OnMethodExit(suppress = Throwable.class, inlined = false) @Advice.AssignReturned.ToReturned @@ -509,9 +506,6 @@ When using non-inlined advices, reading the original field value is still done w annotated parameter, however modifying the value is done through the advice method return value and `@Advice.AssignReturned.ToFields` annotation. -For return type, the `typing = Assigner.Typing.DYNAMIC` is needed to instruct ByteBuddy to properly cast the -value to the appropriate type. - ```java @Advice.OnMethodEnter(suppress = Throwable.class, inlined = false) @Advice.AssignReturned.ToFields(@ToField("fieldName")) From db007a48975bae7c2c3099e1e11a0673f0c59df3 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 19 Aug 2024 13:43:55 +0200 Subject: [PATCH 42/44] capitalize for consistency --- docs/contributing/writing-instrumentation-module.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index 3bf1d230ba81..af3852e8d981 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -435,7 +435,7 @@ module classloader. This allows for example to access package-private methods that would not be accessible otherwise. -### advice local variables +### Advice local variables With inlined advices, declaring an advice method argument with `@Advice.Local` allows defining a variable that is local to the advice execution for communication between the enter and exit advices. From da744fa4b05140e988d26c5aac131bf533814aaf Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 20 Aug 2024 09:16:07 +0200 Subject: [PATCH 43/44] capitalize headers --- docs/contributing/writing-instrumentation-module.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index af3852e8d981..a7c98f52d474 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -417,7 +417,7 @@ by refactoring them with the limitations described below. Once everything is "indy compatible", we can evaluate changing the default value of `otel.javaagent.experimental.indy` to `true` and make it non-experimental. -### shared classes and common classloader +### Shared classes and common classloader By default, all the advices of an instrumentation module will be loaded into isolated classloaders, one per instrumentation module. Some instrumentations require to use a common classloader in order @@ -426,7 +426,7 @@ to preserve the semantics of `static` fields and to share classes. In order to load multiple `InstrumentationModule` implementations in the same classloader, you need to override the `ExperimentalInstrumentationModule#getModuleGroup` to return an identical value. -### classes injected in application classloader +### Classes injected in application classloader Injecting classes in the application classloader is possible by implementing the `ExperimentalInstrumentationModule#injectedClassNames` method. All the class names listed by the @@ -457,7 +457,7 @@ public static void onExit(@Advice.Argument(1) Object request, } ``` -### modifying method arguments +### Modifying method arguments With inlined advices, using the `@Advice.Argument` annotation on method parameter with `readOnly = false` allows modifying instrumented method arguments. @@ -480,7 +480,7 @@ public static Object onEnter(@Advice.Argument(1) Object request) { It is possible to modify multiple arguments at once by using an array, see usages of `@Advice.AssignReturned.ToArguments` for detailed examples. -### modifying method return value +### Modifying method return value With inlined advices, using the `@Advice.Return` annotation on method parameter with `readOnly = false` allows modifying instrumented method return value on exit advice. @@ -497,7 +497,7 @@ public static Object onExit(@Advice.Return Object returnValue) { } ``` -### writing to internal class fields +### Writing to internal class fields With inlined advices, using the `@Advice.FieldValue(value = "fieldName", readOnly = false)` annotation on advice method parameters allows modifying the `fieldName` field of the instrumented class. From 3405ae1306122de75e9101ec466ed9f4fa94c72b Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 22 Aug 2024 19:14:33 +0200 Subject: [PATCH 44/44] remove paragraph --- docs/contributing/writing-instrumentation-module.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/contributing/writing-instrumentation-module.md b/docs/contributing/writing-instrumentation-module.md index a7c98f52d474..550fd6d69de6 100644 --- a/docs/contributing/writing-instrumentation-module.md +++ b/docs/contributing/writing-instrumentation-module.md @@ -466,9 +466,6 @@ When using non-inlined advices, reading the argument values is still done with ` annotated parameters, however modifying the values is done through the advice method return value and `@Advice.AssignReturned.ToArguments` annotation: -Note that independent of the static return type of the advice method, all assignments done `@Advice.AssignReturned` will use explicit casts to the type of target field or variable. We explicitly override the `typing` parameter in those annotations in our agent. -value to the appropriate type. - ```java @Advice.OnMethodEnter(suppress = Throwable.class, inlined = false) @Advice.AssignReturned.ToArguments(@ToArgument(1))