order
This paper mainly studies MySQL plugin of skywalking
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's MySQL plugin provides several enhancements, such as 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 inherits ClassEnhancePluginDefine, and its switchclasses returns 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 inherits AbstractMysqlInstrumentation; it uses org.apache.skywalking.apm.plugin.jdbc.mysql.v8.ConnectionCreateInterceptor to enhance getInstance method of com.mysql.cj.jdbc.ConnectionImpl
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 implements StaticMethodsAroundInterceptor interface, whose afterMethod extracts hostInfo and resolves it to connectionInfo, and then sets it to skyWalkingDynamicField of ret
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 public ElementMatcher<MethodDescription> getMethodsMatcher() { return named(org.apache.skywalking.apm.plugin.jdbc.define.Constants.COMMIT_METHOD_NAME).or(named(org.apache.skywalking.apm.plugin.jdbc.define.Constants.ROLLBACK_METHOD_NAME)).or(named(org.apache.skywalking.apm.plugin.jdbc.define.Constants.CLOSE_METHOD_NAME)).or(named(org.apache.skywalking.apm.plugin.jdbc.define.Constants.RELEASE_SAVE_POINT_METHOD_NAME)); } @Override public String getMethodsInterceptor() { return org.apache.skywalking.apm.plugin.jdbc.define.Constants.SERVICE_METHOD_INTERCEPT_CLASS; } @Override public boolean isOverrideArgs() { return false; } }, new InstanceMethodsInterceptPoint() { @Override public ElementMatcher<MethodDescription> getMethodsMatcher() { return named("setCatalog"); } @Override public String getMethodsInterceptor() { return org.apache.skywalking.apm.plugin.jdbc.mysql.Constants.SET_CATALOG_INTERCEPTOR; } @Override public boolean isOverrideArgs() { return false; } } }; } @Override protected ClassMatch enhanceClass() { return byName("com.mysql.cj.jdbc.ConnectionImpl"); } }
- ConnectionInstrumentation inherits AbstractMysqlInstrumentation, which enhances the com.mysql.cj.jdbc.ConnectionImpl class; it uses org.apache.skywalking.apm.plugin.jdbc.mysql.CreatePreparedStatementInterceptor to enhance its prepareStatement method; it uses org.apache.skywalking.apm.plugin.jdbc.createcallablestatementinterceptor to enhance its prepareCall party Method; it uses org.apache.skywalking.apm.plugin.jdbc.mysql.CreateStatementInterceptor to enhance its createStatement method; it uses org.apache.skywalking.apm.plugin.jdbc.ConnectionServiceMethodInterceptor to enhance its commit, rollback, close, releaseSavepoint method; it uses org.apache.skywalking.apm.plugin.jdbc.setcatalogintercepor to enhance its setca Talog method
CreatePreparedStatementInterceptor
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/CreatePreparedStatementInterceptor.java
public class CreatePreparedStatementInterceptor implements InstanceMethodsAroundInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { } @Override 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(), (String)allArguments[0], "PreparedStatement")); } return ret; } @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) { } }
- CreatePreparedStatementInterceptor implements the instancemethods aroundinterceptor interface, whose afterMethod method will set statementenhanceinfo to ret's skyWalkingDynamicField
CreateCallableStatementInterceptor
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/CreateCallableStatementInterceptor.java
public class CreateCallableStatementInterceptor implements InstanceMethodsAroundInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { } @Override 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(), (String)allArguments[0], "CallableStatement")); } return ret; } @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) { } }
- CreateCallableStatementInterceptor implements the instancemethods aroundinterceptor interface, whose afterMethod method sets statementenhanceinfo to ret's skyWalkingDynamicField
CreateStatementInterceptor
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/CreateStatementInterceptor.java
public class CreateStatementInterceptor implements InstanceMethodsAroundInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { } @Override 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(), "", "Statement")); } return ret; } @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) { } }
- CreateStatementInterceptor implements the instancemethods aroundinterceptor interface, whose afterMethod method sets StatementEnhanceInfos to ret's skyWalkingDynamicField
ConnectionServiceMethodInterceptor
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/ConnectionServiceMethodInterceptor.java
public class ConnectionServiceMethodInterceptor implements InstanceMethodsAroundInterceptor { @Override public final void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { ConnectionInfo connectInfo = (ConnectionInfo)objInst.getSkyWalkingDynamicField(); if (connectInfo != null) { AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/Connection/" + method.getName(), connectInfo.getDatabasePeer()); Tags.DB_TYPE.set(span, "sql"); Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName()); Tags.DB_STATEMENT.set(span, ""); span.setComponent(connectInfo.getComponent()); SpanLayer.asDB(span); } } @Override public final Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Object ret) throws Throwable { ConnectionInfo connectInfo = (ConnectionInfo)objInst.getSkyWalkingDynamicField(); if (connectInfo != null) { ContextManager.stopSpan(); } return ret; } @Override public final void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) { ContextManager.activeSpan().errorOccurred().log(t); } }
- ConnectionServiceMethodInterceptor implements the instancemethods aroundinterceptor interface. Its beforeMethod method sets db'type, db'instance and db'statement. Its afterMethod method executes ContextManager.stopSpan() when connectInfo is not null, and its handleMethodException method executes contextmanager. Activespan(). Erroreoccurred(). Log (T)
SetCatalogInterceptor
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/SetCatalogInterceptor.java
public class SetCatalogInterceptor implements InstanceMethodsAroundInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { Object dynamicField = objInst.getSkyWalkingDynamicField(); if (dynamicField instanceof ConnectionInfo) { ((ConnectionInfo)dynamicField).setDatabaseName(String.valueOf(allArguments[0])); } } @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Object ret) throws Throwable { return ret; } @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) { } }
- SetCatalogInterceptor implements the instancemethods aroundinterceptor interface. Its beforeMethod method method sets the databaseName to the dynamicField of type ConnectionInfo
CallableInstrumentation
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/CallableInstrumentation.java
public class CallableInstrumentation extends AbstractMysqlInstrumentation { private static final String ENHANCE_CLASS = "com.mysql.cj.jdbc.CallableStatement"; private static final String SERVICE_METHOD_INTERCEPTOR = org.apache.skywalking.apm.plugin.jdbc.mysql.Constants.PREPARED_STATEMENT_EXECUTE_METHODS_INTERCEPTOR; @Override public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { return new ConstructorInterceptPoint[0]; } @Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { return new InstanceMethodsInterceptPoint[] { new InstanceMethodsInterceptPoint() { @Override public ElementMatcher<MethodDescription> getMethodsMatcher() { return named("execute") .or(named("executeQuery")) .or(named("executeUpdate")); } @Override public String getMethodsInterceptor() { return SERVICE_METHOD_INTERCEPTOR; } @Override public boolean isOverrideArgs() { return false; } } }; } @Override protected ClassMatch enhanceClass() { return byName(ENHANCE_CLASS); } }
- CallableInstrumentation inherits AbstractMysqlInstrumentation, which uses org.apache.skywalking.apm.plugin.jdbc.mysql.PreparedStatementExecuteMethodsInterceptor to enhance the execute, executeQuery, and executeUpdate methods of com.mysql.cj.jdbc.CallableStatement
PreparedStatementExecuteMethodsInterceptor
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/PreparedStatementExecuteMethodsInterceptor.java
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()); 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); } } @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; } 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; } }
- PreparedStatementExecuteMethodsInterceptor implements the InstanceMethodsAroundInterceptor interface, and its beforeMethod method sets db'type, db'instance, db'statement, sql'parameters (if config.plugin.mysql.trace'sql'parameters is true); its afterMethod executes ContextManager.stopSpan(); its handleMethodException() when cacheObject.getConnectionInfo() is not null The eption method executes contextmanager. Activespan(). Erroreoccurred(). Log (T) when cacheObject.getConnectionInfo() is not null
PreparedStatementInstrumentation
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/PreparedStatementInstrumentation.java
public class PreparedStatementInstrumentation extends AbstractMysqlInstrumentation { private static final String PREPARED_STATEMENT_CLASS_NAME = "com.mysql.cj.jdbc.ClientPreparedStatement"; private static final String PREPARED_STATEMENT_SERVER_SIDE_CLASS_NAME = "com.mysql.cj.jdbc.ServerPreparedStatement"; private static final String SERVICE_METHOD_INTERCEPTOR = Constants.PREPARED_STATEMENT_EXECUTE_METHODS_INTERCEPTOR; @Override public final ConstructorInterceptPoint[] getConstructorsInterceptPoints() { return new ConstructorInterceptPoint[0]; } @Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { return new InstanceMethodsInterceptPoint[] { new InstanceMethodsInterceptPoint() { @Override public ElementMatcher<MethodDescription> getMethodsMatcher() { return named("execute") .or(named("executeQuery")) .or(named("executeUpdate")) .or(named("executeLargeUpdate")); } @Override public String getMethodsInterceptor() { return SERVICE_METHOD_INTERCEPTOR; } @Override public boolean isOverrideArgs() { return false; } } }; } @Override protected ClassMatch enhanceClass() { return byMultiClassMatch(PREPARED_STATEMENT_CLASS_NAME, PREPARED_STATEMENT_SERVER_SIDE_CLASS_NAME); } }
- PreparedStatementInstrumentation inherits AbstractMysqlInstrumentation, which uses org.apache.skywalking.apm.plugin.jdbc.mysql.preparedstatementexecutemethods interceptor to enhance the execute, executeQuery, executeUpdate, executelageupdate methods of com.mysql.cj.jdbc.ClientPreparedStatement
StatementInstrumentation
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/StatementInstrumentation.java
public class StatementInstrumentation extends AbstractMysqlInstrumentation { private static final String SERVICE_METHOD_INTERCEPTOR = org.apache.skywalking.apm.plugin.jdbc.mysql.Constants.STATEMENT_EXECUTE_METHODS_INTERCEPTOR; public static final String MYSQL8_STATEMENT_CLASS_NAME = "com.mysql.cj.jdbc.StatementImpl"; @Override public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { return new ConstructorInterceptPoint[0]; } @Override public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { return new InstanceMethodsInterceptPoint[] { new InstanceMethodsInterceptPoint() { @Override public ElementMatcher<MethodDescription> getMethodsMatcher() { return named("execute") .or(named("executeQuery")) .or(named("executeUpdate")) .or(named("executeLargeUpdate")) .or(named("executeBatchInternal")) .or(named("executeUpdateInternal")) .or(named("executeQuery")) .or(named("executeBatch")); } @Override public String getMethodsInterceptor() { return SERVICE_METHOD_INTERCEPTOR; } @Override public boolean isOverrideArgs() { return false; } } }; } @Override protected ClassMatch enhanceClass() { return byName(MYSQL8_STATEMENT_CLASS_NAME); } }
- StatementInstrumentation inherits AbstractMysqlInstrumentation, which uses org.apache.skywalking.apm.plugin.jdbc.mysql.StatementExecuteMethodsInterceptor to enhance the execution, executeQuery, executeUpdate, executelageupdate, executebattinternal, executeUpdateInternal, executeQuery, executeBatch methods of com.mysql.cj.jdbc.StatementImpl
StatementExecuteMethodsInterceptor
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptor.java
public class StatementExecuteMethodsInterceptor 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(); /** * To protected the code occur NullPointException. because mysql execute system sql when constructor method in * {@link com.mysql.jdbc.ConnectionImpl} class executed. but the interceptor set the connection Info after * the constructor method executed. * * @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()); /** * 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); } } @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; } }
- StatementExecuteMethodsInterceptor implements the InstanceMethodsAroundInterceptor interface. Its beforeMethod method sets db'type, db'instance and db'statement. Its afterMethod method executes ContextManager.stopSpan() when cacheObject.getConnectionInfo() is not null. Its handleMethodException method executes contextmanager when cacheObject.getConnectionInfo() is not null activeSpan().errorOccurred().log(t)
PreparedStatementSetterInstrumentation
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/PreparedStatementSetterInstrumentation.java
public class PreparedStatementSetterInstrumentation extends PreparedStatementInstrumentation { @Override public final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { return new InstanceMethodsInterceptPoint[] { new PSSetterDefinitionOfJDBCInstrumentation(false) }; } }
- PreparedStatementSetterInstrumentation inherits PreparedStatementInstrumentation, whose getinstancemethods interceptpoints method returns pssetterdefinitionofjdbc instrumentation (false)
PSSetterDefinitionOfJDBCInstrumentation
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/PSSetterDefinitionOfJDBCInstrumentation.java
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 || Config.Plugin.POSTGRESQL.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; } }
- Pssetterdefinitionofjdbc instrumentation implements the instancemethods interceptpoint interface, and its getMethodsMatcher method constructs the matcher and methodsinterpoint according to whether PS ﹤ ignorable ﹤ sets or PS ﹤ sets can be used for ignorable
PreparedStatementNullSetterInstrumentation
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/PreparedStatementNullSetterInstrumentation.java
public class PreparedStatementNullSetterInstrumentation extends PreparedStatementInstrumentation { @Override public final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { return new InstanceMethodsInterceptPoint[] { new JDBCPreparedStatementNullSetterInstanceMethodsInterceptPoint() }; } }
- PreparedStatementNullSetterInstrumentation inherits PreparedStatementInstrumentation, whose getinstancemethods interceptpoints method returns JDBC preparedstatementnullsetterinstancemethods interceptpoint
JDBCPreparedStatementNullSetterInstanceMethodsInterceptPoint
skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/JDBCPreparedStatementNullSetterInstanceMethodsInterceptPoint.java
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; } }
- JDBC preparedstatementnullsetterinstancemethods interceptpoint implements the instancemethods interceptpoint interface, which uses org.apache.skywalking.apm.plugin.jdbc.jdbc.jdbc preparedstatementnullsetterinterinterceptor to enhance the setNull method
PreparedStatementIgnoredSetterInstrumentation
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/PreparedStatementIgnoredSetterInstrumentation.java
public class PreparedStatementIgnoredSetterInstrumentation extends PreparedStatementInstrumentation { @Override public final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { return new InstanceMethodsInterceptPoint[] { new PSSetterDefinitionOfJDBCInstrumentation(true) }; } }
- PreparedStatementIgnoredSetterInstrumentation inherits PreparedStatementInstrumentation, whose getinstancemethods interceptpoints method returns pssetterdefinitionofjdbc instrumentation (true)
Summary
skywalking's MySQL plugin provides several enhancements, such as ConnectionImplCreateInstrumentation, ConnectionInstrumentation, CallableInstrumentation, PreparedStatementInstrumentation, StatementInstrumentation, PreparedStatementSetterInstrumentation, PreparedStatementNullSetterInstrumentation, PreparedStatementIgnoredSetterInstrumentation