序
本文主要研究一下skywalking的mysql-plugin
skywalking-plugin.def
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/mysql-8.x-plugin/src/main/resources/skywalking-plugin.def
mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.ConnectionImplCreateInstrumentation
mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.ConnectionInstrumentation
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
- skywalking的mysql-plugin提供了ConnectionImplCreateInstrumentation、ConnectionInstrumentation、CallableInstrumentation、PreparedStatementInstrumentation、StatementInstrumentation、PreparedStatementSetterInstrumentation、PreparedStatementNullSetterInstrumentation、PreparedStatementIgnoredSetterInstrumentation这几个增强
AbstractMysqlInstrumentation
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/mysql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/v8/define/AbstractMysqlInstrumentation.java
public abstract class AbstractMysqlInstrumentation extends ClassEnhancePluginDefine {
@Override
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return null;
}
@Override
public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() {
return null;
}
@Override
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return null;
}
@Override
protected String[] witnessClasses() {
return new String[]{Constants.WITNESS_MYSQL_8X_CLASS};
}
}
- AbstractMysqlInstrumentation继承了ClassEnhancePluginDefine,其witnessClasses返回的是com.mysql.cj.interceptors.QueryInterceptor
ConnectionImplCreateInstrumentation
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/mysql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/v8/define/ConnectionImplCreateInstrumentation.java
public class ConnectionImplCreateInstrumentation extends AbstractMysqlInstrumentation {
private static final String JDBC_ENHANCE_CLASS = "com.mysql.cj.jdbc.ConnectionImpl";
private static final String CONNECT_METHOD = "getInstance";
@Override
public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() {
return new StaticMethodsInterceptPoint[] {
new StaticMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(CONNECT_METHOD);
}
@Override
public String getMethodsInterceptor() {
return "org.apache.skywalking.apm.plugin.jdbc.mysql.v8.ConnectionCreateInterceptor";
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override
protected ClassMatch enhanceClass() {
return byName(JDBC_ENHANCE_CLASS);
}
}
- ConnectionImplCreateInstrumentation继承了AbstractMysqlInstrumentation;它使用org.apache.skywalking.apm.plugin.jdbc.mysql.v8.ConnectionCreateInterceptor增强了com.mysql.cj.jdbc.ConnectionImpl的getInstance方法
ConnectionCreateInterceptor
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/mysql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/v8/ConnectionCreateInterceptor.java
public class ConnectionCreateInterceptor implements StaticMethodsAroundInterceptor {
@Override
public void beforeMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes, MethodInterceptResult result) {
}
@Override
public Object afterMethod(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes, Object ret) {
if (ret instanceof EnhancedInstance) {
final HostInfo hostInfo = (HostInfo) allArguments[0];
ConnectionInfo connectionInfo = URLParser.parser(hostInfo.getDatabaseUrl());
((EnhancedInstance) ret).setSkyWalkingDynamicField(connectionInfo);
}
return ret;
}
@Override
public void handleMethodException(Class clazz, Method method, Object[] allArguments, Class<?>[] parameterTypes, Throwable t) {
}
}
- ConnectionCreateInterceptor实现了StaticMethodsAroundInterceptor接口,其afterMethod方法提取hostInfo解析为connectionInfo然后设置给ret的skyWalkingDynamicField
ConnectionInstrumentation
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/mysql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/v8/define/ConnectionInstrumentation.java
public class ConnectionInstrumentation extends AbstractMysqlInstrumentation {
@Override public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(org.apache.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_STATEMENT_METHOD_NAME);
}
@Override public String getMethodsInterceptor() {
return org.apache.skywalking.apm.plugin.jdbc.mysql.Constants.CREATE_PREPARED_STATEMENT_INTERCEPTOR;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(org.apache.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_CALL_METHOD_NAME);
}
@Override public String getMethodsInterceptor() {
return org.apache.skywalking.apm.plugin.jdbc.mysql.Constants.CREATE_CALLABLE_STATEMENT_INTERCEPTOR;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(org.apache.skywalking.apm.plugin.jdbc.define.Constants.CREATE_STATEMENT_METHOD_NAME).and(takesArguments(2));
}
@Override public String getMethodsInterceptor() {
return org.apache.skywalking.apm.plugin.jdbc.mysql.Constants.CREATE_STATEMENT_INTERCEPTOR;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override publi