提交 09564919 编写于 作者: K kezhenxu94 提交者: wu-sheng

Add config to control tracing sql parameters in MySQL agent (#2846)

* Add config to control tracing sql parameters
上级 d17e215d
......@@ -194,6 +194,21 @@ public class Config {
public static boolean USE_QUALIFIED_NAME_AS_OPERATION_NAME = false;
}
public static class MySQL {
/**
* If set to true, the parameters of the sql (typically {@link java.sql.PreparedStatement})
* would be collected.
*/
public static boolean TRACE_SQL_PARAMETERS = false;
/**
* For the sake of performance, SkyWalking won't save the entire parameters string into the tag,
* but only the first {@code SQL_PARAMETERS_MAX_LENGTH} characters.
*
* Set a negative number to save the complete parameter string to the tag.
*/
public static int SQL_PARAMETERS_MAX_LENGTH = 512;
}
public static class SolrJ {
/**
* If true, trace all the query parameters(include deleteByIds and deleteByQuery) in Solr query request, default is false.
......
/*
* 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;
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.Constants;
import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos;
import java.lang.reflect.Method;
/**
* @author kezhenxu94
*/
public class JDBCPreparedStatementIgnorableSetterInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public final void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
final StatementEnhanceInfos statementEnhanceInfos = (StatementEnhanceInfos) objInst.getSkyWalkingDynamicField();
final int index = (Integer) allArguments[0];
statementEnhanceInfos.setParameter(index, Constants.SQL_PARAMETER_PLACEHOLDER);
}
@Override
public final Object afterMethod(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
Object ret) throws Throwable {
return ret;
}
@Override
public final void handleMethodException(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
Throwable t) {
}
}
/*
* 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;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.plugin.jdbc.define.Constants;
import static net.bytebuddy.matcher.ElementMatchers.named;
/**
* @author kezhenxu94
*/
public final class JDBCPreparedStatementNullSetterInstanceMethodsInterceptPoint implements InstanceMethodsInterceptPoint {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named("setNull");
}
@Override
public String getMethodsInterceptor() {
return Constants.PREPARED_STATEMENT_NULL_SETTER_METHODS_INTERCEPTOR;
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
/*
* 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;
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 java.lang.reflect.Method;
/**
* @author kezhenxu94
*/
public class JDBCPreparedStatementNullSetterInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public final void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
final StatementEnhanceInfos statementEnhanceInfos = (StatementEnhanceInfos) objInst.getSkyWalkingDynamicField();
final int index = (Integer) allArguments[0];
statementEnhanceInfos.setParameter(index, "NULL");
}
@Override
public final Object afterMethod(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
Object ret) throws Throwable {
return ret;
}
@Override
public final void handleMethodException(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
Throwable t) {
}
}
/*
* 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;
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 java.lang.reflect.Method;
/**
* @author kezhenxu94
*/
public class JDBCPreparedStatementSetterInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public final void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
final StatementEnhanceInfos statementEnhanceInfos = (StatementEnhanceInfos) objInst.getSkyWalkingDynamicField();
final int index = (Integer) allArguments[0];
final Object parameter = allArguments[1];
statementEnhanceInfos.setParameter(index, parameter);
}
@Override
public final Object afterMethod(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
Object ret) throws Throwable {
return ret;
}
@Override
public final void handleMethodException(EnhancedInstance objInst,
Method method,
Object[] allArguments,
Class<?>[] argumentsTypes,
Throwable t) {
}
}
/*
* 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;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.apache.skywalking.apm.agent.core.conf.Config;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.plugin.jdbc.define.Constants;
import java.util.Set;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.none;
import static org.apache.skywalking.apm.plugin.jdbc.define.Constants.PS_IGNORABLE_SETTERS;
import static org.apache.skywalking.apm.plugin.jdbc.define.Constants.PS_SETTERS;
/**
* @author kezhenxu94
*/
public class PSSetterDefinitionOfJDBCInstrumentation implements InstanceMethodsInterceptPoint {
private final boolean ignorable;
public PSSetterDefinitionOfJDBCInstrumentation(boolean ignorable) {
this.ignorable = ignorable;
}
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
ElementMatcher.Junction<MethodDescription> matcher = none();
if (Config.Plugin.MySQL.TRACE_SQL_PARAMETERS) {
final Set<String> setters = ignorable ? PS_IGNORABLE_SETTERS : PS_SETTERS;
for (String setter : setters) {
matcher = matcher.or(named(setter));
}
}
return matcher;
}
@Override
public String getMethodsInterceptor() {
return ignorable
? Constants.PREPARED_STATEMENT_IGNORABLE_SETTER_METHODS_INTERCEPTOR
: Constants.PREPARED_STATEMENT_SETTER_METHODS_INTERCEPTOR;
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
......@@ -19,6 +19,10 @@
package org.apache.skywalking.apm.plugin.jdbc.define;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class Constants {
public static final String CREATE_STATEMENT_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.jdbc.JDBCStatementInterceptor";
......@@ -41,5 +45,41 @@ public class Constants {
public static final String CLOSE_METHOD_NAME = "close";
public static final String RELEASE_SAVE_POINT_METHOD_NAME = "releaseSavepoint";
public static final String SQL_PARAMETER_PLACEHOLDER = "?";
public static final Set<String> PS_SETTERS = new HashSet<String>(Arrays.asList(
"setArray",
"setBigDecimal",
"setBoolean",
"setByte",
"setDate",
"setDouble",
"setFloat",
"setInt",
"setLong",
"setNString",
"setObject",
"setRowId",
"setShort",
"setString",
"setTime",
"setTimestamp",
"setURL"
));
public static final Set<String> PS_IGNORABLE_SETTERS = new HashSet<String>(Arrays.asList(
"setAsciiStream",
"setBinaryStream",
"setBlob",
"setBytes",
"setCharacterStream",
"setClob",
"setNCharacterStream",
"setNClob",
"setRef",
"setSQLXML",
"setUnicodeStream"
));
public static final String PREPARED_STATEMENT_SETTER_METHODS_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.JDBCPreparedStatementSetterInterceptor";
public static final String PREPARED_STATEMENT_NULL_SETTER_METHODS_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.JDBCPreparedStatementNullSetterInterceptor";
public static final String PREPARED_STATEMENT_IGNORABLE_SETTER_METHODS_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.JDBCPreparedStatementIgnorableSetterInterceptor";
}
......@@ -21,6 +21,8 @@ package org.apache.skywalking.apm.plugin.jdbc.define;
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import java.util.Arrays;
/**
* {@link StatementEnhanceInfos} contain the {@link ConnectionInfo} and
* <code>sql</code> for trace mysql.
......@@ -31,6 +33,8 @@ public class StatementEnhanceInfos {
private ConnectionInfo connectionInfo;
private String statementName;
private String sql;
private Object[] parameters;
private int maxIndex = 0;
public StatementEnhanceInfos(ConnectionInfo connectionInfo, String sql, String statementName) {
this.connectionInfo = connectionInfo;
......@@ -49,4 +53,31 @@ public class StatementEnhanceInfos {
public String getStatementName() {
return statementName;
}
public void setParameter(int index, final Object parameter) {
maxIndex = maxIndex > index ? maxIndex : index;
index--; // start from 1
if (parameters == null) {
final int initialSize = Math.max(20, maxIndex);
parameters = new Object[initialSize];
Arrays.fill(parameters, null);
}
int length = parameters.length;
if (index >= length) {
int newSize = Math.max(index + 1, length * 2);
Object[] newParameters = new Object[newSize];
System.arraycopy(parameters, 0, newParameters, 0, length);
Arrays.fill(newParameters, length, newSize, null);
parameters = newParameters;
}
parameters[index] = parameter;
}
public Object[] getParameters() {
return parameters;
}
public int getMaxIndex() {
return maxIndex;
}
}
/*
* 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.v5.define;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.plugin.jdbc.PSSetterDefinitionOfJDBCInstrumentation;
/**
* @author kezhenxu94
*/
public class PreparedStatementIgnoredSetterInstrumentation extends PreparedStatementInstrumentation {
@Override
protected final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new PSSetterDefinitionOfJDBCInstrumentation(true)
};
}
}
......@@ -31,13 +31,13 @@ import static org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMa
/**
* {@link PreparedStatementInstrumentation} define that the mysql-2.x plugin intercepts the following methods in the
* com.mysql.jdbc.JDBC42PreparedStatement, com.mysql.jdbc.PreparedStatement and
* com.mysql.jdbc.JDBC42PreparedStatement, com.mysql.jdbc.PreparedStatement and
* com.mysql.cj.jdbc.PreparedStatement class:
* 1. execute
* 2. executeQuery
* 3. executeUpdate
* 4. executeLargeUpdate
* 5. addBatch
* 1. execute
* 2. executeQuery
* 3. executeUpdate
* 4. executeLargeUpdate
* 5. addBatch
*
* @author zhangxin
*/
......@@ -51,7 +51,7 @@ public class PreparedStatementInstrumentation extends AbstractMysqlInstrumentati
return new ConstructorInterceptPoint[0];
}
@Override protected final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
@Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
......
/*
* 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.v5.define;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.plugin.jdbc.JDBCPreparedStatementNullSetterInstanceMethodsInterceptPoint;
/**
* @author kezhenxu94
*/
public class PreparedStatementNullSetterInstrumentation extends PreparedStatementInstrumentation {
@Override
protected final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new JDBCPreparedStatementNullSetterInstanceMethodsInterceptPoint()
};
}
}
/*
* 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.v5.define;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.plugin.jdbc.PSSetterDefinitionOfJDBCInstrumentation;
/**
* @author kezhenxu94
*/
public class PreparedStatementSetterInstrumentation extends PreparedStatementInstrumentation {
@Override
protected final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new PSSetterDefinitionOfJDBCInstrumentation(false)
};
}
}
......@@ -21,3 +21,6 @@ mysql-5.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v5.define.PreparedStatemen
mysql-5.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v5.define.StatementInstrumentation
mysql-5.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v5.define.CacheIpsInstrumentation
mysql-5.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v5.define.ConnectionImplCreateInstrumentation
mysql-5.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v5.define.PreparedStatementIgnoredSetterInstrumentation
mysql-5.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v5.define.PreparedStatementSetterInstrumentation
mysql-5.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v5.define.PreparedStatementNullSetterInstrumentation
/*
* 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.v6.define;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.plugin.jdbc.PSSetterDefinitionOfJDBCInstrumentation;
/**
* @author kezhenxu94
*/
public class PreparedStatementIgnoredSetterInstrumentation extends PreparedStatementInstrumentation {
@Override
protected final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new PSSetterDefinitionOfJDBCInstrumentation(true)
};
}
}
......@@ -30,13 +30,13 @@ import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName
/**
* {@link PreparedStatementInstrumentation} define that the mysql-2.x plugin intercepts the following methods in the
* com.mysql.jdbc.JDBC42PreparedStatement, com.mysql.jdbc.PreparedStatement and
* com.mysql.jdbc.JDBC42PreparedStatement, com.mysql.jdbc.PreparedStatement and
* com.mysql.cj.jdbc.PreparedStatement class:
* 1. execute
* 2. executeQuery
* 3. executeUpdate
* 4. executeLargeUpdate
* 5. addBatch
* 1. execute
* 2. executeQuery
* 3. executeUpdate
* 4. executeLargeUpdate
* 5. addBatch
*
* @author zhangxin
*/
......@@ -49,7 +49,7 @@ public class PreparedStatementInstrumentation extends AbstractMysqlInstrumentati
return new ConstructorInterceptPoint[0];
}
@Override protected final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
@Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
......
/*
* 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.v6.define;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.plugin.jdbc.JDBCPreparedStatementNullSetterInstanceMethodsInterceptPoint;
/**
* @author kezhenxu94
*/
public class PreparedStatementNullSetterInstrumentation extends PreparedStatementInstrumentation {
@Override
protected final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new JDBCPreparedStatementNullSetterInstanceMethodsInterceptPoint()
};
}
}
/*
* 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.v6.define;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.plugin.jdbc.PSSetterDefinitionOfJDBCInstrumentation;
/**
* @author kezhenxu94
*/
public class PreparedStatementSetterInstrumentation extends PreparedStatementInstrumentation {
@Override
protected final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new PSSetterDefinitionOfJDBCInstrumentation(false)
};
}
}
......@@ -21,3 +21,6 @@ mysql-6.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v6.define.PreparedStatemen
mysql-6.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v6.define.StatementInstrumentation
mysql-6.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v6.define.CacheIpsInstrumentation
mysql-6.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v6.define.ConnectionImplCreateInstrumentation
mysql-6.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v6.define.PreparedStatementSetterInstrumentation
mysql-6.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v6.define.PreparedStatementIgnoredSetterInstrumentation
mysql-6.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v6.define.PreparedStatementNullSetterInstrumentation
/*
* 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.v8.define;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.plugin.jdbc.PSSetterDefinitionOfJDBCInstrumentation;
/**
* @author kezhenxu94
*/
public class PreparedStatementIgnoredSetterInstrumentation extends PreparedStatementInstrumentation {
@Override
protected final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new PSSetterDefinitionOfJDBCInstrumentation(true)
};
}
}
......@@ -40,7 +40,7 @@ public class PreparedStatementInstrumentation extends AbstractMysqlInstrumentati
return new ConstructorInterceptPoint[0];
}
@Override protected final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
@Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
......
/*
* 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.v8.define;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.plugin.jdbc.JDBCPreparedStatementNullSetterInstanceMethodsInterceptPoint;
/**
* @author kezhenxu94
*/
public class PreparedStatementNullSetterInstrumentation extends PreparedStatementInstrumentation {
@Override
protected final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new JDBCPreparedStatementNullSetterInstanceMethodsInterceptPoint()
};
}
}
/*
* 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.v8.define;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.plugin.jdbc.PSSetterDefinitionOfJDBCInstrumentation;
/**
* @author kezhenxu94
*/
public class PreparedStatementSetterInstrumentation extends PreparedStatementInstrumentation {
@Override
protected final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new PSSetterDefinitionOfJDBCInstrumentation(false)
};
}
}
......@@ -19,3 +19,6 @@ mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.ConnectionInstru
mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.CallableInstrumentation
mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.PreparedStatementInstrumentation
mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.StatementInstrumentation
mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.PreparedStatementSetterInstrumentation
mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.PreparedStatementNullSetterInstrumentation
mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.PreparedStatementIgnoredSetterInstrumentation
......@@ -18,6 +18,8 @@
package org.apache.skywalking.apm.plugin.jdbc.mysql;
import org.apache.skywalking.apm.agent.core.context.tag.StringTag;
/**
* @author: dingshaocheng
*/
......@@ -29,4 +31,6 @@ public class Constants {
public static final String SET_CATALOG_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.mysql.SetCatalogInterceptor";
public static final String STATEMENT_EXECUTE_METHODS_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.mysql.StatementExecuteMethodsInterceptor";
public static final String DRIVER_CONNECT_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.mysql.DriverConnectInterceptor";
public static final StringTag SQL_PARAMETERS = new StringTag("db.sql.parameters");
}
......@@ -18,6 +18,7 @@
package org.apache.skywalking.apm.plugin.jdbc.mysql;
import org.apache.skywalking.apm.agent.core.conf.Config;
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;
......@@ -30,6 +31,8 @@ import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import java.lang.reflect.Method;
import static org.apache.skywalking.apm.plugin.jdbc.mysql.Constants.SQL_PARAMETERS;
public class PreparedStatementExecuteMethodsInterceptor implements InstanceMethodsAroundInterceptor {
@Override
......@@ -52,6 +55,19 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho
Tags.DB_STATEMENT.set(span, cacheObject.getSql());
span.setComponent(connectInfo.getComponent());
if (Config.Plugin.MySQL.TRACE_SQL_PARAMETERS) {
final Object[] parameters = cacheObject.getParameters();
if (parameters != null && parameters.length > 0) {
int maxIndex = cacheObject.getMaxIndex();
String parameterString = buildParameterString(parameters, maxIndex);
int sqlParametersMaxLength = Config.Plugin.MySQL.SQL_PARAMETERS_MAX_LENGTH;
if (sqlParametersMaxLength > 0 && parameterString.length() > sqlParametersMaxLength) {
parameterString = parameterString.substring(0, sqlParametersMaxLength) + "...";
}
SQL_PARAMETERS.set(span, parameterString);
}
}
SpanLayer.asDB(span);
}
}
......@@ -78,4 +94,19 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho
private String buildOperationName(ConnectionInfo connectionInfo, String methodName, String statementName) {
return connectionInfo.getDBType() + "/JDBI/" + statementName + "/" + methodName;
}
private String buildParameterString(Object[] parameters, int maxIndex) {
String parameterString = "[";
boolean first = true;
for (int i = 0; i < maxIndex; i++) {
Object parameter = parameters[i];
if (!first) {
parameterString += ",";
}
parameterString += parameter;
first = false;
}
parameterString += "]";
return parameterString;
}
}
/*
* 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;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
/**
* Benchmark Mode Cnt Score Error Units
* ArbitrarySetTest.array thrpt 10 2360.500 ± 138.279 ops/ms
* ArbitrarySetTest.arrayList thrpt 10 1080.005 ± 225.897 ops/ms
* ArbitrarySetTest.linkedList thrpt 10 188.007 ± 11.739 ops/ms
* ArbitrarySetTest.treeMap thrpt 10 214.384 ± 27.816 ops/ms
*
* @author kezhenxu94
*/
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Thread)
@Fork(2)
@Warmup(iterations = 4)
@Measurement(iterations = 5)
public class ArbitrarySetTest {
private static final Object PLACEHOLDER = new Object();
@Benchmark
public void arrayList() {
ArrayList<Object> list = new ArrayList<Object>(Collections.nCopies(20, PLACEHOLDER));
for (int i = 0; i < 100; i++) {
int oldSize = list.size();
if (i >= oldSize) {
int newSize = Math.max(oldSize * 2, i);
list.addAll(oldSize, Collections.nCopies(newSize - oldSize, PLACEHOLDER));
}
list.set(i, i);
}
}
@Benchmark
public void linkedList() {
LinkedList<Object> list = new LinkedList<Object>(Collections.nCopies(20, PLACEHOLDER));
for (int i = 0; i < 100; i++) {
int oldSize = list.size();
if (i >= oldSize) {
int newSize = Math.max(oldSize * 2, i);
list.addAll(oldSize, Collections.nCopies(newSize - oldSize, PLACEHOLDER));
}
list.set(i, i);
}
}
@Benchmark
public void array() {
Object[] array = new Object[20];
Arrays.fill(array, PLACEHOLDER);
for (int i = 1; i <= 100; i++) {
int length = array.length;
if (i >= length) {
int newSize = Math.max(i, length * 2);
Object[] newArray = new Object[newSize];
System.arraycopy(array, 0, newArray, 0, length);
Arrays.fill(newArray, length, newSize, PLACEHOLDER);
array = newArray;
}
array[i] = i;
}
}
@Benchmark
public void treeMap() {
final Map<Integer, Object> treeMap = new TreeMap<Integer, Object>();
for (int i = 0; i < 100; i++) {
treeMap.put(i, i);
}
}
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public static void main(String[] args) throws RunnerException {
Options options = new OptionsBuilder().include(ArbitrarySetTest.class.getSimpleName()).build();
new Runner(options).run();
}
}
......@@ -82,11 +82,13 @@ property key | Description | Default |
`plugin.elasticsearch.trace_dsl`|If true, trace all the DSL(Domain Specific Language) in ElasticSearch access, default is false.|`false`|
`plugin.springmvc.use_qualified_name_as_endpoint_name`|If true, the fully qualified method name will be used as the endpoint name instead of the request URL, default is false.|`false`|
`plugin.toolit.use_qualified_name_as_operation_name`|If true, the fully qualified method name will be used as the operation name instead of the given operation name, default is false.|`false`|
`plugin.mysql.trace_sql_parameters`|If set to true, the parameters of the sql (typically `java.sql.PreparedStatement`) would be collected.|`false`|
`plugin.mysql.sql_parameters_max_length`|If set to positive number, the `db.sql.parameters` would be truncated to this length, otherwise it would be completely saved, which may cause performance problem.|`512`|
`plugin.solrj.trace_statement`|If true, trace all the query parameters(include deleteByIds and deleteByQuery) in Solr query request, default is false.|`false`|
`plugin.solrj.trace_ops_params`|If true, trace all the operation parameters in Solr request, default is false.|`false`|
## Optional Plugins
Java agent plugins are all pluggable. Optional plugins could be provided in `optional-plugins` folder under agent or 3rd party repositores.
Java agent plugins are all pluggable. Optional plugins could be provided in `optional-plugins` folder under agent or 3rd party repositories.
For using these plugins, you need to put the target plugin jar file into `/plugins`.
Now, we have the following known optional plugins.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册