This is an automated email from the ASF dual-hosted git repository. wusheng pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/skywalking-java.git
The following commit(s) were added to refs/heads/main by this push: new 2e08217688 Fixed issues in the MySQL component where the executeBatch method could result in empty SQL statements . (#702) 2e08217688 is described below commit 2e082176889e552268c41fe8dbb1444839ef865c Author: w2dp <w...@qq.com> AuthorDate: Mon Jul 1 17:01:00 2024 +0800 Fixed issues in the MySQL component where the executeBatch method could result in empty SQL statements . (#702) --- CHANGES.md | 1 + .../mysql/StatementExecuteMethodsInterceptor.java | 8 ++++++-- .../StatementExecuteMethodsInterceptorTest.java | 21 ++++++++++++++++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index f80f1f151b..623b5015f1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,7 @@ Release Notes. * Fix the opentracing toolkit SPI config * Improve 4x performance of ContextManagerExtendService.createTraceContext() * Add a plugin that supports the Solon framework. +* Fixed issues in the MySQL component where the executeBatch method could result in empty SQL statements . All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/213?closed=1) diff --git a/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptor.java b/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptor.java index 8895e118a5..0c2f5047b9 100644 --- a/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptor.java @@ -28,6 +28,7 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInt import org.apache.skywalking.apm.plugin.jdbc.SqlBodyUtil; import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos; import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; +import org.apache.skywalking.apm.util.StringUtil; import java.lang.reflect.Method; @@ -52,14 +53,17 @@ public class StatementExecuteMethodsInterceptor implements InstanceMethodsAround Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName()); /** - * The first argument of all intercept method in `com.mysql.jdbc.StatementImpl` class is SQL, except the - * `executeBatch` method that the jdbc plugin need to trace, because of this method argument size is zero. + * Except for the `executeBatch` method, the first parameter of all enhanced methods in `com.mysql.jdbc.StatementImpl` is the SQL statement. + * Therefore, executeBatch will attempt to obtain the SQL from `cacheObject`. */ String sql = ""; if (allArguments.length > 0) { sql = (String) allArguments[0]; sql = SqlBodyUtil.limitSqlBodySize(sql); + } else if (StringUtil.isNotBlank(cacheObject.getSql())) { + sql = SqlBodyUtil.limitSqlBodySize(cacheObject.getSql()); } + Tags.DB_STATEMENT.set(span, sql); span.setComponent(connectInfo.getComponent()); diff --git a/apm-sniffer/apm-sdk-plugin/mysql-common/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/mysql-common/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptorTest.java index e3ceaa6228..df2769b8cd 100644 --- a/apm-sniffer/apm-sdk-plugin/mysql-common/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/mysql-common/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptorTest.java @@ -72,7 +72,8 @@ public class StatementExecuteMethodsInterceptorTest { JDBCPluginConfig.Plugin.JDBC.SQL_BODY_MAX_LENGTH = 2048; serviceMethodInterceptor = new StatementExecuteMethodsInterceptor(); - enhanceRequireCacheObject = new StatementEnhanceInfos(connectionInfo, "SELECT * FROM test", "CallableStatement"); + enhanceRequireCacheObject = new StatementEnhanceInfos(connectionInfo, SQL, "CallableStatement"); + when(objectInstance.getSkyWalkingDynamicField()).thenReturn(enhanceRequireCacheObject); when(method.getName()).thenReturn("executeQuery"); when(connectionInfo.getComponent()).thenReturn(ComponentsDefine.H2_JDBC_DRIVER); @@ -81,6 +82,24 @@ public class StatementExecuteMethodsInterceptorTest { when(connectionInfo.getDatabasePeer()).thenReturn("localhost:3307"); } + @Test + public void testCreateDatabaseSpanWithNoMethodParamButWithCache() throws Throwable { + JDBCPluginConfig.Plugin.JDBC.SQL_BODY_MAX_LENGTH = 2048; + + serviceMethodInterceptor.beforeMethod(objectInstance, method, new Object[0], null, null); + serviceMethodInterceptor.afterMethod(objectInstance, method, new Object[0], null, null); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment segment = segmentStorage.getTraceSegments().get(0); + assertThat(SegmentHelper.getSpans(segment).size(), is(1)); + AbstractTracingSpan span = SegmentHelper.getSpans(segment).get(0); + SpanAssert.assertLayer(span, SpanLayer.DB); + assertThat(span.getOperationName(), is("H2/JDBC/CallableStatement/executeQuery")); + SpanAssert.assertTag(span, 0, "H2"); + SpanAssert.assertTag(span, 1, "test"); + SpanAssert.assertTag(span, 2, SQL); + } + @Test public void testCreateDatabaseSpan() throws Throwable { JDBCPluginConfig.Plugin.JDBC.SQL_BODY_MAX_LENGTH = 2048;