提交 c9dbd6d9 编写于 作者: A ascrutae

fix the sql tag value is null when client using Statement.execute(sql) method

上级 ea378399
......@@ -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;
}
......
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed 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.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
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() {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册