mirror of
https://github.com/wahyd4/pinpoint.git
synced 2026-08-20 18:25:55 +10:00
#1224 Apply SQL bind values tracing configuration to db interceptors
This commit is contained in:
+121
-106
@@ -1,106 +1,121 @@
|
||||
/*
|
||||
* Copyright 2015 NAVER Corp.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.navercorp.pinpoint.profiler.modifier.db.oracle;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.ByteCodeInstrumentor;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentException;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.NotFoundInstrumentException;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.Scope;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.Interceptor;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.tracevalue.BindValueTraceValue;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.tracevalue.ParsingResultTraceValue;
|
||||
import com.navercorp.pinpoint.profiler.interceptor.ScopeDelegateStaticInterceptor;
|
||||
import com.navercorp.pinpoint.profiler.modifier.AbstractModifierDelegate;
|
||||
import com.navercorp.pinpoint.profiler.modifier.db.interceptor.PreparedStatementBindVariableInterceptor;
|
||||
import com.navercorp.pinpoint.profiler.modifier.db.interceptor.PreparedStatementExecuteQueryInterceptor;
|
||||
import com.navercorp.pinpoint.profiler.util.JavaAssistUtils;
|
||||
import com.navercorp.pinpoint.profiler.util.PreparedStatementUtils;
|
||||
|
||||
/**
|
||||
* @author HyunGil Jeong
|
||||
*/
|
||||
public class OraclePreparedStatementModifierDelegate extends AbstractModifierDelegate {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
public OraclePreparedStatementModifierDelegate(ByteCodeInstrumentor byteCodeInstrumentor) {
|
||||
super(byteCodeInstrumentor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Modifying. {}", className);
|
||||
}
|
||||
try {
|
||||
InstrumentClass preparedStatement = byteCodeInstrumentor.getClass(classLoader, className, classFileBuffer);
|
||||
|
||||
Interceptor execute = new PreparedStatementExecuteQueryInterceptor();
|
||||
preparedStatement.addScopeInterceptor("execute", null, execute, OracleScope.SCOPE_NAME);
|
||||
Interceptor executeQuery = new PreparedStatementExecuteQueryInterceptor();
|
||||
preparedStatement.addScopeInterceptor("executeQuery", null, executeQuery, OracleScope.SCOPE_NAME);
|
||||
Interceptor executeUpdate = new PreparedStatementExecuteQueryInterceptor();
|
||||
preparedStatement.addScopeInterceptor("executeUpdate", null, executeUpdate, OracleScope.SCOPE_NAME);
|
||||
|
||||
preparedStatement.addTraceValue(DatabaseInfoTraceValue.class);
|
||||
preparedStatement.addTraceValue(ParsingResultTraceValue.class);
|
||||
preparedStatement.addTraceValue(BindValueTraceValue.class, "new java.util.HashMap();");
|
||||
bindVariableIntercept(preparedStatement, classLoader, protectedDomain);
|
||||
|
||||
return preparedStatement.toBytecode();
|
||||
} catch (InstrumentException e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void bindVariableIntercept(InstrumentClass preparedStatement, ClassLoader classLoader, ProtectionDomain protectedDomain) throws InstrumentException {
|
||||
List<Method> bindMethod = PreparedStatementUtils.findBindVariableSetMethod();
|
||||
final Scope scope = byteCodeInstrumentor.getScope(OracleScope.SCOPE_NAME);
|
||||
Interceptor interceptor = new ScopeDelegateStaticInterceptor(new PreparedStatementBindVariableInterceptor(), scope);
|
||||
int interceptorId = -1;
|
||||
for (Method method : bindMethod) {
|
||||
String methodName = method.getName();
|
||||
String[] parameterType = JavaAssistUtils.getParameterType(method.getParameterTypes());
|
||||
try {
|
||||
if (interceptorId == -1) {
|
||||
interceptorId = preparedStatement.addInterceptor(methodName, parameterType, interceptor);
|
||||
} else {
|
||||
preparedStatement.reuseInterceptor(methodName, parameterType, interceptorId);
|
||||
}
|
||||
} catch (NotFoundInstrumentException e) {
|
||||
// Cannot find bind variable setter method. This is not an error. logging will be enough.
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("bindVariable api not found. method:{} param:{} Cause:{}", methodName, Arrays.toString(parameterType), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2015 NAVER Corp.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.navercorp.pinpoint.profiler.modifier.db;
|
||||
|
||||
import com.navercorp.pinpoint.bootstrap.Agent;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.*;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.Interceptor;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.tracevalue.BindValueTraceValue;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.tracevalue.ParsingResultTraceValue;
|
||||
import com.navercorp.pinpoint.profiler.interceptor.ScopeDelegateStaticInterceptor;
|
||||
import com.navercorp.pinpoint.profiler.modifier.AbstractModifier;
|
||||
import com.navercorp.pinpoint.profiler.modifier.db.interceptor.PreparedStatementBindVariableInterceptor;
|
||||
import com.navercorp.pinpoint.profiler.modifier.db.interceptor.PreparedStatementExecuteQueryInterceptor;
|
||||
import com.navercorp.pinpoint.profiler.util.JavaAssistUtils;
|
||||
import com.navercorp.pinpoint.profiler.util.PreparedStatementUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author HyunGil Jeong
|
||||
*/
|
||||
public abstract class AbstractPreparedStatementModifier extends AbstractModifier {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final boolean traceBindValue;
|
||||
|
||||
public AbstractPreparedStatementModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent, boolean traceBindValue) {
|
||||
super(byteCodeInstrumentor, agent);
|
||||
this.traceBindValue = traceBindValue;
|
||||
}
|
||||
|
||||
protected abstract String getScope();
|
||||
|
||||
@Override
|
||||
public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Modifying. {}", javassistClassName);
|
||||
}
|
||||
try {
|
||||
InstrumentClass preparedStatementClass = byteCodeInstrumentor.getClass(classLoader, javassistClassName, classFileBuffer);
|
||||
String scope = this.getScope();
|
||||
|
||||
for (String methodToIntercept : getMethodsToIntercept()) {
|
||||
Interceptor executeMethodInterceptor = new PreparedStatementExecuteQueryInterceptor();
|
||||
preparedStatementClass.addScopeInterceptor(methodToIntercept, null, executeMethodInterceptor, scope);
|
||||
}
|
||||
|
||||
addTraceValues(preparedStatementClass);
|
||||
|
||||
if (this.traceBindValue) {
|
||||
bindVariableInterceptors(preparedStatementClass);
|
||||
}
|
||||
|
||||
return preparedStatementClass.toBytecode();
|
||||
} catch (InstrumentException e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected List<String> getMethodsToIntercept() {
|
||||
return Arrays.asList("execute", "executeQuery", "executeUpdate");
|
||||
}
|
||||
|
||||
protected void addTraceValues(InstrumentClass preparedStatementClass) throws InstrumentException {
|
||||
preparedStatementClass.addTraceValue(DatabaseInfoTraceValue.class);
|
||||
preparedStatementClass.addTraceValue(ParsingResultTraceValue.class);
|
||||
preparedStatementClass.addTraceValue(BindValueTraceValue.class, "new java.util.HashMap();");
|
||||
}
|
||||
|
||||
protected List<Method> getBindMethods() {
|
||||
return PreparedStatementUtils.findBindVariableSetMethod();
|
||||
}
|
||||
|
||||
protected void bindVariableInterceptors(InstrumentClass preparedStatement) throws InstrumentException {
|
||||
List<Method> bindMethods = getBindMethods();
|
||||
final Scope scope = super.byteCodeInstrumentor.getScope(this.getScope());
|
||||
Interceptor interceptor = new ScopeDelegateStaticInterceptor(new PreparedStatementBindVariableInterceptor(), scope);
|
||||
int interceptorId = -1;
|
||||
for (Method method : bindMethods) {
|
||||
String methodName = method.getName();
|
||||
String[] parameterType = JavaAssistUtils.getParameterType(method.getParameterTypes());
|
||||
try {
|
||||
if (interceptorId == -1) {
|
||||
interceptorId = preparedStatement.addInterceptor(methodName, parameterType, interceptor);
|
||||
} else {
|
||||
preparedStatement.reuseInterceptor(methodName, parameterType, interceptorId);
|
||||
}
|
||||
} catch (NotFoundInstrumentException e) {
|
||||
// Cannot find bind variable setter method. This is not an error. Just some log will be enough.
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("bindVariable api not found. method:{} param:{} Cause:{}", methodName, Arrays.toString(parameterType), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+7
-77
@@ -16,97 +16,27 @@
|
||||
|
||||
package com.navercorp.pinpoint.profiler.modifier.db.cubrid;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.navercorp.pinpoint.bootstrap.Agent;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.ByteCodeInstrumentor;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentException;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.NotFoundInstrumentException;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.Scope;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.Interceptor;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.tracevalue.BindValueTraceValue;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.tracevalue.ParsingResultTraceValue;
|
||||
import com.navercorp.pinpoint.profiler.interceptor.ScopeDelegateStaticInterceptor;
|
||||
import com.navercorp.pinpoint.profiler.modifier.AbstractModifier;
|
||||
import com.navercorp.pinpoint.profiler.modifier.db.interceptor.*;
|
||||
import com.navercorp.pinpoint.profiler.util.JavaAssistUtils;
|
||||
import com.navercorp.pinpoint.profiler.util.PreparedStatementUtils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import com.navercorp.pinpoint.profiler.modifier.db.AbstractPreparedStatementModifier;
|
||||
|
||||
/**
|
||||
* @author emeroad
|
||||
*/
|
||||
public class CubridPreparedStatementModifier extends AbstractModifier {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
public class CubridPreparedStatementModifier extends AbstractPreparedStatementModifier {
|
||||
|
||||
public CubridPreparedStatementModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) {
|
||||
super(byteCodeInstrumentor, agent);
|
||||
super(byteCodeInstrumentor, agent, agent.getProfilerConfig().isJdbcProfileCubridSqlBindValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTargetClass() {
|
||||
return "cubrid/jdbc/driver/CUBRIDPreparedStatement";
|
||||
}
|
||||
|
||||
public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Modifing. {}", javassistClassName);
|
||||
}
|
||||
try {
|
||||
InstrumentClass preparedStatementClass = byteCodeInstrumentor.getClass(classLoader, javassistClassName, classFileBuffer);
|
||||
|
||||
Interceptor executeInterceptor = new PreparedStatementExecuteQueryInterceptor();
|
||||
preparedStatementClass.addScopeInterceptor("execute", null, executeInterceptor, CubridScope.SCOPE_NAME);
|
||||
|
||||
Interceptor executeQueryInterceptor = new PreparedStatementExecuteQueryInterceptor();
|
||||
preparedStatementClass.addScopeInterceptor("executeQuery", null, executeQueryInterceptor, CubridScope.SCOPE_NAME);
|
||||
|
||||
Interceptor executeUpdateInterceptor = new PreparedStatementExecuteQueryInterceptor();
|
||||
preparedStatementClass.addScopeInterceptor("executeUpdate", null, executeUpdateInterceptor, CubridScope.SCOPE_NAME);
|
||||
|
||||
preparedStatementClass.addTraceValue(DatabaseInfoTraceValue.class);
|
||||
preparedStatementClass.addTraceValue(ParsingResultTraceValue.class);
|
||||
preparedStatementClass.addTraceValue(BindValueTraceValue.class, "new java.util.HashMap();");
|
||||
|
||||
bindVariableIntercept(preparedStatementClass, classLoader, protectedDomain);
|
||||
|
||||
return preparedStatementClass.toBytecode();
|
||||
} catch (InstrumentException e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
protected String getScope() {
|
||||
return CubridScope.SCOPE_NAME;
|
||||
}
|
||||
|
||||
private void bindVariableIntercept(InstrumentClass preparedStatement, ClassLoader classLoader, ProtectionDomain protectedDomain) throws InstrumentException {
|
||||
List<Method> bindMethod = PreparedStatementUtils.findBindVariableSetMethod();
|
||||
final Scope scope = byteCodeInstrumentor.getScope(CubridScope.SCOPE_NAME);
|
||||
Interceptor interceptor = new ScopeDelegateStaticInterceptor(new PreparedStatementBindVariableInterceptor(), scope);
|
||||
int interceptorId = -1;
|
||||
for (Method method : bindMethod) {
|
||||
String methodName = method.getName();
|
||||
String[] parameterType = JavaAssistUtils.getParameterType(method.getParameterTypes());
|
||||
try {
|
||||
if (interceptorId == -1) {
|
||||
interceptorId = preparedStatement.addInterceptor(methodName, parameterType, interceptor);
|
||||
} else {
|
||||
preparedStatement.reuseInterceptor(methodName, parameterType, interceptorId);
|
||||
}
|
||||
} catch (NotFoundInstrumentException e) {
|
||||
// Cannot find bind variable setter method. This is not an error. Just some log will be enough.
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("bindVariable api not found. method:{} param:{} Cause:{}", methodName, Arrays.toString(parameterType), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-81
@@ -18,97 +18,23 @@ package com.navercorp.pinpoint.profiler.modifier.db.jtds;
|
||||
|
||||
import com.navercorp.pinpoint.bootstrap.Agent;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.ByteCodeInstrumentor;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentException;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.NotFoundInstrumentException;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.Scope;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.Interceptor;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.tracevalue.BindValueTraceValue;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.tracevalue.ParsingResultTraceValue;
|
||||
import com.navercorp.pinpoint.profiler.interceptor.ScopeDelegateStaticInterceptor;
|
||||
import com.navercorp.pinpoint.profiler.modifier.AbstractModifier;
|
||||
import com.navercorp.pinpoint.profiler.modifier.db.interceptor.PreparedStatementBindVariableInterceptor;
|
||||
import com.navercorp.pinpoint.profiler.modifier.db.interceptor.PreparedStatementExecuteQueryInterceptor;
|
||||
import com.navercorp.pinpoint.profiler.util.JavaAssistUtils;
|
||||
import com.navercorp.pinpoint.profiler.util.PreparedStatementUtils;
|
||||
import com.navercorp.pinpoint.profiler.modifier.db.AbstractPreparedStatementModifier;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class JtdsPreparedStatementModifier extends AbstractModifier {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
public class JtdsPreparedStatementModifier extends AbstractPreparedStatementModifier {
|
||||
|
||||
public JtdsPreparedStatementModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) {
|
||||
super(byteCodeInstrumentor, agent);
|
||||
super(byteCodeInstrumentor, agent, agent.getProfilerConfig().isJdbcProfileJtdsSqlBindValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTargetClass() {
|
||||
return "net/sourceforge/jtds/jdbc/JtdsPreparedStatement";
|
||||
}
|
||||
|
||||
|
||||
public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Modifing. {}", javassistClassName);
|
||||
}
|
||||
try {
|
||||
InstrumentClass preparedStatementClass = byteCodeInstrumentor.getClass(classLoader, javassistClassName, classFileBuffer);
|
||||
|
||||
Interceptor executeInterceptor = new PreparedStatementExecuteQueryInterceptor();
|
||||
preparedStatementClass.addScopeInterceptor("execute", null, executeInterceptor, JtdsScope.SCOPE_NAME);
|
||||
|
||||
Interceptor executeQueryInterceptor = new PreparedStatementExecuteQueryInterceptor();
|
||||
preparedStatementClass.addScopeInterceptor("executeQuery", null, executeQueryInterceptor, JtdsScope.SCOPE_NAME);
|
||||
|
||||
Interceptor executeUpdateInterceptor = new PreparedStatementExecuteQueryInterceptor();
|
||||
preparedStatementClass.addScopeInterceptor("executeUpdate", null, executeUpdateInterceptor, JtdsScope.SCOPE_NAME);
|
||||
|
||||
preparedStatementClass.addTraceValue(DatabaseInfoTraceValue.class);
|
||||
preparedStatementClass.addTraceValue(ParsingResultTraceValue.class);
|
||||
preparedStatementClass.addTraceValue(BindValueTraceValue.class, "new java.util.HashMap();");
|
||||
|
||||
bindVariableIntercept(preparedStatementClass, classLoader, protectedDomain);
|
||||
|
||||
return preparedStatementClass.toBytecode();
|
||||
} catch (InstrumentException e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
protected String getScope() {
|
||||
return JtdsScope.SCOPE_NAME;
|
||||
}
|
||||
|
||||
private void bindVariableIntercept(InstrumentClass preparedStatement, ClassLoader classLoader, ProtectionDomain protectedDomain) throws InstrumentException {
|
||||
List<Method> bindMethod = PreparedStatementUtils.findBindVariableSetMethod();
|
||||
final Scope scope = byteCodeInstrumentor.getScope(JtdsScope.SCOPE_NAME);
|
||||
Interceptor interceptor = new ScopeDelegateStaticInterceptor(new PreparedStatementBindVariableInterceptor(), scope);
|
||||
int interceptorId = -1;
|
||||
for (Method method : bindMethod) {
|
||||
String methodName = method.getName();
|
||||
String[] parameterType = JavaAssistUtils.getParameterType(method.getParameterTypes());
|
||||
try {
|
||||
if (interceptorId == -1) {
|
||||
interceptorId = preparedStatement.addInterceptor(methodName, parameterType, interceptor);
|
||||
} else {
|
||||
preparedStatement.reuseInterceptor(methodName, parameterType, interceptorId);
|
||||
}
|
||||
} catch (NotFoundInstrumentException e) {
|
||||
// Cannot find bind variable setter method. This is not an error. logging will be enough.
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("bindVariable api not found. method:{} param:{} Cause:{}", methodName, Arrays.toString(parameterType), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+24
-59
@@ -20,84 +20,49 @@ import com.navercorp.pinpoint.bootstrap.Agent;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.ByteCodeInstrumentor;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentException;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.NotFoundInstrumentException;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.Scope;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.Type;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.Interceptor;
|
||||
import com.navercorp.pinpoint.profiler.interceptor.ScopeDelegateStaticInterceptor;
|
||||
import com.navercorp.pinpoint.profiler.modifier.AbstractModifier;
|
||||
import com.navercorp.pinpoint.profiler.modifier.db.interceptor.PreparedStatementBindVariableInterceptor;
|
||||
import com.navercorp.pinpoint.profiler.modifier.db.AbstractPreparedStatementModifier;
|
||||
import com.navercorp.pinpoint.profiler.util.*;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author emeroad
|
||||
*/
|
||||
public class MySQLPreparedStatementJDBC4Modifier extends AbstractModifier {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
public class MySQLPreparedStatementJDBC4Modifier extends AbstractPreparedStatementModifier {
|
||||
|
||||
public MySQLPreparedStatementJDBC4Modifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) {
|
||||
super(byteCodeInstrumentor, agent);
|
||||
super(byteCodeInstrumentor, agent, agent.getProfilerConfig().isJdbcProfileMySqlSqlBindValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTargetClass() {
|
||||
return "com/mysql/jdbc/JDBC4PreparedStatement";
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectedDomain, byte[] classFileBuffer) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Modifing. {}", className);
|
||||
}
|
||||
try {
|
||||
InstrumentClass preparedStatement = byteCodeInstrumentor.getClass(classLoader, className, classFileBuffer);
|
||||
|
||||
bindVariableIntercept(preparedStatement, classLoader, protectedDomain);
|
||||
|
||||
return preparedStatement.toBytecode();
|
||||
} catch (InstrumentException e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
protected String getScope() {
|
||||
return MYSQLScope.SCOPE_NAME;
|
||||
}
|
||||
|
||||
private void bindVariableIntercept(InstrumentClass preparedStatement, ClassLoader classLoader, ProtectionDomain protectedDomain) throws InstrumentException {
|
||||
// TODO Need to add parameter type to filter arguments
|
||||
// Cannot specify methods without parameter type information because each JDBC driver has different API.
|
||||
BindVariableFilter exclude = new IncludeBindVariableFilter(new String[]{"setRowId", "setNClob", "setSQLXML"});
|
||||
List<Method> bindMethod = PreparedStatementUtils.findBindVariableSetMethod(exclude);
|
||||
|
||||
// TODO Do we have to utilize this logic?
|
||||
// It would be better to create util api in bci package which adds interceptors to multiple methods.
|
||||
final Scope scope = byteCodeInstrumentor.getScope(MYSQLScope.SCOPE_NAME);
|
||||
Interceptor interceptor = new ScopeDelegateStaticInterceptor(new PreparedStatementBindVariableInterceptor(), scope);
|
||||
int interceptorId = -1;
|
||||
for (Method method : bindMethod) {
|
||||
String methodName = method.getName();
|
||||
String[] parameterType = JavaAssistUtils.getParameterType(method.getParameterTypes());
|
||||
try {
|
||||
if (interceptorId == -1) {
|
||||
interceptorId = preparedStatement.addInterceptor(methodName, parameterType, interceptor, Type.after);
|
||||
} else {
|
||||
preparedStatement.reuseInterceptor(methodName, parameterType, interceptorId, Type.after);
|
||||
}
|
||||
} catch (NotFoundInstrumentException e) {
|
||||
// Cannot find bind variable setter method. This is not an error. logging will be enough.
|
||||
// Did not log stack trace intentionally
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("bindVariable api not found. method:{} param:{} Cause:{}", methodName, Arrays.toString(parameterType), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected List<String> getMethodsToIntercept() {
|
||||
// return nothing (taken care of in the parent class)
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addTraceValues(InstrumentClass preparedStatementClass) throws InstrumentException {
|
||||
// do nothing (taken care of in the parent class)
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Method> getBindMethods() {
|
||||
BindVariableFilter excludedMethods = new IncludeBindVariableFilter(new String[]{"setRowId", "setNClob", "setSQLXML"});
|
||||
return PreparedStatementUtils.findBindVariableSetMethod(excludedMethods);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+7
-83
@@ -18,101 +18,25 @@ package com.navercorp.pinpoint.profiler.modifier.db.mysql;
|
||||
|
||||
import com.navercorp.pinpoint.bootstrap.Agent;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.ByteCodeInstrumentor;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentClass;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.InstrumentException;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.NotFoundInstrumentException;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.Scope;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.Interceptor;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.tracevalue.BindValueTraceValue;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.tracevalue.DatabaseInfoTraceValue;
|
||||
import com.navercorp.pinpoint.bootstrap.interceptor.tracevalue.ParsingResultTraceValue;
|
||||
import com.navercorp.pinpoint.profiler.interceptor.ScopeDelegateStaticInterceptor;
|
||||
import com.navercorp.pinpoint.profiler.modifier.AbstractModifier;
|
||||
import com.navercorp.pinpoint.profiler.modifier.db.interceptor.*;
|
||||
import com.navercorp.pinpoint.profiler.util.ExcludeBindVariableFilter;
|
||||
import com.navercorp.pinpoint.profiler.util.JavaAssistUtils;
|
||||
import com.navercorp.pinpoint.profiler.util.PreparedStatementUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import com.navercorp.pinpoint.profiler.modifier.db.AbstractPreparedStatementModifier;
|
||||
|
||||
/**
|
||||
* @author emeroad
|
||||
*/
|
||||
public class MySQLPreparedStatementModifier extends AbstractModifier {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
public class MySQLPreparedStatementModifier extends AbstractPreparedStatementModifier {
|
||||
|
||||
public MySQLPreparedStatementModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) {
|
||||
super(byteCodeInstrumentor, agent);
|
||||
super(byteCodeInstrumentor, agent, agent.getProfilerConfig().isJdbcProfileMySqlSqlBindValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTargetClass() {
|
||||
return "com/mysql/jdbc/PreparedStatement";
|
||||
}
|
||||
|
||||
public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Modifing. {}", javassistClassName);
|
||||
}
|
||||
|
||||
try {
|
||||
InstrumentClass preparedStatement = byteCodeInstrumentor.getClass(classLoader, javassistClassName, classFileBuffer);
|
||||
|
||||
Interceptor execute = new PreparedStatementExecuteQueryInterceptor();
|
||||
preparedStatement.addScopeInterceptor("execute", null, execute, MYSQLScope.SCOPE_NAME);
|
||||
|
||||
Interceptor executeQuery = new PreparedStatementExecuteQueryInterceptor();
|
||||
preparedStatement.addScopeInterceptor("executeQuery", null, executeQuery, MYSQLScope.SCOPE_NAME);
|
||||
|
||||
Interceptor executeUpdate = new PreparedStatementExecuteQueryInterceptor();
|
||||
preparedStatement.addScopeInterceptor("executeUpdate", null, executeUpdate, MYSQLScope.SCOPE_NAME);
|
||||
|
||||
preparedStatement.addTraceValue(DatabaseInfoTraceValue.class);
|
||||
preparedStatement.addTraceValue(ParsingResultTraceValue.class);
|
||||
|
||||
preparedStatement.addTraceValue(BindValueTraceValue.class, "new java.util.HashMap();");
|
||||
bindVariableIntercept(preparedStatement, classLoader, protectedDomain);
|
||||
|
||||
return preparedStatement.toBytecode();
|
||||
} catch (InstrumentException e) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("{} modify fail. Cause:{}", this.getClass().getSimpleName(), e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
protected String getScope() {
|
||||
return MYSQLScope.SCOPE_NAME;
|
||||
}
|
||||
|
||||
private void bindVariableIntercept(InstrumentClass preparedStatement, ClassLoader classLoader, ProtectionDomain protectedDomain) throws InstrumentException {
|
||||
ExcludeBindVariableFilter exclude = new ExcludeBindVariableFilter(new String[]{"setRowId", "setNClob", "setSQLXML"});
|
||||
List<Method> bindMethod = PreparedStatementUtils.findBindVariableSetMethod(exclude);
|
||||
|
||||
final Scope scope = byteCodeInstrumentor.getScope(MYSQLScope.SCOPE_NAME);
|
||||
Interceptor interceptor = new ScopeDelegateStaticInterceptor(new PreparedStatementBindVariableInterceptor(), scope);
|
||||
int interceptorId = -1;
|
||||
for (Method method : bindMethod) {
|
||||
String methodName = method.getName();
|
||||
String[] parameterType = JavaAssistUtils.getParameterType(method.getParameterTypes());
|
||||
try {
|
||||
if (interceptorId == -1) {
|
||||
interceptorId = preparedStatement.addInterceptor(methodName, parameterType, interceptor);
|
||||
} else {
|
||||
preparedStatement.reuseInterceptor(methodName, parameterType, interceptorId);
|
||||
}
|
||||
} catch (NotFoundInstrumentException e) {
|
||||
// Cannot find bind variable setter method. This is not an error. logging will be enough.
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("bindVariable api not found. method:{} param:{} Cause:{}", methodName, Arrays.toString(parameterType), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+9
-8
@@ -20,8 +20,7 @@ import java.security.ProtectionDomain;
|
||||
|
||||
import com.navercorp.pinpoint.bootstrap.Agent;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.ByteCodeInstrumentor;
|
||||
import com.navercorp.pinpoint.profiler.modifier.AbstractModifier;
|
||||
import com.navercorp.pinpoint.profiler.modifier.ModifierDelegate;
|
||||
import com.navercorp.pinpoint.profiler.modifier.db.AbstractPreparedStatementModifier;
|
||||
|
||||
/**
|
||||
* For ojdbc library without OraclePreparedStatementWrapper.
|
||||
@@ -29,13 +28,10 @@ import com.navercorp.pinpoint.profiler.modifier.ModifierDelegate;
|
||||
*
|
||||
* @author HyunGil Jeong
|
||||
*/
|
||||
public class OraclePreparedStatementModifier extends AbstractModifier {
|
||||
|
||||
private final ModifierDelegate delegate;
|
||||
public class OraclePreparedStatementModifier extends AbstractPreparedStatementModifier {
|
||||
|
||||
public OraclePreparedStatementModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) {
|
||||
super(byteCodeInstrumentor, agent);
|
||||
this.delegate = new OraclePreparedStatementModifierDelegate(byteCodeInstrumentor);
|
||||
super(byteCodeInstrumentor, agent, agent.getProfilerConfig().isJdbcProfileOracleSqlBindValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -43,13 +39,18 @@ public class OraclePreparedStatementModifier extends AbstractModifier {
|
||||
return OracleClassConstants.ORACLE_PREPARED_STATEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getScope() {
|
||||
return OracleScope.SCOPE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) {
|
||||
// Do not modify if wrapper exists
|
||||
if (byteCodeInstrumentor.findClass(classLoader, OracleClassConstants.ORACLE_PREPARED_STATEMENT_WRAPPER)) {
|
||||
return null;
|
||||
}
|
||||
return this.delegate.modify(classLoader, javassistClassName, protectedDomain, classFileBuffer);
|
||||
return super.modify(classLoader, javassistClassName, protectedDomain, classFileBuffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-11
@@ -16,32 +16,27 @@
|
||||
|
||||
package com.navercorp.pinpoint.profiler.modifier.db.oracle;
|
||||
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
import com.navercorp.pinpoint.bootstrap.Agent;
|
||||
import com.navercorp.pinpoint.bootstrap.instrument.ByteCodeInstrumentor;
|
||||
import com.navercorp.pinpoint.profiler.modifier.AbstractModifier;
|
||||
import com.navercorp.pinpoint.profiler.modifier.ModifierDelegate;
|
||||
import com.navercorp.pinpoint.profiler.modifier.db.AbstractPreparedStatementModifier;
|
||||
|
||||
/**
|
||||
* @author emeroad
|
||||
*/
|
||||
public class OraclePreparedStatementWrapperModifier extends AbstractModifier {
|
||||
|
||||
private final ModifierDelegate delegate;
|
||||
public class OraclePreparedStatementWrapperModifier extends AbstractPreparedStatementModifier {
|
||||
|
||||
public OraclePreparedStatementWrapperModifier(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent) {
|
||||
super(byteCodeInstrumentor, agent);
|
||||
this.delegate = new OraclePreparedStatementModifierDelegate(byteCodeInstrumentor);
|
||||
super(byteCodeInstrumentor, agent, agent.getProfilerConfig().isJdbcProfileOracleSqlBindValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTargetClass() {
|
||||
return OracleClassConstants.ORACLE_PREPARED_STATEMENT_WRAPPER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] modify(ClassLoader classLoader, String javassistClassName, ProtectionDomain protectedDomain, byte[] classFileBuffer) {
|
||||
return this.delegate.modify(classLoader, javassistClassName, protectedDomain, classFileBuffer);
|
||||
protected String getScope() {
|
||||
return OracleScope.SCOPE_NAME;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user