日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

skywalking使用mysql_聊聊skywalking的mysql-plugin

發布時間:2025/3/11 数据库 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 skywalking使用mysql_聊聊skywalking的mysql-plugin 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文主要研究一下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 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 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 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 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 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 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繼承了AbstractMysqlInstrumentation,它增強的是com.mysql.cj.jdbc.ConnectionImpl類;它使用org.apache.skywalking.apm.plugin.jdbc.mysql.CreatePreparedStatementInterceptor增強其prepareStatement方法;它使用org.apache.skywalking.apm.plugin.jdbc.mysql.CreateCallableStatementInterceptor增強其prepareCall方法;它使用org.apache.skywalking.apm.plugin.jdbc.mysql.CreateStatementInterceptor增強其createStatement方法;它使用org.apache.skywalking.apm.plugin.jdbc.ConnectionServiceMethodInterceptor增強其commit、rollback、close、releaseSavepoint方法;它使用org.apache.skywalking.apm.plugin.jdbc.mysql.SetCatalogInterceptor增強其setCatalog方法

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實現了InstanceMethodsAroundInterceptor接口,其afterMethod方法會將StatementEnhanceInfos設置給ret的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實現了InstanceMethodsAroundInterceptor接口,其afterMethod方法將StatementEnhanceInfos設置給ret的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實現了InstanceMethodsAroundInterceptor接口,其afterMethod方法將StatementEnhanceInfos設置給ret的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實現了InstanceMethodsAroundInterceptor接口,其beforeMethod方法設置DB_TYPE、DB_INSTANCE、DB_STATEMENT;其afterMethod方法在connectInfo不為null時執行ContextManager.stopSpan();其handleMethodException方法執行ContextManager.activeSpan().errorOccurred().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實現了InstanceMethodsAroundInterceptor接口,其beforeMethod方法給類型為ConnectionInfo的dynamicField設置databaseName

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 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繼承了AbstractMysqlInstrumentation,它使用org.apache.skywalking.apm.plugin.jdbc.mysql.PreparedStatementExecuteMethodsInterceptor增強了com.mysql.cj.jdbc.CallableStatement的execute、executeQuery、executeUpdate方法

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實現了InstanceMethodsAroundInterceptor接口,其beforeMethod方法設置DB_TYPE、DB_INSTANCE、DB_STATEMENT、SQL_PARAMETERS(Config.Plugin.MySQL.TRACE_SQL_PARAMETERS為true的話);其afterMethod方法在cacheObject.getConnectionInfo()不為null時執行ContextManager.stopSpan();其handleMethodException方法在cacheObject.getConnectionInfo()不為null時執行ContextManager.activeSpan().errorOccurred().log(t)

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 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繼承了AbstractMysqlInstrumentation,它使用org.apache.skywalking.apm.plugin.jdbc.mysql.PreparedStatementExecuteMethodsInterceptor增強了com.mysql.cj.jdbc.ClientPreparedStatement的execute、executeQuery、executeUpdate、executeLargeUpdate方法

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 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繼承了AbstractMysqlInstrumentation,它使用org.apache.skywalking.apm.plugin.jdbc.mysql.StatementExecuteMethodsInterceptor增強了com.mysql.cj.jdbc.StatementImpl的execute、executeQuery、executeUpdate、executeLargeUpdate、executeBatchInternal、executeUpdateInternal、executeQuery、executeBatch方法

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實現了InstanceMethodsAroundInterceptor接口,其beforeMethod方法設置DB_TYPE、DB_INSTANCE、DB_STATEMENT;其afterMethod方法在cacheObject.getConnectionInfo()不為null時執行ContextManager.stopSpan();其handleMethodException方法在cacheObject.getConnectionInfo()不為null時執行ContextManager.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繼承了PreparedStatementInstrumentation,其getInstanceMethodsInterceptPoints方法返回的是PSSetterDefinitionOfJDBCInstrumentation(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 getMethodsMatcher() {

ElementMatcher.Junction matcher = none();

if (Config.Plugin.MySQL.TRACE_SQL_PARAMETERS || Config.Plugin.POSTGRESQL.TRACE_SQL_PARAMETERS) {

final Set 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;

}

}

PSSetterDefinitionOfJDBCInstrumentation實現了InstanceMethodsInterceptPoint接口,其getMethodsMatcher方法根據ignorable使用PS_IGNORABLE_SETTERS還是PS_SETTERS去構造matcher以及methodsInterceptor

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繼承了PreparedStatementInstrumentation,其getInstanceMethodsInterceptPoints方法返回的是JDBCPreparedStatementNullSetterInstanceMethodsInterceptPoint

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 getMethodsMatcher() {

return named("setNull");

}

@Override

public String getMethodsInterceptor() {

return Constants.PREPARED_STATEMENT_NULL_SETTER_METHODS_INTERCEPTOR;

}

@Override

public boolean isOverrideArgs() {

return false;

}

}

JDBCPreparedStatementNullSetterInstanceMethodsInterceptPoint實現了InstanceMethodsInterceptPoint接口,它使用org.apache.skywalking.apm.plugin.jdbc.JDBCPreparedStatementNullSetterInterceptor增強setNull方法

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繼承了PreparedStatementInstrumentation,其getInstanceMethodsInterceptPoints方法返回的是PSSetterDefinitionOfJDBCInstrumentation(true)

小結

skywalking的mysql-plugin提供了ConnectionImplCreateInstrumentation、ConnectionInstrumentation、CallableInstrumentation、PreparedStatementInstrumentation、StatementInstrumentation、PreparedStatementSetterInstrumentation、PreparedStatementNullSetterInstrumentation、PreparedStatementIgnoredSetterInstrumentation這幾個增強

doc

總結

以上是生活随笔為你收集整理的skywalking使用mysql_聊聊skywalking的mysql-plugin的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。