Fixed issues in the MySQL component where the executeBatch method could result in empty SQL statements . (#702)

This commit is contained in:
w2dp 2024-07-01 17:01:00 +08:00 committed by GitHub
parent 0fc3cd86e8
commit 2e08217688
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 3 deletions

View File

@ -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)

View File

@ -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());

View File

@ -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;