Merge pull request #663 from ascrutae/fix/mysql-plugin-issue
fix the sql tag value is null when client using Statement.execute(sql) method
This commit is contained in:
commit
2fa0a41fbc
|
|
@ -43,7 +43,7 @@ public class CreateStatementInterceptor implements InstanceMethodsAroundIntercep
|
|||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
Object ret) throws Throwable {
|
||||
if (ret instanceof EnhancedInstance) {
|
||||
((EnhancedInstance)ret).setSkyWalkingDynamicField(new StatementEnhanceInfos((ConnectionInfo)objInst.getSkyWalkingDynamicField(), "", "CallableStatement"));
|
||||
((EnhancedInstance)ret).setSkyWalkingDynamicField(new StatementEnhanceInfos((ConnectionInfo)objInst.getSkyWalkingDynamicField(), "", "Statement"));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.jdbc.mysql;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.agent.core.context.tag.Tags;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos;
|
||||
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
|
||||
|
||||
/**
|
||||
* @author zhang xin
|
||||
*/
|
||||
public class PreparedStatementExecuteMethodsInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
|
||||
@Override
|
||||
public final void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes,
|
||||
MethodInterceptResult result) throws Throwable {
|
||||
StatementEnhanceInfos cacheObject = (StatementEnhanceInfos)objInst.getSkyWalkingDynamicField();
|
||||
ConnectionInfo connectInfo = cacheObject.getConnectionInfo();
|
||||
/**
|
||||
* For avoid NPE. In this particular case, Execute sql inside the {@link com.mysql.jdbc.ConnectionImpl} constructor,
|
||||
* before the interceptor sets the connectionInfo.
|
||||
*
|
||||
* @see JDBCDriverInterceptor#afterMethod(EnhancedInstance, Method, Object[], Class[], Object)
|
||||
*/
|
||||
if (connectInfo != null) {
|
||||
|
||||
AbstractSpan span = ContextManager.createExitSpan(buildOperationName(connectInfo, method.getName(), cacheObject.getStatementName()), connectInfo.getDatabasePeer());
|
||||
Tags.DB_TYPE.set(span, "sql");
|
||||
Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName());
|
||||
Tags.DB_STATEMENT.set(span, cacheObject.getSql());
|
||||
span.setComponent(connectInfo.getComponent());
|
||||
|
||||
SpanLayer.asDB(span);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes,
|
||||
Object ret) throws Throwable {
|
||||
StatementEnhanceInfos cacheObject = (StatementEnhanceInfos)objInst.getSkyWalkingDynamicField();
|
||||
if (cacheObject.getConnectionInfo() != null) {
|
||||
ContextManager.stopSpan();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override public final void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t) {
|
||||
StatementEnhanceInfos cacheObject = (StatementEnhanceInfos)objInst.getSkyWalkingDynamicField();
|
||||
if (cacheObject.getConnectionInfo() != null) {
|
||||
ContextManager.activeSpan().errorOccurred().log(t);
|
||||
}
|
||||
}
|
||||
|
||||
private String buildOperationName(ConnectionInfo connectionInfo, String methodName, String statementName) {
|
||||
return connectionInfo.getDBType() + "/JDBI/" + statementName + "/" + methodName;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,18 +16,17 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
package org.apache.skywalking.apm.plugin.jdbc.mysql;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.agent.core.context.tag.Tags;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos;
|
||||
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
|
||||
|
||||
/**
|
||||
|
|
@ -54,7 +53,17 @@ public class StatementExecuteMethodsInterceptor implements InstanceMethodsAround
|
|||
AbstractSpan span = ContextManager.createExitSpan(buildOperationName(connectInfo, method.getName(), cacheObject.getStatementName()), connectInfo.getDatabasePeer());
|
||||
Tags.DB_TYPE.set(span, "sql");
|
||||
Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName());
|
||||
Tags.DB_STATEMENT.set(span, cacheObject.getSql());
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
String sql = "";
|
||||
if (allArguments.length > 0) {
|
||||
sql = (String)allArguments[0];
|
||||
}
|
||||
|
||||
Tags.DB_STATEMENT.set(span, sql);
|
||||
span.setComponent(connectInfo.getComponent());
|
||||
|
||||
SpanLayer.asDB(span);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import static org.apache.skywalking.apm.plugin.jdbc.mysql.define.MultiClassNameM
|
|||
*/
|
||||
public class CallableInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
private static final String ENHANCE_CLASS = "com.mysql.jdbc.CallableStatement";
|
||||
private static final String SERVICE_METHOD_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.mysql.StatementExecuteMethodsInterceptor";
|
||||
private static final String SERVICE_METHOD_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.mysql.PreparedStatementExecuteMethodsInterceptor";
|
||||
|
||||
@Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[0];
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ import static org.apache.skywalking.apm.plugin.jdbc.mysql.define.MultiClassNameM
|
|||
public class PreparedStatementInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
private static final String PREPARED_STATEMENT_CLASS_NAME = "com.mysql.jdbc.PreparedStatement";
|
||||
private static final String SERVICE_METHOD_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.mysql.StatementExecuteMethodsInterceptor";
|
||||
private static final String SERVICE_METHOD_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.mysql.PreparedStatementExecuteMethodsInterceptor";
|
||||
public static final String MYSQL6_PREPARED_STATEMENT_CLASS_NAME = "com.mysql.cj.jdbc.PreparedStatement";
|
||||
public static final String JDBC42_PREPARED_STATEMENT_CLASS_NAME = "com.mysql.jdbc.JDBC42PreparedStatement";
|
||||
|
||||
|
|
@ -59,8 +59,7 @@ public class PreparedStatementInstrumentation extends ClassInstanceMethodsEnhanc
|
|||
return named("execute")
|
||||
.or(named("executeQuery"))
|
||||
.or(named("executeUpdate"))
|
||||
.or(named("executeLargeUpdate"))
|
||||
.or(named("addBatch"));
|
||||
.or(named("executeLargeUpdate"));
|
||||
}
|
||||
|
||||
@Override public String getMethodsInterceptor() {
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ public class StatementInstrumentation extends ClassInstanceMethodsEnhancePluginD
|
|||
.or(named("executeQuery"))
|
||||
.or(named("executeUpdate"))
|
||||
.or(named("executeLargeUpdate"))
|
||||
.or(named("addBatch"))
|
||||
.or(named("executeBatchInternal"))
|
||||
.or(named("executeUpdateInternal"))
|
||||
.or(named("executeQuery"))
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
package org.apache.skywalking.apm.plugin.jdbc.mysql;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
|
@ -80,8 +79,8 @@ public class StatementExecuteMethodsInterceptorTest {
|
|||
|
||||
@Test
|
||||
public void testCreateDatabaseSpan() throws Throwable {
|
||||
serviceMethodInterceptor.beforeMethod(objectInstance, method, null, null, null);
|
||||
serviceMethodInterceptor.afterMethod(objectInstance, method, null, null, null);
|
||||
serviceMethodInterceptor.beforeMethod(objectInstance, method, new Object[] {"SELECT * FROM test"}, null, null);
|
||||
serviceMethodInterceptor.afterMethod(objectInstance, method, new Object[] {"SELECT * FROM test"}, null, null);
|
||||
|
||||
assertThat(segmentStorage.getTraceSegments().size(), is(1));
|
||||
TraceSegment segment = segmentStorage.getTraceSegments().get(0);
|
||||
|
|
|
|||
|
|
@ -65,9 +65,7 @@ public class AbstractJdbc2StatementInstrumentation extends ClassInstanceMethodsE
|
|||
.or(named("executeQuery").and(takesArguments(0)))
|
||||
.or(named("executeQuery").and(takesArguments(1)))
|
||||
.or(named("executeUpdate").and(takesArguments(0)))
|
||||
.or(named("executeUpdate").and(takesArguments(1)))
|
||||
.or(named("addBatch").and(takesArguments(1)))
|
||||
.or(named("addBatch").and(takesArguments(0)));
|
||||
.or(named("executeUpdate").and(takesArguments(1)));
|
||||
}
|
||||
|
||||
@Override public String getMethodsInterceptor() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue