From 0814d2344cd5ff5fc4d7352aa37ff4f958caf73a Mon Sep 17 00:00:00 2001 From: chengpu Date: Thu, 18 Jan 2024 01:05:50 +0800 Subject: [PATCH 01/12] Add support for MyBatis framework --- docs/supported-libraries.md | 1 + .../mybatis/javaagent/build.gradle.kts | 26 +++++++ .../mybatis/MapperMethodRequest.java | 13 ++++ .../mybatis/MybatisAttributesExtractor.java | 21 ++++++ .../MybatisExecuteInstrumentation.java | 60 ++++++++++++++++ .../mybatis/MybatisInstrumentationModule.java | 20 ++++++ .../mybatis/MybatisSingletons.java | 34 +++++++++ .../mybatis/MybatisSpanNameExtractor.java | 11 +++ .../instrumentation/mybatis/MybatisTest.java | 70 +++++++++++++++++++ .../instrumentation/mybatis/RecordMapper.java | 8 +++ settings.gradle.kts | 1 + 11 files changed, 265 insertions(+) create mode 100644 instrumentation/mybatis/javaagent/build.gradle.kts create mode 100644 instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MapperMethodRequest.java create mode 100644 instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisAttributesExtractor.java create mode 100644 instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisExecuteInstrumentation.java create mode 100644 instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisInstrumentationModule.java create mode 100644 instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSingletons.java create mode 100644 instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSpanNameExtractor.java create mode 100644 instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisTest.java create mode 100644 instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/RecordMapper.java diff --git a/docs/supported-libraries.md b/docs/supported-libraries.md index 7ff7d2a70f22..5609b363e73e 100644 --- a/docs/supported-libraries.md +++ b/docs/supported-libraries.md @@ -144,6 +144,7 @@ These are the supported libraries and frameworks: | [Vert.x Web](https://vertx.io/docs/vertx-web/java/) | 3.0+ | N/A | Provides `http.route` [2] | | [Vibur DBCP](https://www.vibur.org/) | 11.0+ | [opentelemetry-vibur-dbcp-11.0](../instrumentation/vibur-dbcp-11.0/library) | [Database Pool Metrics] | | [ZIO](https://zio.dev/) | 2.0+ | N/A | Context propagation | +| [MyBatis](https://mybatis.org/mybatis-3/) | 3.0.1+ | N/A | none | **[1]** Standalone library instrumentation refers to instrumentation that can be used without the Java agent. diff --git a/instrumentation/mybatis/javaagent/build.gradle.kts b/instrumentation/mybatis/javaagent/build.gradle.kts new file mode 100644 index 000000000000..a2d525641801 --- /dev/null +++ b/instrumentation/mybatis/javaagent/build.gradle.kts @@ -0,0 +1,26 @@ +plugins { + id("otel.javaagent-instrumentation") +} + +dependencies { + compileOnly("com.google.auto.value:auto-value-annotations") + annotationProcessor("com.google.auto.value:auto-value") + library("org.mybatis:mybatis:3.2.0") + testImplementation("org.mockito:mockito-core") + testImplementation("org.mockito:mockito-junit-jupiter") + testImplementation("com.h2database:h2:1.4.191") +} + +muzzle { + pass { + group.set("org.mybatis") + module.set("mybatis") + versions.set("[3.0.1,)") + } +} + +tasks.withType().configureEach { + // required on jdk17 + jvmArgs("--add-opens=java.base/java.lang=ALL-UNNAMED") + jvmArgs("-XX:+IgnoreUnrecognizedVMOptions") +} \ No newline at end of file diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MapperMethodRequest.java b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MapperMethodRequest.java new file mode 100644 index 000000000000..124088b511e3 --- /dev/null +++ b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MapperMethodRequest.java @@ -0,0 +1,13 @@ +package io.opentelemetry.javaagent.instrumentation.mybatis; + +import com.google.auto.value.AutoValue; + +@AutoValue +public abstract class MapperMethodRequest { + + public static MapperMethodRequest create(String mapperName) { + return new AutoValue_MapperMethodRequest(mapperName); + } + + public abstract String getMapperName(); +} diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisAttributesExtractor.java b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisAttributesExtractor.java new file mode 100644 index 000000000000..9e9916235676 --- /dev/null +++ b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisAttributesExtractor.java @@ -0,0 +1,21 @@ +package io.opentelemetry.javaagent.instrumentation.mybatis; + +import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; +import javax.annotation.Nullable; + + +class MybatisAttributesExtractor implements AttributesExtractor { + + @Override + public void onStart(AttributesBuilder attributes, Context parentContext, + MapperMethodRequest mapperMethodRequest) { + attributes.put("component.name", "mybatis"); + } + + @Override + public void onEnd(AttributesBuilder attributes, Context context, + MapperMethodRequest mapperMethodRequest, @Nullable Void unused, @Nullable Throwable error) { + } +} diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisExecuteInstrumentation.java b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisExecuteInstrumentation.java new file mode 100644 index 000000000000..6fe5f7b958e4 --- /dev/null +++ b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisExecuteInstrumentation.java @@ -0,0 +1,60 @@ +package io.opentelemetry.javaagent.instrumentation.mybatis; + + +import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext; +import static io.opentelemetry.javaagent.instrumentation.mybatis.MybatisSingletons.mapperInstrumenter; +import static net.bytebuddy.matcher.ElementMatchers.named; + +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.ibatis.binding.MapperMethod.SqlCommand; + +public class MybatisExecuteInstrumentation implements TypeInstrumentation { + + @Override + public ElementMatcher typeMatcher() { + return named("org.apache.ibatis.binding.MapperMethod"); + } + + @Override + public void transform(TypeTransformer transformer) { + transformer.applyAdviceToMethod( + named("execute"),MybatisExecuteInstrumentation.class.getName() + "$ExecuteAdvice"); + } + + @SuppressWarnings("unused") + public static class ExecuteAdvice { + + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void getMapperInfo( + @Advice.FieldValue("command") SqlCommand command, + @Advice.Local("otelRequest") MapperMethodRequest request, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + Context parentContext = currentContext(); + if (command == null || !mapperInstrumenter().shouldStart(parentContext, request)) { + return; + } + request = MapperMethodRequest.create(command.getName()); + context = mapperInstrumenter().start(parentContext, request); + scope = context.makeCurrent(); + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = true) + public static void stopSpan( + @Advice.Thrown Throwable throwable, + @Advice.Local("otelRequest") MapperMethodRequest request, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + if (scope != null) { + scope.close(); + mapperInstrumenter().end(context, request, null, throwable); + } + } + } +} diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisInstrumentationModule.java b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisInstrumentationModule.java new file mode 100644 index 000000000000..01f0c596ecb8 --- /dev/null +++ b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisInstrumentationModule.java @@ -0,0 +1,20 @@ +package io.opentelemetry.javaagent.instrumentation.mybatis; + +import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import java.util.Arrays; +import java.util.List; + +@AutoService(InstrumentationModule.class) +public class MybatisInstrumentationModule extends InstrumentationModule { + + public MybatisInstrumentationModule() { + super("mybatis"); + } + + @Override + public List typeInstrumentations() { + return Arrays.asList(new MybatisExecuteInstrumentation()); + } +} diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSingletons.java b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSingletons.java new file mode 100644 index 000000000000..8707835f4f8a --- /dev/null +++ b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSingletons.java @@ -0,0 +1,34 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.mybatis; + +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; +import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor; + +public final class MybatisSingletons { + private static final String INSTRUMENTATION_NAME = "io.opentelemetry.mybatis"; + + private static final Instrumenter MAPPER_INSTRUMENTER; + + static { + SpanNameExtractor spanNameExtractor = new MybatisSpanNameExtractor(); + + MAPPER_INSTRUMENTER = + Instrumenter.builder( + GlobalOpenTelemetry.get(), + INSTRUMENTATION_NAME, + spanNameExtractor) + .addAttributesExtractor(new MybatisAttributesExtractor()) + .buildInstrumenter(SpanKindExtractor.alwaysInternal()); + } + + public static Instrumenter mapperInstrumenter() { + return MAPPER_INSTRUMENTER; + } + private MybatisSingletons() {} +} diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSpanNameExtractor.java b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSpanNameExtractor.java new file mode 100644 index 000000000000..0485887dbd86 --- /dev/null +++ b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSpanNameExtractor.java @@ -0,0 +1,11 @@ +package io.opentelemetry.javaagent.instrumentation.mybatis; + +import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor; + +public class MybatisSpanNameExtractor implements SpanNameExtractor { + + @Override + public String extract(MapperMethodRequest request) { + return request.getMapperName(); + } +} diff --git a/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisTest.java b/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisTest.java new file mode 100644 index 000000000000..c362f2462edd --- /dev/null +++ b/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisTest.java @@ -0,0 +1,70 @@ +package io.opentelemetry.javaagent.instrumentation.mybatis; + +import static org.mockito.Mockito.when; + +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; +import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import org.apache.ibatis.binding.MapperMethod; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.SqlCommandType; +import org.apache.ibatis.reflection.factory.DefaultObjectFactory; +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.session.defaults.DefaultSqlSession; +import org.junit.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mockito.Mockito; + +public class MybatisTest { + + @RegisterExtension + protected static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + + private static final String SPAN_NAME = "io.opentelemetry.javaagent.instrumentation.mybatis.RecordMapper.updateRecord"; + + + + @Test + public void mybatis() throws Exception { + DefaultSqlSession sqlSession = Mockito.mock(DefaultSqlSession.class); + Configuration configuration = Mockito.mock(Configuration.class); + DefaultObjectFactory defaultObjectFactory = Mockito.mock(DefaultObjectFactory.class); + when(sqlSession.update(SPAN_NAME, null)).thenReturn(1); + Class mappedStatementClass = Class.forName(MappedStatement.class.getName()); + Constructor constructor = mappedStatementClass.getDeclaredConstructor(); + constructor.setAccessible(true); + MappedStatement mappedStatement = (MappedStatement) constructor.newInstance(); + Field id = mappedStatementClass.getDeclaredField("id"); + id.setAccessible(true); + id.set(mappedStatement, SPAN_NAME); + Field sqlCommandType = mappedStatementClass.getDeclaredField("sqlCommandType"); + sqlCommandType.setAccessible(true); + sqlCommandType.set(mappedStatement, SqlCommandType.UPDATE); + when(configuration.hasStatement(SPAN_NAME)).thenReturn(true); + when(configuration.getMappedStatement(SPAN_NAME)).thenReturn(mappedStatement); + when(configuration.getObjectFactory()).thenReturn(defaultObjectFactory); + when(defaultObjectFactory.isCollection(Void.class)).thenReturn(false); + Class mapper = Class.forName(RecordMapper.class.getName()); + Method method = mapper.getMethod("updateRecord"); + MapperMethod mapperMethod = new MapperMethod(mapper, method, configuration); + try { + mapperMethod.execute(sqlSession, null); + testSpan(SPAN_NAME); + } catch (RuntimeException e) { + throw new RuntimeException(e); + } + } + + public void testSpan(String spanName) { + testing.waitAndAssertTracesWithoutScopeVersionVerification(trace -> { + trace.hasSize(1) + .hasSpansSatisfyingExactly(span -> { + span.hasKind(SpanKind.INTERNAL) + .hasName(spanName); + }); + }); + } +} diff --git a/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/RecordMapper.java b/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/RecordMapper.java new file mode 100644 index 000000000000..b3197cbcd48c --- /dev/null +++ b/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/RecordMapper.java @@ -0,0 +1,8 @@ +package io.opentelemetry.javaagent.instrumentation.mybatis; + +import org.apache.ibatis.annotations.Update; + +public interface RecordMapper { + @Update("update dummy_record set content = '3131223'") + void updateRecord(); +} diff --git a/settings.gradle.kts b/settings.gradle.kts index ae4b4afe767a..eb47d10eb590 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -567,6 +567,7 @@ include(":instrumentation:vibur-dbcp-11.0:library") include(":instrumentation:vibur-dbcp-11.0:testing") include(":instrumentation:wicket-8.0:javaagent") include(":instrumentation:zio:zio-2.0:javaagent") +include(":instrumentation:mybatis:javaagent") // benchmark include(":benchmark-overhead-jmh") From 72b2e18c3dd62e677046d20b29a14c850f2cdd5f Mon Sep 17 00:00:00 2001 From: chengpu Date: Thu, 18 Jan 2024 01:50:43 +0800 Subject: [PATCH 02/12] Fixed checkstyle problems and polished codes. --- docs/supported-libraries.md | 2 +- .../mybatis/javaagent/build.gradle.kts | 32 +++++++-------- .../mybatis/MapperMethodRequest.java | 5 +++ .../mybatis/MybatisAttributesExtractor.java | 21 +++++++--- .../MybatisExecuteInstrumentation.java | 8 +++- .../mybatis/MybatisInstrumentationModule.java | 5 +++ .../mybatis/MybatisSpanNameExtractor.java | 5 +++ .../instrumentation/mybatis/MybatisTest.java | 40 ++++++++++--------- .../instrumentation/mybatis/RecordMapper.java | 6 +++ 9 files changed, 80 insertions(+), 44 deletions(-) diff --git a/docs/supported-libraries.md b/docs/supported-libraries.md index 5609b363e73e..fbeba5b86d4a 100644 --- a/docs/supported-libraries.md +++ b/docs/supported-libraries.md @@ -144,7 +144,7 @@ These are the supported libraries and frameworks: | [Vert.x Web](https://vertx.io/docs/vertx-web/java/) | 3.0+ | N/A | Provides `http.route` [2] | | [Vibur DBCP](https://www.vibur.org/) | 11.0+ | [opentelemetry-vibur-dbcp-11.0](../instrumentation/vibur-dbcp-11.0/library) | [Database Pool Metrics] | | [ZIO](https://zio.dev/) | 2.0+ | N/A | Context propagation | -| [MyBatis](https://mybatis.org/mybatis-3/) | 3.0.1+ | N/A | none | +| [MyBatis](https://mybatis.org/mybatis-3/) | 3.2.0+ | N/A | none | **[1]** Standalone library instrumentation refers to instrumentation that can be used without the Java agent. diff --git a/instrumentation/mybatis/javaagent/build.gradle.kts b/instrumentation/mybatis/javaagent/build.gradle.kts index a2d525641801..207afc9e77bc 100644 --- a/instrumentation/mybatis/javaagent/build.gradle.kts +++ b/instrumentation/mybatis/javaagent/build.gradle.kts @@ -1,26 +1,26 @@ plugins { - id("otel.javaagent-instrumentation") + id("otel.javaagent-instrumentation") } dependencies { - compileOnly("com.google.auto.value:auto-value-annotations") - annotationProcessor("com.google.auto.value:auto-value") - library("org.mybatis:mybatis:3.2.0") - testImplementation("org.mockito:mockito-core") - testImplementation("org.mockito:mockito-junit-jupiter") - testImplementation("com.h2database:h2:1.4.191") + compileOnly("com.google.auto.value:auto-value-annotations") + annotationProcessor("com.google.auto.value:auto-value") + library("org.mybatis:mybatis:3.2.0") + testImplementation("org.mockito:mockito-core") + testImplementation("org.mockito:mockito-junit-jupiter") + testImplementation("com.h2database:h2:1.4.191") } muzzle { - pass { - group.set("org.mybatis") - module.set("mybatis") - versions.set("[3.0.1,)") - } + pass { + group.set("org.mybatis") + module.set("mybatis") + versions.set("[3.2.0,)") + } } tasks.withType().configureEach { - // required on jdk17 - jvmArgs("--add-opens=java.base/java.lang=ALL-UNNAMED") - jvmArgs("-XX:+IgnoreUnrecognizedVMOptions") -} \ No newline at end of file + // required on jdk17 + jvmArgs("--add-opens=java.base/java.lang=ALL-UNNAMED") + jvmArgs("-XX:+IgnoreUnrecognizedVMOptions") +} diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MapperMethodRequest.java b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MapperMethodRequest.java index 124088b511e3..ec5f4adef433 100644 --- a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MapperMethodRequest.java +++ b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MapperMethodRequest.java @@ -1,3 +1,8 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.javaagent.instrumentation.mybatis; import com.google.auto.value.AutoValue; diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisAttributesExtractor.java b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisAttributesExtractor.java index 9e9916235676..59eca156152c 100644 --- a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisAttributesExtractor.java +++ b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisAttributesExtractor.java @@ -1,3 +1,8 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.javaagent.instrumentation.mybatis; import io.opentelemetry.api.common.AttributesBuilder; @@ -5,17 +10,21 @@ import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; import javax.annotation.Nullable; - -class MybatisAttributesExtractor implements AttributesExtractor { +class MybatisAttributesExtractor implements AttributesExtractor { @Override - public void onStart(AttributesBuilder attributes, Context parentContext, + public void onStart( + AttributesBuilder attributes, + Context parentContext, MapperMethodRequest mapperMethodRequest) { attributes.put("component.name", "mybatis"); } @Override - public void onEnd(AttributesBuilder attributes, Context context, - MapperMethodRequest mapperMethodRequest, @Nullable Void unused, @Nullable Throwable error) { - } + public void onEnd( + AttributesBuilder attributes, + Context context, + MapperMethodRequest mapperMethodRequest, + @Nullable Void unused, + @Nullable Throwable error) {} } diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisExecuteInstrumentation.java b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisExecuteInstrumentation.java index 6fe5f7b958e4..e2061dac0cd0 100644 --- a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisExecuteInstrumentation.java +++ b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisExecuteInstrumentation.java @@ -1,5 +1,9 @@ -package io.opentelemetry.javaagent.instrumentation.mybatis; +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ +package io.opentelemetry.javaagent.instrumentation.mybatis; import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext; import static io.opentelemetry.javaagent.instrumentation.mybatis.MybatisSingletons.mapperInstrumenter; @@ -24,7 +28,7 @@ public ElementMatcher typeMatcher() { @Override public void transform(TypeTransformer transformer) { transformer.applyAdviceToMethod( - named("execute"),MybatisExecuteInstrumentation.class.getName() + "$ExecuteAdvice"); + named("execute"), MybatisExecuteInstrumentation.class.getName() + "$ExecuteAdvice"); } @SuppressWarnings("unused") diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisInstrumentationModule.java b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisInstrumentationModule.java index 01f0c596ecb8..e6793d459b73 100644 --- a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisInstrumentationModule.java +++ b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisInstrumentationModule.java @@ -1,3 +1,8 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.javaagent.instrumentation.mybatis; import com.google.auto.service.AutoService; diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSpanNameExtractor.java b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSpanNameExtractor.java index 0485887dbd86..b83134d3c256 100644 --- a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSpanNameExtractor.java +++ b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSpanNameExtractor.java @@ -1,3 +1,8 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.javaagent.instrumentation.mybatis; import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor; diff --git a/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisTest.java b/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisTest.java index c362f2462edd..bf036fedc6ff 100644 --- a/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisTest.java +++ b/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisTest.java @@ -1,3 +1,8 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.javaagent.instrumentation.mybatis; import static org.mockito.Mockito.when; @@ -18,17 +23,16 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.Mockito; -public class MybatisTest { +class MybatisTest { @RegisterExtension protected static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); - private static final String SPAN_NAME = "io.opentelemetry.javaagent.instrumentation.mybatis.RecordMapper.updateRecord"; + private static final String SPAN_NAME = + "io.opentelemetry.javaagent.instrumentation.mybatis.RecordMapper.updateRecord"; - - @Test - public void mybatis() throws Exception { + void mybatis() throws Exception { DefaultSqlSession sqlSession = Mockito.mock(DefaultSqlSession.class); Configuration configuration = Mockito.mock(Configuration.class); DefaultObjectFactory defaultObjectFactory = Mockito.mock(DefaultObjectFactory.class); @@ -50,21 +54,19 @@ public void mybatis() throws Exception { Class mapper = Class.forName(RecordMapper.class.getName()); Method method = mapper.getMethod("updateRecord"); MapperMethod mapperMethod = new MapperMethod(mapper, method, configuration); - try { - mapperMethod.execute(sqlSession, null); - testSpan(SPAN_NAME); - } catch (RuntimeException e) { - throw new RuntimeException(e); - } + mapperMethod.execute(sqlSession, null); + span(SPAN_NAME); } - public void testSpan(String spanName) { - testing.waitAndAssertTracesWithoutScopeVersionVerification(trace -> { - trace.hasSize(1) - .hasSpansSatisfyingExactly(span -> { - span.hasKind(SpanKind.INTERNAL) - .hasName(spanName); - }); - }); + private void span(String spanName) { + testing.waitAndAssertTracesWithoutScopeVersionVerification( + trace -> { + trace + .hasSize(1) + .hasSpansSatisfyingExactly( + span -> { + span.hasKind(SpanKind.INTERNAL).hasName(spanName); + }); + }); } } diff --git a/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/RecordMapper.java b/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/RecordMapper.java index b3197cbcd48c..8e897a6e2b12 100644 --- a/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/RecordMapper.java +++ b/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/RecordMapper.java @@ -1,8 +1,14 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + package io.opentelemetry.javaagent.instrumentation.mybatis; import org.apache.ibatis.annotations.Update; public interface RecordMapper { + @Update("update dummy_record set content = '3131223'") void updateRecord(); } From 25a56f550ab46fec3f3f1639372228f6ef2f4d90 Mon Sep 17 00:00:00 2001 From: chengpu Date: Thu, 18 Jan 2024 12:04:43 +0800 Subject: [PATCH 03/12] Fixed checkstyle and build problems. --- .../javaagent/instrumentation/mybatis/MybatisSingletons.java | 5 ++--- .../javaagent/instrumentation/mybatis/MybatisTest.java | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSingletons.java b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSingletons.java index 8707835f4f8a..f5c1be121d68 100644 --- a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSingletons.java +++ b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSingletons.java @@ -20,9 +20,7 @@ public final class MybatisSingletons { MAPPER_INSTRUMENTER = Instrumenter.builder( - GlobalOpenTelemetry.get(), - INSTRUMENTATION_NAME, - spanNameExtractor) + GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, spanNameExtractor) .addAttributesExtractor(new MybatisAttributesExtractor()) .buildInstrumenter(SpanKindExtractor.alwaysInternal()); } @@ -30,5 +28,6 @@ public final class MybatisSingletons { public static Instrumenter mapperInstrumenter() { return MAPPER_INSTRUMENTER; } + private MybatisSingletons() {} } diff --git a/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisTest.java b/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisTest.java index bf036fedc6ff..a471bce28f53 100644 --- a/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisTest.java +++ b/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisTest.java @@ -58,7 +58,7 @@ void mybatis() throws Exception { span(SPAN_NAME); } - private void span(String spanName) { + private static void span(String spanName) { testing.waitAndAssertTracesWithoutScopeVersionVerification( trace -> { trace From 6d78abfe04519a98dee8fe8259e7fad090337000 Mon Sep 17 00:00:00 2001 From: chengpu Date: Fri, 19 Jan 2024 22:13:22 +0800 Subject: [PATCH 04/12] Code optimization --- docs/supported-libraries.md | 1 + .../javaagent/build.gradle.kts | 18 +++++------ .../mybatis/v3_2}/MapperMethodRequest.java | 2 +- .../v3_2/MyBatisExecuteInstrumentation.java} | 8 ++--- .../v3_2/MyBatisInstrumentationModule.java} | 12 ++++---- .../mybatis/v3_2/MyBatisSingletons.java} | 14 ++++----- .../mybatis/v3_2/MyBatisTest.java} | 12 ++++---- .../mybatis/v3_2}/RecordMapper.java | 2 +- .../mybatis/MybatisAttributesExtractor.java | 30 ------------------- .../mybatis/MybatisSpanNameExtractor.java | 16 ---------- settings.gradle.kts | 2 +- 11 files changed, 34 insertions(+), 83 deletions(-) rename instrumentation/{mybatis => mybatis-3.2}/javaagent/build.gradle.kts (92%) rename instrumentation/{mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis => mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2}/MapperMethodRequest.java (84%) rename instrumentation/{mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisExecuteInstrumentation.java => mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisExecuteInstrumentation.java} (90%) rename instrumentation/{mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisInstrumentationModule.java => mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisInstrumentationModule.java} (59%) rename instrumentation/{mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSingletons.java => mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSingletons.java} (65%) rename instrumentation/{mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisTest.java => mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java} (88%) rename instrumentation/{mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis => mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2}/RecordMapper.java (79%) delete mode 100644 instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisAttributesExtractor.java delete mode 100644 instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSpanNameExtractor.java diff --git a/docs/supported-libraries.md b/docs/supported-libraries.md index fbeba5b86d4a..c22694fd5eba 100644 --- a/docs/supported-libraries.md +++ b/docs/supported-libraries.md @@ -94,6 +94,7 @@ These are the supported libraries and frameworks: | [Logback](http://logback.qos.ch/) | 1.0+ | [opentelemetry-logback-appender-1.0](../instrumentation/logback/logback-appender-1.0/library),
[opentelemetry-logback-mdc-1.0](../instrumentation/logback/logback-mdc-1.0/library) | none | | [Micrometer](https://micrometer.io/) | 1.5+ | [opentelemetry-micrometer-1.5](../instrumentation/micrometer/micrometer-1.5/library) | none | | [MongoDB Driver](https://mongodb.github.io/mongo-java-driver/) | 3.1+ | [opentelemetry-mongo-3.1](../instrumentation/mongo/mongo-3.1/library) | [Database Client Spans] | +| [MyBatis](https://mybatis.org/mybatis-3/) | 3.2.0+ | N/A | none | | [Netty](https://github.com/netty/netty) | 3.8+ | [opentelemetry-netty-4.1](../instrumentation/netty/netty-4.1/library) | [HTTP Client Spans], [HTTP Client Metrics], [HTTP Server Spans], [HTTP Server Metrics] | | [OkHttp](https://github.com/square/okhttp/) | 2.2+ | [opentelemetry-okhttp-3.0](../instrumentation/okhttp/okhttp-3.0/library) | [HTTP Client Spans], [HTTP Client Metrics] | | [Oracle UCP](https://docs.oracle.com/database/121/JJUCP/) | 11.2+ | [opentelemetry-oracle-ucp-11.2](../instrumentation/oracle-ucp-11.2/library) | [Database Pool Metrics] | diff --git a/instrumentation/mybatis/javaagent/build.gradle.kts b/instrumentation/mybatis-3.2/javaagent/build.gradle.kts similarity index 92% rename from instrumentation/mybatis/javaagent/build.gradle.kts rename to instrumentation/mybatis-3.2/javaagent/build.gradle.kts index 207afc9e77bc..76f6ad11f948 100644 --- a/instrumentation/mybatis/javaagent/build.gradle.kts +++ b/instrumentation/mybatis-3.2/javaagent/build.gradle.kts @@ -2,23 +2,23 @@ plugins { id("otel.javaagent-instrumentation") } -dependencies { - compileOnly("com.google.auto.value:auto-value-annotations") - annotationProcessor("com.google.auto.value:auto-value") - library("org.mybatis:mybatis:3.2.0") - testImplementation("org.mockito:mockito-core") - testImplementation("org.mockito:mockito-junit-jupiter") - testImplementation("com.h2database:h2:1.4.191") -} - muzzle { pass { group.set("org.mybatis") module.set("mybatis") versions.set("[3.2.0,)") + assertInverse.set(true) } } +dependencies { + compileOnly("com.google.auto.value:auto-value-annotations") + annotationProcessor("com.google.auto.value:auto-value") + library("org.mybatis:mybatis:3.2.0") + testImplementation("org.mockito:mockito-core") + testImplementation("org.mockito:mockito-junit-jupiter") +} + tasks.withType().configureEach { // required on jdk17 jvmArgs("--add-opens=java.base/java.lang=ALL-UNNAMED") diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MapperMethodRequest.java b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MapperMethodRequest.java similarity index 84% rename from instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MapperMethodRequest.java rename to instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MapperMethodRequest.java index ec5f4adef433..cd8be5b7d48f 100644 --- a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MapperMethodRequest.java +++ b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MapperMethodRequest.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.mybatis; +package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; import com.google.auto.value.AutoValue; diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisExecuteInstrumentation.java b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisExecuteInstrumentation.java similarity index 90% rename from instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisExecuteInstrumentation.java rename to instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisExecuteInstrumentation.java index e2061dac0cd0..ccc6f6580eb5 100644 --- a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisExecuteInstrumentation.java +++ b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisExecuteInstrumentation.java @@ -3,10 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.mybatis; +package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext; -import static io.opentelemetry.javaagent.instrumentation.mybatis.MybatisSingletons.mapperInstrumenter; +import static io.opentelemetry.javaagent.instrumentation.mybatis.v3_2.MyBatisSingletons.mapperInstrumenter; import static net.bytebuddy.matcher.ElementMatchers.named; import io.opentelemetry.context.Context; @@ -18,7 +18,7 @@ import net.bytebuddy.matcher.ElementMatcher; import org.apache.ibatis.binding.MapperMethod.SqlCommand; -public class MybatisExecuteInstrumentation implements TypeInstrumentation { +public class MyBatisExecuteInstrumentation implements TypeInstrumentation { @Override public ElementMatcher typeMatcher() { @@ -28,7 +28,7 @@ public ElementMatcher typeMatcher() { @Override public void transform(TypeTransformer transformer) { transformer.applyAdviceToMethod( - named("execute"), MybatisExecuteInstrumentation.class.getName() + "$ExecuteAdvice"); + named("execute"), MyBatisExecuteInstrumentation.class.getName() + "$ExecuteAdvice"); } @SuppressWarnings("unused") diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisInstrumentationModule.java b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisInstrumentationModule.java similarity index 59% rename from instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisInstrumentationModule.java rename to instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisInstrumentationModule.java index e6793d459b73..1800bd9fcb18 100644 --- a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisInstrumentationModule.java +++ b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisInstrumentationModule.java @@ -3,23 +3,23 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.mybatis; +package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import java.util.Arrays; +import java.util.Collections; import java.util.List; @AutoService(InstrumentationModule.class) -public class MybatisInstrumentationModule extends InstrumentationModule { +public class MyBatisInstrumentationModule extends InstrumentationModule { - public MybatisInstrumentationModule() { - super("mybatis"); + public MyBatisInstrumentationModule() { + super("mybatis", "mybatis-3.2"); } @Override public List typeInstrumentations() { - return Arrays.asList(new MybatisExecuteInstrumentation()); + return Collections.singletonList(new MyBatisExecuteInstrumentation()); } } diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSingletons.java b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSingletons.java similarity index 65% rename from instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSingletons.java rename to instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSingletons.java index f5c1be121d68..9fb8977347c7 100644 --- a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSingletons.java +++ b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSingletons.java @@ -3,25 +3,21 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.mybatis; +package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; -import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor; -public final class MybatisSingletons { - private static final String INSTRUMENTATION_NAME = "io.opentelemetry.mybatis"; +public final class MyBatisSingletons { + private static final String INSTRUMENTATION_NAME = "io.opentelemetry.mybatis-3.2"; private static final Instrumenter MAPPER_INSTRUMENTER; static { - SpanNameExtractor spanNameExtractor = new MybatisSpanNameExtractor(); - MAPPER_INSTRUMENTER = Instrumenter.builder( - GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, spanNameExtractor) - .addAttributesExtractor(new MybatisAttributesExtractor()) + GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, MapperMethodRequest::getMapperName) .buildInstrumenter(SpanKindExtractor.alwaysInternal()); } @@ -29,5 +25,5 @@ public static Instrumenter mapperInstrumenter() { return MAPPER_INSTRUMENTER; } - private MybatisSingletons() {} + private MyBatisSingletons() {} } diff --git a/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisTest.java b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java similarity index 88% rename from instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisTest.java rename to instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java index a471bce28f53..ce7a6a014289 100644 --- a/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisTest.java +++ b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.mybatis; +package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; import static org.mockito.Mockito.when; @@ -23,21 +23,21 @@ import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.Mockito; -class MybatisTest { +public class MyBatisTest { @RegisterExtension protected static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); private static final String SPAN_NAME = - "io.opentelemetry.javaagent.instrumentation.mybatis.RecordMapper.updateRecord"; + "io.opentelemetry.javaagent.instrumentation.mybatis.v3_2.RecordMapper.updateRecord"; @Test - void mybatis() throws Exception { + public void mybatis() throws Exception { DefaultSqlSession sqlSession = Mockito.mock(DefaultSqlSession.class); Configuration configuration = Mockito.mock(Configuration.class); DefaultObjectFactory defaultObjectFactory = Mockito.mock(DefaultObjectFactory.class); when(sqlSession.update(SPAN_NAME, null)).thenReturn(1); - Class mappedStatementClass = Class.forName(MappedStatement.class.getName()); + Class mappedStatementClass = MappedStatement.class; Constructor constructor = mappedStatementClass.getDeclaredConstructor(); constructor.setAccessible(true); MappedStatement mappedStatement = (MappedStatement) constructor.newInstance(); @@ -51,7 +51,7 @@ void mybatis() throws Exception { when(configuration.getMappedStatement(SPAN_NAME)).thenReturn(mappedStatement); when(configuration.getObjectFactory()).thenReturn(defaultObjectFactory); when(defaultObjectFactory.isCollection(Void.class)).thenReturn(false); - Class mapper = Class.forName(RecordMapper.class.getName()); + Class mapper = RecordMapper.class; Method method = mapper.getMethod("updateRecord"); MapperMethod mapperMethod = new MapperMethod(mapper, method, configuration); mapperMethod.execute(sqlSession, null); diff --git a/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/RecordMapper.java b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/RecordMapper.java similarity index 79% rename from instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/RecordMapper.java rename to instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/RecordMapper.java index 8e897a6e2b12..09f9f1a3d0b3 100644 --- a/instrumentation/mybatis/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/RecordMapper.java +++ b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/RecordMapper.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.instrumentation.mybatis; +package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; import org.apache.ibatis.annotations.Update; diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisAttributesExtractor.java b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisAttributesExtractor.java deleted file mode 100644 index 59eca156152c..000000000000 --- a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisAttributesExtractor.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.mybatis; - -import io.opentelemetry.api.common.AttributesBuilder; -import io.opentelemetry.context.Context; -import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; -import javax.annotation.Nullable; - -class MybatisAttributesExtractor implements AttributesExtractor { - - @Override - public void onStart( - AttributesBuilder attributes, - Context parentContext, - MapperMethodRequest mapperMethodRequest) { - attributes.put("component.name", "mybatis"); - } - - @Override - public void onEnd( - AttributesBuilder attributes, - Context context, - MapperMethodRequest mapperMethodRequest, - @Nullable Void unused, - @Nullable Throwable error) {} -} diff --git a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSpanNameExtractor.java b/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSpanNameExtractor.java deleted file mode 100644 index b83134d3c256..000000000000 --- a/instrumentation/mybatis/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/MybatisSpanNameExtractor.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.mybatis; - -import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor; - -public class MybatisSpanNameExtractor implements SpanNameExtractor { - - @Override - public String extract(MapperMethodRequest request) { - return request.getMapperName(); - } -} diff --git a/settings.gradle.kts b/settings.gradle.kts index eb47d10eb590..785e057fe3d9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -384,6 +384,7 @@ include(":instrumentation:mongo:mongo-3.7:javaagent") include(":instrumentation:mongo:mongo-4.0:javaagent") include(":instrumentation:mongo:mongo-async-3.3:javaagent") include(":instrumentation:mongo:mongo-common:testing") +include(":instrumentation:mybatis-3.2:javaagent") include(":instrumentation:netty:netty-3.8:javaagent") include(":instrumentation:netty:netty-4.0:javaagent") include(":instrumentation:netty:netty-4.1:javaagent") @@ -567,7 +568,6 @@ include(":instrumentation:vibur-dbcp-11.0:library") include(":instrumentation:vibur-dbcp-11.0:testing") include(":instrumentation:wicket-8.0:javaagent") include(":instrumentation:zio:zio-2.0:javaagent") -include(":instrumentation:mybatis:javaagent") // benchmark include(":benchmark-overhead-jmh") From 58e6de571c9829071f518354d7c049e2db2735a1 Mon Sep 17 00:00:00 2001 From: chengpu Date: Sat, 20 Jan 2024 00:37:47 +0800 Subject: [PATCH 05/12] Adjusted test case. --- .../mybatis-3.2/javaagent/build.gradle.kts | 1 + .../mybatis/v3_2/MyBatisTest.java | 50 ++++++------------- .../mybatis/v3_2/RecordMapper.java | 2 +- 3 files changed, 17 insertions(+), 36 deletions(-) diff --git a/instrumentation/mybatis-3.2/javaagent/build.gradle.kts b/instrumentation/mybatis-3.2/javaagent/build.gradle.kts index 76f6ad11f948..0d03a588b594 100644 --- a/instrumentation/mybatis-3.2/javaagent/build.gradle.kts +++ b/instrumentation/mybatis-3.2/javaagent/build.gradle.kts @@ -17,6 +17,7 @@ dependencies { library("org.mybatis:mybatis:3.2.0") testImplementation("org.mockito:mockito-core") testImplementation("org.mockito:mockito-junit-jupiter") + testImplementation("com.h2database:h2:1.4.191") } tasks.withType().configureEach { diff --git a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java index ce7a6a014289..fde77b272a82 100644 --- a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java +++ b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java @@ -5,23 +5,17 @@ package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; -import static org.mockito.Mockito.when; - import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import org.apache.ibatis.binding.MapperMethod; -import org.apache.ibatis.mapping.MappedStatement; -import org.apache.ibatis.mapping.SqlCommandType; -import org.apache.ibatis.reflection.factory.DefaultObjectFactory; +import org.apache.ibatis.mapping.Environment; import org.apache.ibatis.session.Configuration; -import org.apache.ibatis.session.defaults.DefaultSqlSession; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactoryBuilder; +import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; +import org.h2.jdbcx.JdbcDataSource; import org.junit.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.mockito.Mockito; public class MyBatisTest { @@ -32,33 +26,19 @@ public class MyBatisTest { "io.opentelemetry.javaagent.instrumentation.mybatis.v3_2.RecordMapper.updateRecord"; @Test - public void mybatis() throws Exception { - DefaultSqlSession sqlSession = Mockito.mock(DefaultSqlSession.class); - Configuration configuration = Mockito.mock(Configuration.class); - DefaultObjectFactory defaultObjectFactory = Mockito.mock(DefaultObjectFactory.class); - when(sqlSession.update(SPAN_NAME, null)).thenReturn(1); - Class mappedStatementClass = MappedStatement.class; - Constructor constructor = mappedStatementClass.getDeclaredConstructor(); - constructor.setAccessible(true); - MappedStatement mappedStatement = (MappedStatement) constructor.newInstance(); - Field id = mappedStatementClass.getDeclaredField("id"); - id.setAccessible(true); - id.set(mappedStatement, SPAN_NAME); - Field sqlCommandType = mappedStatementClass.getDeclaredField("sqlCommandType"); - sqlCommandType.setAccessible(true); - sqlCommandType.set(mappedStatement, SqlCommandType.UPDATE); - when(configuration.hasStatement(SPAN_NAME)).thenReturn(true); - when(configuration.getMappedStatement(SPAN_NAME)).thenReturn(mappedStatement); - when(configuration.getObjectFactory()).thenReturn(defaultObjectFactory); - when(defaultObjectFactory.isCollection(Void.class)).thenReturn(false); - Class mapper = RecordMapper.class; - Method method = mapper.getMethod("updateRecord"); - MapperMethod mapperMethod = new MapperMethod(mapper, method, configuration); - mapperMethod.execute(sqlSession, null); + public void mybatis() { + JdbcDataSource dataSource = new JdbcDataSource(); + dataSource.setURL("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"); + Configuration configuration = new Configuration(); + configuration.setEnvironment(new Environment("test", new JdbcTransactionFactory(), dataSource)); + configuration.addMapper(RecordMapper.class); + SqlSession sqlSession = new SqlSessionFactoryBuilder().build(configuration).openSession(); + RecordMapper recordMapper = sqlSession.getMapper(RecordMapper.class); + recordMapper.updateRecord(); span(SPAN_NAME); } - private static void span(String spanName) { + static void span(String spanName) { testing.waitAndAssertTracesWithoutScopeVersionVerification( trace -> { trace diff --git a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/RecordMapper.java b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/RecordMapper.java index 09f9f1a3d0b3..3de3dce7b179 100644 --- a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/RecordMapper.java +++ b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/RecordMapper.java @@ -9,6 +9,6 @@ public interface RecordMapper { - @Update("update dummy_record set content = '3131223'") + @Update("CREATE TABLE dummy_record (id INT PRIMARY KEY, content VARCHAR(255))") void updateRecord(); } From 94d10217391772355a5c1fe064072dee188e41b5 Mon Sep 17 00:00:00 2001 From: steverao Date: Mon, 22 Jan 2024 00:30:23 +0800 Subject: [PATCH 06/12] Optimized the code. --- .../mybatis/v3_2/MyBatisExecuteInstrumentation.java | 2 +- .../mybatis/v3_2/MyBatisInstrumentationModule.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisExecuteInstrumentation.java b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisExecuteInstrumentation.java index ccc6f6580eb5..f6723e5b5e62 100644 --- a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisExecuteInstrumentation.java +++ b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisExecuteInstrumentation.java @@ -49,7 +49,7 @@ public static void getMapperInfo( scope = context.makeCurrent(); } - @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = true) + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void stopSpan( @Advice.Thrown Throwable throwable, @Advice.Local("otelRequest") MapperMethodRequest request, diff --git a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisInstrumentationModule.java b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisInstrumentationModule.java index 1800bd9fcb18..9419d589bbe7 100644 --- a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisInstrumentationModule.java +++ b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisInstrumentationModule.java @@ -5,10 +5,11 @@ package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; +import static java.util.Collections.singletonList; + import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import java.util.Collections; import java.util.List; @AutoService(InstrumentationModule.class) @@ -20,6 +21,6 @@ public MyBatisInstrumentationModule() { @Override public List typeInstrumentations() { - return Collections.singletonList(new MyBatisExecuteInstrumentation()); + return singletonList(new MyBatisExecuteInstrumentation()); } } From eac822696e98808ccb857648d703fc91f67b5eb3 Mon Sep 17 00:00:00 2001 From: steverao Date: Mon, 22 Jan 2024 17:31:38 +0800 Subject: [PATCH 07/12] Optimized the code. --- instrumentation/mybatis-3.2/javaagent/build.gradle.kts | 2 ++ .../javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/instrumentation/mybatis-3.2/javaagent/build.gradle.kts b/instrumentation/mybatis-3.2/javaagent/build.gradle.kts index 0d03a588b594..d0296fe756a1 100644 --- a/instrumentation/mybatis-3.2/javaagent/build.gradle.kts +++ b/instrumentation/mybatis-3.2/javaagent/build.gradle.kts @@ -14,7 +14,9 @@ muzzle { dependencies { compileOnly("com.google.auto.value:auto-value-annotations") annotationProcessor("com.google.auto.value:auto-value") + library("org.mybatis:mybatis:3.2.0") + testImplementation("org.mockito:mockito-core") testImplementation("org.mockito:mockito-junit-jupiter") testImplementation("com.h2database:h2:1.4.191") diff --git a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java index fde77b272a82..5639677aabac 100644 --- a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java +++ b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java @@ -14,10 +14,10 @@ import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; import org.h2.jdbcx.JdbcDataSource; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -public class MyBatisTest { +class MyBatisTest { @RegisterExtension protected static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); @@ -26,7 +26,7 @@ public class MyBatisTest { "io.opentelemetry.javaagent.instrumentation.mybatis.v3_2.RecordMapper.updateRecord"; @Test - public void mybatis() { + void mybatis() { JdbcDataSource dataSource = new JdbcDataSource(); dataSource.setURL("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"); Configuration configuration = new Configuration(); From d288b43d722420d85cab9336156ff0ee0f5b1109 Mon Sep 17 00:00:00 2001 From: steverao Date: Tue, 23 Jan 2024 00:01:57 +0800 Subject: [PATCH 08/12] Optimized the code in test. --- .../instrumentation/mybatis/v3_2/MyBatisTest.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java index 5639677aabac..3083d1f12c21 100644 --- a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java +++ b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java @@ -35,14 +35,13 @@ void mybatis() { SqlSession sqlSession = new SqlSessionFactoryBuilder().build(configuration).openSession(); RecordMapper recordMapper = sqlSession.getMapper(RecordMapper.class); recordMapper.updateRecord(); - span(SPAN_NAME); + assertMyBatisTraces(SPAN_NAME); } - static void span(String spanName) { - testing.waitAndAssertTracesWithoutScopeVersionVerification( + private static void assertMyBatisTraces(String spanName) { + testing.waitAndAssertTraces( trace -> { trace - .hasSize(1) .hasSpansSatisfyingExactly( span -> { span.hasKind(SpanKind.INTERNAL).hasName(spanName); From 5cb0873df436d6441829c8373927491ca285048b Mon Sep 17 00:00:00 2001 From: steverao Date: Tue, 23 Jan 2024 00:25:12 +0800 Subject: [PATCH 09/12] Fixed checkstyle problem in test. --- .../instrumentation/mybatis/v3_2/MyBatisTest.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java index 3083d1f12c21..cecae0fe3102 100644 --- a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java +++ b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java @@ -41,11 +41,10 @@ void mybatis() { private static void assertMyBatisTraces(String spanName) { testing.waitAndAssertTraces( trace -> { - trace - .hasSpansSatisfyingExactly( - span -> { - span.hasKind(SpanKind.INTERNAL).hasName(spanName); - }); + trace.hasSpansSatisfyingExactly( + span -> { + span.hasKind(SpanKind.INTERNAL).hasName(spanName); + }); }); } } From 45aa6ecde96661a94eb4b62a51dd312ce1ba862b Mon Sep 17 00:00:00 2001 From: steverao Date: Tue, 23 Jan 2024 13:58:17 +0800 Subject: [PATCH 10/12] Deleted package name in span name. --- .../mybatis/v3_2/MyBatisSingletons.java | 5 ++++- .../v3_2/MyBatisSpanNameExtractor.java | 20 +++++++++++++++++++ .../mybatis/v3_2/MyBatisTest.java | 5 +---- 3 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSpanNameExtractor.java diff --git a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSingletons.java b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSingletons.java index 9fb8977347c7..6145f8aa765f 100644 --- a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSingletons.java +++ b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSingletons.java @@ -8,6 +8,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; +import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor; public final class MyBatisSingletons { private static final String INSTRUMENTATION_NAME = "io.opentelemetry.mybatis-3.2"; @@ -15,9 +16,11 @@ public final class MyBatisSingletons { private static final Instrumenter MAPPER_INSTRUMENTER; static { + SpanNameExtractor spanNameExtractor = new MyBatisSpanNameExtractor(); + MAPPER_INSTRUMENTER = Instrumenter.builder( - GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, MapperMethodRequest::getMapperName) + GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, spanNameExtractor) .buildInstrumenter(SpanKindExtractor.alwaysInternal()); } diff --git a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSpanNameExtractor.java b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSpanNameExtractor.java new file mode 100644 index 000000000000..cb868d95e02f --- /dev/null +++ b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSpanNameExtractor.java @@ -0,0 +1,20 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; + +import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor; + +public class MyBatisSpanNameExtractor implements SpanNameExtractor { + + @Override + public String extract(MapperMethodRequest request) { + String mapperName = request.getMapperName(); + // filter the package name in mapperName + int lastDotIndex = mapperName.lastIndexOf('.'); + int secondLastDotIndex = mapperName.lastIndexOf('.', lastDotIndex - 1); + return mapperName.substring(secondLastDotIndex + 1); + } +} diff --git a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java index cecae0fe3102..2ad0a191ab02 100644 --- a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java +++ b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java @@ -22,9 +22,6 @@ class MyBatisTest { @RegisterExtension protected static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); - private static final String SPAN_NAME = - "io.opentelemetry.javaagent.instrumentation.mybatis.v3_2.RecordMapper.updateRecord"; - @Test void mybatis() { JdbcDataSource dataSource = new JdbcDataSource(); @@ -35,7 +32,7 @@ void mybatis() { SqlSession sqlSession = new SqlSessionFactoryBuilder().build(configuration).openSession(); RecordMapper recordMapper = sqlSession.getMapper(RecordMapper.class); recordMapper.updateRecord(); - assertMyBatisTraces(SPAN_NAME); + assertMyBatisTraces("RecordMapper.updateRecord"); } private static void assertMyBatisTraces(String spanName) { From c584f764d6a9cfcbf1f71055b76d743799f648d5 Mon Sep 17 00:00:00 2001 From: steverao Date: Tue, 23 Jan 2024 23:40:46 +0800 Subject: [PATCH 11/12] Handled the spanName equals to null. --- .../instrumentation/mybatis/v3_2/MyBatisSpanNameExtractor.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSpanNameExtractor.java b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSpanNameExtractor.java index cb868d95e02f..b8e8b9371433 100644 --- a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSpanNameExtractor.java +++ b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSpanNameExtractor.java @@ -12,6 +12,9 @@ public class MyBatisSpanNameExtractor implements SpanNameExtractor Date: Fri, 9 Feb 2024 11:37:46 +0200 Subject: [PATCH 12/12] Rework mybatis instrumentation (#1) --- docs/supported-libraries.md | 3 +- .../mybatis-3.2/javaagent/build.gradle.kts | 7 +-- ....java => MapperMethodInstrumentation.java} | 25 ++++++---- .../mybatis/v3_2/MapperMethodRequest.java | 18 ------- .../v3_2/MyBatisInstrumentationModule.java | 10 +++- .../mybatis/v3_2/MyBatisSingletons.java | 26 ++++++---- .../v3_2/MyBatisSpanNameExtractor.java | 23 --------- .../v3_2/SqlCommandInstrumentation.java | 44 +++++++++++++++++ .../mybatis/v3_2/SqlCommandUtil.java | 29 ++++++++++++ .../mybatis/v3_2/MyBatisTest.java | 47 +++++++++++++------ .../mybatis/v3_2/RecordMapper.java | 14 ------ .../mybatis/v3_2/TestMapper.java | 14 ++++++ 12 files changed, 162 insertions(+), 98 deletions(-) rename instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/{MyBatisExecuteInstrumentation.java => MapperMethodInstrumentation.java} (70%) delete mode 100644 instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MapperMethodRequest.java delete mode 100644 instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSpanNameExtractor.java create mode 100644 instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/SqlCommandInstrumentation.java create mode 100644 instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/SqlCommandUtil.java delete mode 100644 instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/RecordMapper.java create mode 100644 instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/TestMapper.java diff --git a/docs/supported-libraries.md b/docs/supported-libraries.md index c22694fd5eba..3d274eeea72c 100644 --- a/docs/supported-libraries.md +++ b/docs/supported-libraries.md @@ -94,7 +94,7 @@ These are the supported libraries and frameworks: | [Logback](http://logback.qos.ch/) | 1.0+ | [opentelemetry-logback-appender-1.0](../instrumentation/logback/logback-appender-1.0/library),
[opentelemetry-logback-mdc-1.0](../instrumentation/logback/logback-mdc-1.0/library) | none | | [Micrometer](https://micrometer.io/) | 1.5+ | [opentelemetry-micrometer-1.5](../instrumentation/micrometer/micrometer-1.5/library) | none | | [MongoDB Driver](https://mongodb.github.io/mongo-java-driver/) | 3.1+ | [opentelemetry-mongo-3.1](../instrumentation/mongo/mongo-3.1/library) | [Database Client Spans] | -| [MyBatis](https://mybatis.org/mybatis-3/) | 3.2.0+ | N/A | none | +| [MyBatis](https://mybatis.org/mybatis-3/) | 3.2+ | N/A | none | | [Netty](https://github.com/netty/netty) | 3.8+ | [opentelemetry-netty-4.1](../instrumentation/netty/netty-4.1/library) | [HTTP Client Spans], [HTTP Client Metrics], [HTTP Server Spans], [HTTP Server Metrics] | | [OkHttp](https://github.com/square/okhttp/) | 2.2+ | [opentelemetry-okhttp-3.0](../instrumentation/okhttp/okhttp-3.0/library) | [HTTP Client Spans], [HTTP Client Metrics] | | [Oracle UCP](https://docs.oracle.com/database/121/JJUCP/) | 11.2+ | [opentelemetry-oracle-ucp-11.2](../instrumentation/oracle-ucp-11.2/library) | [Database Pool Metrics] | @@ -145,7 +145,6 @@ These are the supported libraries and frameworks: | [Vert.x Web](https://vertx.io/docs/vertx-web/java/) | 3.0+ | N/A | Provides `http.route` [2] | | [Vibur DBCP](https://www.vibur.org/) | 11.0+ | [opentelemetry-vibur-dbcp-11.0](../instrumentation/vibur-dbcp-11.0/library) | [Database Pool Metrics] | | [ZIO](https://zio.dev/) | 2.0+ | N/A | Context propagation | -| [MyBatis](https://mybatis.org/mybatis-3/) | 3.2.0+ | N/A | none | **[1]** Standalone library instrumentation refers to instrumentation that can be used without the Java agent. diff --git a/instrumentation/mybatis-3.2/javaagent/build.gradle.kts b/instrumentation/mybatis-3.2/javaagent/build.gradle.kts index d0296fe756a1..c7c8a098ea77 100644 --- a/instrumentation/mybatis-3.2/javaagent/build.gradle.kts +++ b/instrumentation/mybatis-3.2/javaagent/build.gradle.kts @@ -12,17 +12,14 @@ muzzle { } dependencies { - compileOnly("com.google.auto.value:auto-value-annotations") - annotationProcessor("com.google.auto.value:auto-value") - library("org.mybatis:mybatis:3.2.0") - testImplementation("org.mockito:mockito-core") - testImplementation("org.mockito:mockito-junit-jupiter") testImplementation("com.h2database:h2:1.4.191") } tasks.withType().configureEach { + jvmArgs("-Dotel.instrumentation.mybatis.enabled=true") + // required on jdk17 jvmArgs("--add-opens=java.base/java.lang=ALL-UNNAMED") jvmArgs("-XX:+IgnoreUnrecognizedVMOptions") diff --git a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisExecuteInstrumentation.java b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MapperMethodInstrumentation.java similarity index 70% rename from instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisExecuteInstrumentation.java rename to instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MapperMethodInstrumentation.java index f6723e5b5e62..741005717f60 100644 --- a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisExecuteInstrumentation.java +++ b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MapperMethodInstrumentation.java @@ -6,11 +6,12 @@ package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext; -import static io.opentelemetry.javaagent.instrumentation.mybatis.v3_2.MyBatisSingletons.mapperInstrumenter; +import static io.opentelemetry.javaagent.instrumentation.mybatis.v3_2.MyBatisSingletons.instrumenter; import static net.bytebuddy.matcher.ElementMatchers.named; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.incubator.semconv.util.ClassAndMethod; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import net.bytebuddy.asm.Advice; @@ -18,7 +19,7 @@ import net.bytebuddy.matcher.ElementMatcher; import org.apache.ibatis.binding.MapperMethod.SqlCommand; -public class MyBatisExecuteInstrumentation implements TypeInstrumentation { +public class MapperMethodInstrumentation implements TypeInstrumentation { @Override public ElementMatcher typeMatcher() { @@ -28,7 +29,7 @@ public ElementMatcher typeMatcher() { @Override public void transform(TypeTransformer transformer) { transformer.applyAdviceToMethod( - named("execute"), MyBatisExecuteInstrumentation.class.getName() + "$ExecuteAdvice"); + named("execute"), MapperMethodInstrumentation.class.getName() + "$ExecuteAdvice"); } @SuppressWarnings("unused") @@ -37,27 +38,33 @@ public static class ExecuteAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) public static void getMapperInfo( @Advice.FieldValue("command") SqlCommand command, - @Advice.Local("otelRequest") MapperMethodRequest request, + @Advice.Local("otelRequest") ClassAndMethod request, @Advice.Local("otelContext") Context context, @Advice.Local("otelScope") Scope scope) { + if (command == null) { + return; + } + request = SqlCommandUtil.getClassAndMethod(command); + if (request == null) { + return; + } Context parentContext = currentContext(); - if (command == null || !mapperInstrumenter().shouldStart(parentContext, request)) { + if (!instrumenter().shouldStart(parentContext, request)) { return; } - request = MapperMethodRequest.create(command.getName()); - context = mapperInstrumenter().start(parentContext, request); + context = instrumenter().start(parentContext, request); scope = context.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void stopSpan( @Advice.Thrown Throwable throwable, - @Advice.Local("otelRequest") MapperMethodRequest request, + @Advice.Local("otelRequest") ClassAndMethod request, @Advice.Local("otelContext") Context context, @Advice.Local("otelScope") Scope scope) { if (scope != null) { scope.close(); - mapperInstrumenter().end(context, request, null, throwable); + instrumenter().end(context, request, null, throwable); } } } diff --git a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MapperMethodRequest.java b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MapperMethodRequest.java deleted file mode 100644 index cd8be5b7d48f..000000000000 --- a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MapperMethodRequest.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; - -import com.google.auto.value.AutoValue; - -@AutoValue -public abstract class MapperMethodRequest { - - public static MapperMethodRequest create(String mapperName) { - return new AutoValue_MapperMethodRequest(mapperName); - } - - public abstract String getMapperName(); -} diff --git a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisInstrumentationModule.java b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisInstrumentationModule.java index 9419d589bbe7..55d4910ef232 100644 --- a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisInstrumentationModule.java +++ b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisInstrumentationModule.java @@ -5,11 +5,12 @@ package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; -import static java.util.Collections.singletonList; +import static java.util.Arrays.asList; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import java.util.List; @AutoService(InstrumentationModule.class) @@ -21,6 +22,11 @@ public MyBatisInstrumentationModule() { @Override public List typeInstrumentations() { - return singletonList(new MyBatisExecuteInstrumentation()); + return asList(new MapperMethodInstrumentation(), new SqlCommandInstrumentation()); + } + + @Override + public boolean defaultEnabled(ConfigProperties config) { + return false; } } diff --git a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSingletons.java b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSingletons.java index 6145f8aa765f..b24eac8cce1e 100644 --- a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSingletons.java +++ b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSingletons.java @@ -6,26 +6,32 @@ package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.semconv.code.CodeAttributesExtractor; +import io.opentelemetry.instrumentation.api.incubator.semconv.code.CodeAttributesGetter; +import io.opentelemetry.instrumentation.api.incubator.semconv.code.CodeSpanNameExtractor; +import io.opentelemetry.instrumentation.api.incubator.semconv.util.ClassAndMethod; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; -import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor; public final class MyBatisSingletons { private static final String INSTRUMENTATION_NAME = "io.opentelemetry.mybatis-3.2"; - - private static final Instrumenter MAPPER_INSTRUMENTER; + private static final Instrumenter INSTRUMENTER; static { - SpanNameExtractor spanNameExtractor = new MyBatisSpanNameExtractor(); - - MAPPER_INSTRUMENTER = - Instrumenter.builder( - GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, spanNameExtractor) + CodeAttributesGetter codeAttributesGetter = + ClassAndMethod.codeAttributesGetter(); + + INSTRUMENTER = + Instrumenter.builder( + GlobalOpenTelemetry.get(), + INSTRUMENTATION_NAME, + CodeSpanNameExtractor.create(codeAttributesGetter)) + .addAttributesExtractor(CodeAttributesExtractor.create(codeAttributesGetter)) .buildInstrumenter(SpanKindExtractor.alwaysInternal()); } - public static Instrumenter mapperInstrumenter() { - return MAPPER_INSTRUMENTER; + public static Instrumenter instrumenter() { + return INSTRUMENTER; } private MyBatisSingletons() {} diff --git a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSpanNameExtractor.java b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSpanNameExtractor.java deleted file mode 100644 index b8e8b9371433..000000000000 --- a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisSpanNameExtractor.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; - -import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor; - -public class MyBatisSpanNameExtractor implements SpanNameExtractor { - - @Override - public String extract(MapperMethodRequest request) { - String mapperName = request.getMapperName(); - if (mapperName == null) { - return "MyBatis execute"; - } - // filter the package name in mapperName - int lastDotIndex = mapperName.lastIndexOf('.'); - int secondLastDotIndex = mapperName.lastIndexOf('.', lastDotIndex - 1); - return mapperName.substring(secondLastDotIndex + 1); - } -} diff --git a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/SqlCommandInstrumentation.java b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/SqlCommandInstrumentation.java new file mode 100644 index 000000000000..c137bd294082 --- /dev/null +++ b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/SqlCommandInstrumentation.java @@ -0,0 +1,44 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; + +import static net.bytebuddy.matcher.ElementMatchers.isConstructor; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; + +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import java.lang.reflect.Method; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.ibatis.binding.MapperMethod.SqlCommand; + +public class SqlCommandInstrumentation implements TypeInstrumentation { + @Override + public ElementMatcher typeMatcher() { + return named("org.apache.ibatis.binding.MapperMethod$SqlCommand"); + } + + @Override + public void transform(TypeTransformer transformer) { + transformer.applyAdviceToMethod( + isConstructor().and(takesArgument(1, Class.class)).and(takesArgument(2, Method.class)), + SqlCommandInstrumentation.class.getName() + "$ConstructorAdvice"); + } + + @SuppressWarnings("unused") + public static class ConstructorAdvice { + + @Advice.OnMethodExit(suppress = Throwable.class) + public static void onExit( + @Advice.This SqlCommand command, + @Advice.Argument(1) Class mapperInterface, + @Advice.Argument(2) Method method) { + SqlCommandUtil.setClassAndMethod(command, mapperInterface, method); + } + } +} diff --git a/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/SqlCommandUtil.java b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/SqlCommandUtil.java new file mode 100644 index 000000000000..f67692f47229 --- /dev/null +++ b/instrumentation/mybatis-3.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/SqlCommandUtil.java @@ -0,0 +1,29 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; + +import io.opentelemetry.instrumentation.api.incubator.semconv.util.ClassAndMethod; +import io.opentelemetry.instrumentation.api.util.VirtualField; +import java.lang.reflect.Method; +import org.apache.ibatis.binding.MapperMethod.SqlCommand; + +public final class SqlCommandUtil { + private static final VirtualField field = + VirtualField.find(SqlCommand.class, ClassAndMethod.class); + + public static void setClassAndMethod(SqlCommand command, Class clazz, Method method) { + if (clazz == null || method == null || method.getName() == null) { + return; + } + field.set(command, ClassAndMethod.create(clazz, method.getName())); + } + + public static ClassAndMethod getClassAndMethod(SqlCommand command) { + return field.get(command); + } + + private SqlCommandUtil() {} +} diff --git a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java index 2ad0a191ab02..42b81e0b1ee0 100644 --- a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java +++ b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/MyBatisTest.java @@ -5,43 +5,60 @@ package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; + import io.opentelemetry.api.trace.SpanKind; import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; +import io.opentelemetry.semconv.SemanticAttributes; import org.apache.ibatis.mapping.Environment; import org.apache.ibatis.session.Configuration; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; import org.h2.jdbcx.JdbcDataSource; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; class MyBatisTest { @RegisterExtension - protected static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); + private static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); - @Test - void mybatis() { + private static SqlSession sqlSession; + + @BeforeAll + static void setUp() { JdbcDataSource dataSource = new JdbcDataSource(); dataSource.setURL("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"); Configuration configuration = new Configuration(); configuration.setEnvironment(new Environment("test", new JdbcTransactionFactory(), dataSource)); - configuration.addMapper(RecordMapper.class); - SqlSession sqlSession = new SqlSessionFactoryBuilder().build(configuration).openSession(); - RecordMapper recordMapper = sqlSession.getMapper(RecordMapper.class); - recordMapper.updateRecord(); - assertMyBatisTraces("RecordMapper.updateRecord"); + configuration.addMapper(TestMapper.class); + sqlSession = new SqlSessionFactoryBuilder().build(configuration).openSession(); } - private static void assertMyBatisTraces(String spanName) { + @AfterAll + static void cleanUp() { + if (sqlSession != null) { + sqlSession.close(); + } + } + + @Test + void testSelect() { + TestMapper testMapper = sqlSession.getMapper(TestMapper.class); + testMapper.select(); + testing.waitAndAssertTraces( - trace -> { - trace.hasSpansSatisfyingExactly( - span -> { - span.hasKind(SpanKind.INTERNAL).hasName(spanName); - }); - }); + trace -> + trace.hasSpansSatisfyingExactly( + span -> + span.hasKind(SpanKind.INTERNAL) + .hasName("TestMapper.select") + .hasAttributesSatisfyingExactly( + equalTo(SemanticAttributes.CODE_NAMESPACE, TestMapper.class.getName()), + equalTo(SemanticAttributes.CODE_FUNCTION, "select")))); } } diff --git a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/RecordMapper.java b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/RecordMapper.java deleted file mode 100644 index 3de3dce7b179..000000000000 --- a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/RecordMapper.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; - -import org.apache.ibatis.annotations.Update; - -public interface RecordMapper { - - @Update("CREATE TABLE dummy_record (id INT PRIMARY KEY, content VARCHAR(255))") - void updateRecord(); -} diff --git a/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/TestMapper.java b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/TestMapper.java new file mode 100644 index 000000000000..1d5e858a91ce --- /dev/null +++ b/instrumentation/mybatis-3.2/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/mybatis/v3_2/TestMapper.java @@ -0,0 +1,14 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.mybatis.v3_2; + +import org.apache.ibatis.annotations.Select; + +public interface TestMapper { + + @Select("SELECT 1") + int select(); +}