diff --git a/.github/workflows/plugins-test.3.yaml b/.github/workflows/plugins-test.3.yaml
index 42069a540..d06107efe 100644
--- a/.github/workflows/plugins-test.3.yaml
+++ b/.github/workflows/plugins-test.3.yaml
@@ -43,6 +43,7 @@ jobs:
- { name: 'spring-async-scenario', title: 'Spring Async 4.3.x-5.1.x (35)' }
- { name: 'vertx-eventbus-3.x-scenario', title: 'Vert.x EventBus 3.2.0-3.9.0 (27)' }
- { name: 'vertx-web-3.x-scenario', title: 'Vert.x Web 3.0.0-3.9.0 (29)' }
+ - { name: 'mariadb-scenario', title: 'Mariadb 2.x (8)' }
steps:
- uses: actions/checkout@v2
with:
diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
index 136ebb6df..c608ae334 100755
--- a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
+++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
@@ -156,4 +156,6 @@ public class ComponentsDefine {
public static final OfficialComponent UNDERTOW = new OfficialComponent(84, "Undertow");
public static final OfficialComponent FINAGLE = new OfficialComponent(85, "Finagle");
+
+ public static final OfficialComponent MARIADB_JDBC = new OfficialComponent(87, "mariadb-jdbc");
}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java
index 764e514f4..8a4990d71 100755
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java
@@ -328,6 +328,22 @@ public class Config {
public static int SQL_PARAMETERS_MAX_LENGTH = 512;
}
+ public static class MARIADB {
+ /**
+ * If set to true, the parameters of the sql (typically {@link java.sql.PreparedStatement}) would be
+ * collected.
+ */
+ public static boolean TRACE_SQL_PARAMETERS = false;
+
+ /**
+ * For the sake of performance, SkyWalking won't save the entire parameters string into the tag, but only
+ * the first {@code SQL_PARAMETERS_MAX_LENGTH} characters.
+ *
+ * Set a negative number to save the complete parameter string to the tag.
+ */
+ public static int SQL_PARAMETERS_MAX_LENGTH = 512;
+ }
+
public static class SolrJ {
/**
* If true, trace all the query parameters(include deleteByIds and deleteByQuery) in Solr query request,
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/PSSetterDefinitionOfJDBCInstrumentation.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/PSSetterDefinitionOfJDBCInstrumentation.java
index bdb890a9e..d641ca6ec 100644
--- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/PSSetterDefinitionOfJDBCInstrumentation.java
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/PSSetterDefinitionOfJDBCInstrumentation.java
@@ -42,7 +42,7 @@ public class PSSetterDefinitionOfJDBCInstrumentation implements InstanceMethodsI
public ElementMatcher getMethodsMatcher() {
ElementMatcher.Junction matcher = none();
- if (Config.Plugin.MySQL.TRACE_SQL_PARAMETERS || Config.Plugin.POSTGRESQL.TRACE_SQL_PARAMETERS) {
+ if (Config.Plugin.MySQL.TRACE_SQL_PARAMETERS || Config.Plugin.POSTGRESQL.TRACE_SQL_PARAMETERS || Config.Plugin.MARIADB.TRACE_SQL_PARAMETERS) {
final Set setters = ignorable ? PS_IGNORABLE_SETTERS : PS_SETTERS;
for (String setter : setters) {
matcher = matcher.or(named(setter));
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/PreparedStatementParameterBuilder.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/PreparedStatementParameterBuilder.java
new file mode 100644
index 000000000..1209b80c8
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/PreparedStatementParameterBuilder.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc;
+
+public class PreparedStatementParameterBuilder {
+ private static final String EMPTY_LIST = "[]";
+ private Object[] parameters;
+ private Integer maxIndex;
+ private int maxLength = 0;
+
+ public PreparedStatementParameterBuilder setParameters(Object[] parameters) {
+ this.parameters = parameters;
+ return this;
+ }
+
+ public PreparedStatementParameterBuilder setMaxIndex(int maxIndex) {
+ this.maxIndex = maxIndex;
+ return this;
+ }
+
+ public PreparedStatementParameterBuilder setMaxLength(int maxLength) {
+ this.maxLength = maxLength;
+ return this;
+ }
+
+ public String build() {
+ if (parameters == null) {
+ return EMPTY_LIST;
+ }
+
+ String parameterString = getParameterString();
+ return truncate(parameterString);
+ }
+
+ private String getParameterString() {
+ StringBuilder stringBuilder = new StringBuilder();
+ boolean first = true;
+ for (int i = 0; i < getMaxIndex(); i++) {
+ Object parameter = parameters[i];
+ if (!first) {
+ stringBuilder.append(",");
+ }
+ stringBuilder.append(parameter);
+ first = false;
+ }
+ return String.format("[%s]", stringBuilder.toString());
+ }
+
+ private int getMaxIndex() {
+ int maxIdx = maxIndex != null ? maxIndex : parameters.length;
+ return Math.min(maxIdx, parameters.length);
+ }
+
+ private String truncate(String parameterString) {
+ if (maxLength > 0 && parameterString.length() > maxLength) {
+ parameterString = parameterString.substring(0, maxLength) + "...";
+ }
+
+ return parameterString;
+ }
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/MariadbURLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/MariadbURLParser.java
new file mode 100644
index 000000000..65b21e652
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/MariadbURLParser.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.connectionurl.parser;
+
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+
+public class MariadbURLParser extends MysqlURLParser {
+ public MariadbURLParser(String url) {
+ super(url, "Mariadb", ComponentsDefine.MARIADB_JDBC);
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/MysqlURLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/MysqlURLParser.java
index 7b86ea71e..d4ca1b860 100644
--- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/MysqlURLParser.java
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/MysqlURLParser.java
@@ -19,6 +19,7 @@
package org.apache.skywalking.apm.plugin.jdbc.connectionurl.parser;
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.apache.skywalking.apm.network.trace.component.OfficialComponent;
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
/**
@@ -27,12 +28,19 @@ import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
public class MysqlURLParser extends AbstractURLParser {
private static final int DEFAULT_PORT = 3306;
- private static final String DB_TYPE = "Mysql";
+ private String dbType = "Mysql";
+ private OfficialComponent component = ComponentsDefine.MYSQL_JDBC_DRIVER;
public MysqlURLParser(String url) {
super(url);
}
+ public MysqlURLParser(String url, String dbType, OfficialComponent component) {
+ super(url);
+ this.dbType = dbType;
+ this.component = component;
+ }
+
@Override
protected URLLocation fetchDatabaseHostsIndexRange() {
int hostLabelStartIndex = url.indexOf("//");
@@ -87,15 +95,15 @@ public class MysqlURLParser extends AbstractURLParser {
sb.append(host).append(",");
}
}
- return new ConnectionInfo(ComponentsDefine.MYSQL_JDBC_DRIVER, DB_TYPE, sb.substring(0, sb.length() - 1), fetchDatabaseNameFromURL());
+ return new ConnectionInfo(component, dbType, sb.substring(0, sb.length() - 1), fetchDatabaseNameFromURL());
} else {
String[] hostAndPort = hostSegment[0].split(":");
if (hostAndPort.length != 1) {
- return new ConnectionInfo(ComponentsDefine.MYSQL_JDBC_DRIVER, DB_TYPE, hostAndPort[0], Integer.valueOf(hostAndPort[1]), fetchDatabaseNameFromURL(location
- .endIndex()));
+ return new ConnectionInfo(component, dbType, hostAndPort[0], Integer.valueOf(hostAndPort[1]), fetchDatabaseNameFromURL(location
+ .endIndex()));
} else {
- return new ConnectionInfo(ComponentsDefine.MYSQL_JDBC_DRIVER, DB_TYPE, hostAndPort[0], DEFAULT_PORT, fetchDatabaseNameFromURL(location
- .endIndex()));
+ return new ConnectionInfo(component, dbType, hostAndPort[0], DEFAULT_PORT, fetchDatabaseNameFromURL(location
+ .endIndex()));
}
}
}
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java
index 905806588..12c6e042c 100644
--- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java
@@ -30,6 +30,7 @@ public class URLParser {
private static final String ORACLE_JDBC_URL_PREFIX = "jdbc:oracle";
private static final String H2_JDBC_URL_PREFIX = "jdbc:h2";
private static final String POSTGRESQL_JDBC_URL_PREFIX = "jdbc:postgresql";
+ private static final String MARIADB_JDBC_URL_PREFIX = "jdbc:mariadb";
public static ConnectionInfo parser(String url) {
ConnectionURLParser parser = null;
@@ -42,6 +43,8 @@ public class URLParser {
parser = new H2URLParser(url);
} else if (lowerCaseUrl.startsWith(POSTGRESQL_JDBC_URL_PREFIX)) {
parser = new PostgreSQLURLParser(url);
+ } else if (lowerCaseUrl.startsWith(MARIADB_JDBC_URL_PREFIX)) {
+ parser = new MariadbURLParser(url);
}
return parser.parse();
}
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/apache/skywalking/apm/plugin/jdbc/PreparedStatementParameterBuilderTest.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/apache/skywalking/apm/plugin/jdbc/PreparedStatementParameterBuilderTest.java
new file mode 100644
index 000000000..11d6fa39c
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/apache/skywalking/apm/plugin/jdbc/PreparedStatementParameterBuilderTest.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc;
+
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class PreparedStatementParameterBuilderTest {
+ private static Object[] PARAMETERS = new Object[]{"test", 1234};
+ private static final String EMPTY_LIST = "[]";
+ private PreparedStatementParameterBuilder builder;
+
+ @Test
+ public void testDefaultBuilder() {
+ builder = new PreparedStatementParameterBuilder();
+ assertThat(builder.build(), is(EMPTY_LIST));
+ }
+
+ @Test
+ public void testNullParameters() {
+ builder = new PreparedStatementParameterBuilder();
+ builder.setParameters(null);
+ assertThat(builder.build(), is(EMPTY_LIST));
+ }
+
+ @Test
+ public void testMaxIndex() {
+ builder = new PreparedStatementParameterBuilder();
+ Object[] parameters = new Object[]{
+ "test",
+ 1234,
+ "abcd"
+ };
+ builder.setParameters(parameters).setMaxIndex(2);
+ assertThat(builder.build(), is("[test,1234]"));
+ }
+
+ @Test
+ public void testOutOfRangeOfMaxIndex() {
+ builder = new PreparedStatementParameterBuilder();
+ builder.setParameters(PARAMETERS);
+ builder.setMaxIndex(3);
+ assertThat(builder.build(), is("[test,1234]"));
+
+ builder.setMaxIndex(0);
+ assertThat(builder.build(), is(EMPTY_LIST));
+
+ builder.setMaxIndex(-1);
+ assertThat(builder.build(), is(EMPTY_LIST));
+ }
+
+ @Test
+ public void testParametersString() {
+ builder = new PreparedStatementParameterBuilder();
+ Object[] parameters = new Object[]{
+ "",
+ 1234,
+ 10.0,
+ null,
+ 'c',
+ true,
+ 0x100
+ };
+ builder.setParameters(parameters);
+ assertThat(builder.build(), is("[,1234,10.0,null,c,true,256]"));
+ }
+
+ @Test
+ public void testMaxLength() {
+ builder = new PreparedStatementParameterBuilder();
+ builder.setParameters(PARAMETERS);
+ builder.setMaxLength(10);
+ assertThat(builder.build(), is("[test,1234..."));
+ }
+
+ @Test
+ public void testMaxLengthZero() {
+ builder = new PreparedStatementParameterBuilder();
+ builder.setParameters(PARAMETERS);
+ builder.setMaxLength(0);
+ assertThat(builder.build(), is("[test,1234]"));
+ }
+
+ @Test
+ public void testMaxLengthOutOfRange() {
+ builder = new PreparedStatementParameterBuilder();
+ builder.setParameters(PARAMETERS);
+ builder.setMaxLength(20);
+ assertThat(builder.build(), is("[test,1234]"));
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParserTest.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParserTest.java
index 50b9f5035..b832b45e1 100644
--- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParserTest.java
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParserTest.java
@@ -152,4 +152,12 @@ public class URLParserTest {
assertThat(connectionInfo.getDatabaseName(), is("sample"));
assertThat(connectionInfo.getDatabasePeer(), is("localhost:8084"));
}
+
+ @Test
+ public void testParseMariadbJDBCURLWithHost() {
+ ConnectionInfo connectionInfo = new URLParser().parser("jdbc:mariadb//primaryhost/test");
+ assertThat(connectionInfo.getDBType(), is("Mariadb"));
+ assertThat(connectionInfo.getDatabaseName(), is("test"));
+ assertThat(connectionInfo.getDatabasePeer(), is("primaryhost:3306"));
+ }
}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/pom.xml
new file mode 100644
index 000000000..0288fbe8e
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/pom.xml
@@ -0,0 +1,61 @@
+
+
+
+
+ apm-sdk-plugin
+ org.apache.skywalking
+ 8.0.0-SNAPSHOT
+
+ 4.0.0
+
+ apm-mariadb-2.x-plugin
+ jar
+
+ mariadb-2.x-plugin
+ http://maven.apache.org
+
+
+ UTF-8
+ 2.6.0
+
+
+
+
+ org.mariadb.jdbc
+ mariadb-java-client
+ ${mariadb-java-client.version}
+ provided
+
+
+ org.apache.skywalking
+ apm-jdbc-commons
+ ${project.version}
+ provided
+
+
+
+
+
+
+ maven-deploy-plugin
+
+
+
+
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/Constants.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/Constants.java
new file mode 100644
index 000000000..8e717a6d2
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/Constants.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2;
+
+import org.apache.skywalking.apm.agent.core.context.tag.StringTag;
+
+public class Constants {
+ public static final StringTag SQL_PARAMETERS = new StringTag("db.sql.parameters");
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreateCallableStatementInterceptor.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreateCallableStatementInterceptor.java
new file mode 100644
index 000000000..212b38834
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreateCallableStatementInterceptor.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+
+import java.lang.reflect.Method;
+
+public class CreateCallableStatementInterceptor implements InstanceMethodsAroundInterceptor {
+ @Override
+ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ MethodInterceptResult result) {
+
+ }
+
+ @Override
+ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ Object ret) {
+ 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) {
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreatePreparedStatementInterceptor.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreatePreparedStatementInterceptor.java
new file mode 100644
index 000000000..3b286a6eb
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreatePreparedStatementInterceptor.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+
+import java.lang.reflect.Method;
+
+public class CreatePreparedStatementInterceptor implements InstanceMethodsAroundInterceptor {
+ @Override
+ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ MethodInterceptResult result) {
+
+ }
+
+ @Override
+ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ Object ret) {
+ 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) {
+
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreateStatementInterceptor.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreateStatementInterceptor.java
new file mode 100644
index 000000000..5113af05a
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreateStatementInterceptor.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+
+import java.lang.reflect.Method;
+
+public class CreateStatementInterceptor implements InstanceMethodsAroundInterceptor {
+ @Override
+ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ MethodInterceptResult result) {
+
+ }
+
+ @Override
+ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ Object ret) {
+ 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) {
+
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/PreparedStatementExecuteMethodsInterceptor.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/PreparedStatementExecuteMethodsInterceptor.java
new file mode 100644
index 000000000..c17d94a88
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/PreparedStatementExecuteMethodsInterceptor.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2;
+
+import org.apache.skywalking.apm.agent.core.conf.Config;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.tag.Tags;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.plugin.jdbc.PreparedStatementParameterBuilder;
+import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+
+import java.lang.reflect.Method;
+
+import static org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.Constants.SQL_PARAMETERS;
+
+public class PreparedStatementExecuteMethodsInterceptor implements InstanceMethodsAroundInterceptor {
+
+ @Override
+ public final void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
+ Class>[] argumentsTypes, MethodInterceptResult result) {
+ StatementEnhanceInfos cacheObject = (StatementEnhanceInfos) objInst.getSkyWalkingDynamicField();
+ ConnectionInfo connectInfo = cacheObject.getConnectionInfo();
+ if (connectInfo == null) {
+ return;
+ }
+ 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.MARIADB.TRACE_SQL_PARAMETERS) {
+ final Object[] parameters = cacheObject.getParameters();
+ if (parameters != null && parameters.length > 0) {
+ int maxIndex = cacheObject.getMaxIndex();
+ SQL_PARAMETERS.set(span, getParameterString(parameters, maxIndex));
+ }
+ }
+
+ SpanLayer.asDB(span);
+ }
+
+ @Override
+ public final Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
+ Class>[] argumentsTypes, Object ret) {
+ 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 getParameterString(Object[] parameters, int maxIndex) {
+ return new PreparedStatementParameterBuilder()
+ .setParameters(parameters)
+ .setMaxIndex(maxIndex)
+ .setMaxLength(Config.Plugin.MARIADB.SQL_PARAMETERS_MAX_LENGTH)
+ .build();
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/SetCatalogInterceptor.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/SetCatalogInterceptor.java
new file mode 100644
index 000000000..8c25279c4
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/SetCatalogInterceptor.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+
+import java.lang.reflect.Method;
+
+public class SetCatalogInterceptor implements InstanceMethodsAroundInterceptor {
+ @Override
+ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ MethodInterceptResult result) {
+ 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) {
+ return ret;
+ }
+
+ @Override
+ public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
+ Class>[] argumentsTypes, Throwable t) {
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/StatementExecuteMethodsInterceptor.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/StatementExecuteMethodsInterceptor.java
new file mode 100644
index 000000000..8f636ce82
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/StatementExecuteMethodsInterceptor.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2;
+
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.tag.Tags;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+
+import java.lang.reflect.Method;
+
+public class StatementExecuteMethodsInterceptor implements InstanceMethodsAroundInterceptor {
+ @Override
+ public final void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
+ Class>[] argumentsTypes, MethodInterceptResult result) {
+ StatementEnhanceInfos cacheObject = (StatementEnhanceInfos) objInst.getSkyWalkingDynamicField();
+ ConnectionInfo connectInfo = cacheObject.getConnectionInfo();
+ 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());
+ String sql = allArguments.length > 0 ? (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) {
+ 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;
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/ConnectionInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/ConnectionInstrumentation.java
new file mode 100644
index 000000000..45ddf69ec
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/ConnectionInstrumentation.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+import org.apache.skywalking.apm.plugin.jdbc.define.Constants;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+
+public class ConnectionInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+
+ private static final String ENHANCE_CLASS = "org.mariadb.jdbc.MariaDbConnection";
+ private static final String CREATE_STATEMENT_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.CreateStatementInterceptor";
+ private static final String CREATE_PREPARED_STATEMENT_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.CreatePreparedStatementInterceptor";
+ private static final String CREATE_CALLABLE_STATEMENT_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.CreateCallableStatementInterceptor";
+ private static final String SET_CATALOG_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.SetCatalogInterceptor";
+
+ @Override
+ protected ClassMatch enhanceClass() {
+ return byName(ENHANCE_CLASS);
+ }
+
+ @Override
+ public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return new ConstructorInterceptPoint[0];
+ }
+
+ @Override
+ public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return named(Constants.CREATE_STATEMENT_METHOD_NAME);
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return CREATE_STATEMENT_INTERCEPTOR_CLASS;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ },
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return named(Constants.PREPARE_STATEMENT_METHOD_NAME);
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return CREATE_PREPARED_STATEMENT_INTERCEPTOR_CLASS;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ },
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return named(Constants.PREPARE_CALL_METHOD_NAME);
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return CREATE_CALLABLE_STATEMENT_INTERCEPTOR_CLASS;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ },
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return named(Constants.COMMIT_METHOD_NAME)
+ .or(named(Constants.ROLLBACK_METHOD_NAME))
+ .or(named(Constants.CLOSE_METHOD_NAME))
+ .or(named(Constants.RELEASE_SAVE_POINT_METHOD_NAME));
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return 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 SET_CATALOG_INTERCEPTOR_CLASS;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ }
+ };
+
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/DriverInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/DriverInstrumentation.java
new file mode 100644
index 000000000..f59ef432c
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/DriverInstrumentation.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.define;
+
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+import org.apache.skywalking.apm.plugin.jdbc.define.AbstractDriverInstrumentation;
+
+import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+
+/**
+ * {@link DriverInstrumentation} presents that skywalking intercepts {@link org.mariadb.jdbc.Driver}.
+ */
+public class DriverInstrumentation extends AbstractDriverInstrumentation {
+ private static final String ENHANCE_CLASS = "org.mariadb.jdbc.Driver";
+
+ @Override
+ protected ClassMatch enhanceClass() {
+ return byName(ENHANCE_CLASS);
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/PreparedStatementIgnoredSetterInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/PreparedStatementIgnoredSetterInstrumentation.java
new file mode 100644
index 000000000..17f528e93
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/PreparedStatementIgnoredSetterInstrumentation.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.define;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.plugin.jdbc.PSSetterDefinitionOfJDBCInstrumentation;
+
+public class PreparedStatementIgnoredSetterInstrumentation extends PreparedStatementInstrumentation {
+
+ @Override
+ public final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{
+ new PSSetterDefinitionOfJDBCInstrumentation(true)
+ };
+ }
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/PreparedStatementInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/PreparedStatementInstrumentation.java
new file mode 100644
index 000000000..c1b1afe69
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/PreparedStatementInstrumentation.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMatch.byMultiClassMatch;
+
+public class PreparedStatementInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+
+ private static final String CLIENT_SIDE_PREPARED_STATEMENT_CLASS_2_0_X = "org.mariadb.jdbc.MariaDbPreparedStatementClient";
+ private static final String CLIENT_SIDE_PREPARED_STATEMENT_CLASS_2_4_X = "org.mariadb.jdbc.ClientSidePreparedStatement";
+ private static final String SERVER_SIDE_PREPARED_STATEMENT_CLASS_2_0_X = "org.mariadb.jdbc.MariaDbPreparedStatementServer";
+ private static final String SERVER_SIDE_PREPARED_STATEMENT_CLASS_2_4_X = "org.mariadb.jdbc.ServerSidePreparedStatement";
+ private static final String PREPARED_STATEMENT_EXECUTE_METHODS_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.PreparedStatementExecuteMethodsInterceptor";
+
+ @Override
+ protected ClassMatch enhanceClass() {
+ return byMultiClassMatch(
+ CLIENT_SIDE_PREPARED_STATEMENT_CLASS_2_0_X,
+ CLIENT_SIDE_PREPARED_STATEMENT_CLASS_2_4_X,
+ SERVER_SIDE_PREPARED_STATEMENT_CLASS_2_0_X,
+ SERVER_SIDE_PREPARED_STATEMENT_CLASS_2_4_X
+ );
+ }
+
+ @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 PREPARED_STATEMENT_EXECUTE_METHODS_INTERCEPTOR_CLASS;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ }
+ };
+
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/PreparedStatementNullSetterInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/PreparedStatementNullSetterInstrumentation.java
new file mode 100644
index 000000000..e4cb3ecb0
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/PreparedStatementNullSetterInstrumentation.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.define;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.plugin.jdbc.JDBCPreparedStatementNullSetterInstanceMethodsInterceptPoint;
+
+public class PreparedStatementNullSetterInstrumentation extends PreparedStatementInstrumentation {
+
+ @Override
+ public final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{
+ new JDBCPreparedStatementNullSetterInstanceMethodsInterceptPoint()
+ };
+ }
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/PreparedStatementSetterInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/PreparedStatementSetterInstrumentation.java
new file mode 100644
index 000000000..7f58dfd42
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/PreparedStatementSetterInstrumentation.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.define;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.plugin.jdbc.PSSetterDefinitionOfJDBCInstrumentation;
+
+public class PreparedStatementSetterInstrumentation extends PreparedStatementInstrumentation {
+
+ @Override
+ public final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{
+ new PSSetterDefinitionOfJDBCInstrumentation(false)
+ };
+ }
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/StatementInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/StatementInstrumentation.java
new file mode 100644
index 000000000..8d7bfbd15
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/define/StatementInstrumentation.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+
+public class StatementInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+ private static final String MARIADB_STATEMENT_CLASS_NAME = "org.mariadb.jdbc.MariaDbStatement";
+ private static final String STATEMENT_EXECUTE_METHODS_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.StatementExecuteMethodsInterceptor";
+
+ @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("executeBatch"))
+ .or(named("executeLargeBatch"));
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return STATEMENT_EXECUTE_METHODS_INTERCEPTOR;
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ }
+ };
+ }
+
+ @Override
+ protected ClassMatch enhanceClass() {
+ return byName(MARIADB_STATEMENT_CLASS_NAME);
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/resources/skywalking-plugin.def
new file mode 100644
index 000000000..65c37bf8e
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/resources/skywalking-plugin.def
@@ -0,0 +1,23 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+mariadb-2.x=org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.define.DriverInstrumentation
+mariadb-2.x=org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.define.ConnectionInstrumentation
+mariadb-2.x=org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.define.StatementInstrumentation
+mariadb-2.x=org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.define.PreparedStatementInstrumentation
+mariadb-2.x=org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.define.PreparedStatementSetterInstrumentation
+mariadb-2.x=org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.define.PreparedStatementNullSetterInstrumentation
+mariadb-2.x=org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.define.PreparedStatementIgnoredSetterInstrumentation
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreateCallableStatementInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreateCallableStatementInterceptorTest.java
new file mode 100644
index 000000000..5979c2cc5
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreateCallableStatementInterceptorTest.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class CreateCallableStatementInterceptorTest {
+
+ private static final String SQL = "Select * from test";
+
+ private CreateCallableStatementInterceptor interceptor;
+
+ @Mock
+ private EnhancedInstance ret;
+
+ @Mock
+ private EnhancedInstance objectInstance;
+
+ @Mock
+ private ConnectionInfo connectionInfo;
+
+ @Before
+ public void setUp() {
+ interceptor = new CreateCallableStatementInterceptor();
+
+ when(objectInstance.getSkyWalkingDynamicField()).thenReturn(connectionInfo);
+ }
+
+ @Test
+ public void testResultIsEnhanceInstance() {
+ interceptor.afterMethod(objectInstance, null, new Object[]{SQL}, null, ret);
+ verify(ret).setSkyWalkingDynamicField(Matchers.any());
+ }
+
+ @Test
+ public void testResultIsNotEnhanceInstance() {
+ interceptor.afterMethod(objectInstance, null, new Object[]{SQL}, null, new Object());
+ verify(ret, times(0)).setSkyWalkingDynamicField(Matchers.any());
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreatePreparedStatementInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreatePreparedStatementInterceptorTest.java
new file mode 100644
index 000000000..4141c0486
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreatePreparedStatementInterceptorTest.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class CreatePreparedStatementInterceptorTest {
+
+ private static final String SQL = "Select * from test";
+
+ private CreatePreparedStatementInterceptor interceptor;
+
+ @Mock
+ private EnhancedInstance ret;
+
+ @Mock
+ private EnhancedInstance objectInstance;
+
+ @Mock
+ private ConnectionInfo connectionInfo;
+
+ @Before
+ public void setUp() {
+ interceptor = new CreatePreparedStatementInterceptor();
+
+ when(objectInstance.getSkyWalkingDynamicField()).thenReturn(connectionInfo);
+ }
+
+ @Test
+ public void testResultIsEnhanceInstance() {
+ interceptor.afterMethod(objectInstance, null, new Object[]{SQL}, null, ret);
+ verify(ret).setSkyWalkingDynamicField(Matchers.any());
+ }
+
+ @Test
+ public void testResultIsNotEnhanceInstance() {
+ interceptor.afterMethod(objectInstance, null, new Object[]{SQL}, null, new Object());
+ verify(ret, times(0)).setSkyWalkingDynamicField(Matchers.any());
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreateStatementInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreateStatementInterceptorTest.java
new file mode 100644
index 000000000..6292a4b9a
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/CreateStatementInterceptorTest.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class CreateStatementInterceptorTest {
+
+ private static final String SQL = "Select * from test";
+
+ private CreateStatementInterceptor interceptor;
+
+ @Mock
+ private EnhancedInstance ret;
+
+ @Mock
+ private EnhancedInstance objectInstance;
+
+ @Mock
+ private ConnectionInfo connectionInfo;
+
+ @Before
+ public void setUp() {
+ interceptor = new CreateStatementInterceptor();
+
+ when(objectInstance.getSkyWalkingDynamicField()).thenReturn(connectionInfo);
+ }
+
+ @Test
+ public void testResultIsEnhanceInstance() {
+ interceptor.afterMethod(objectInstance, null, new Object[]{SQL}, null, ret);
+ verify(ret).setSkyWalkingDynamicField(Matchers.any());
+ }
+
+ @Test
+ public void testResultIsNotEnhanceInstance() {
+ interceptor.afterMethod(objectInstance, null, new Object[]{SQL}, null, new Object());
+ verify(ret, times(0)).setSkyWalkingDynamicField(Matchers.any());
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/PreparedStatementExecuteMethodsInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/PreparedStatementExecuteMethodsInterceptorTest.java
new file mode 100644
index 000000000..874284246
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/PreparedStatementExecuteMethodsInterceptorTest.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2;
+
+import org.apache.skywalking.apm.agent.core.conf.Config;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
+import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
+import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
+import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
+import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
+import org.apache.skywalking.apm.agent.test.tools.SpanAssert;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.apache.skywalking.apm.plugin.jdbc.JDBCPreparedStatementSetterInterceptor;
+import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.modules.junit4.PowerMockRunnerDelegate;
+
+import java.lang.reflect.Method;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+@RunWith(PowerMockRunner.class)
+@PowerMockRunnerDelegate(TracingSegmentRunner.class)
+public class PreparedStatementExecuteMethodsInterceptorTest {
+
+ private static final String SQL = "Select * from test where id = ?";
+
+ @SegmentStoragePoint
+ private SegmentStorage segmentStorage;
+
+ @Rule
+ public AgentServiceRule serviceRule = new AgentServiceRule();
+
+ private PreparedStatementExecuteMethodsInterceptor serviceMethodInterceptor;
+
+ private JDBCPreparedStatementSetterInterceptor preparedStatementSetterInterceptor;
+
+ @Mock
+ private ConnectionInfo connectionInfo;
+ @Mock
+ private EnhancedInstance objectInstance;
+ @Mock
+ private Method method;
+ private StatementEnhanceInfos enhanceRequireCacheObject;
+
+ @Before
+ public void setUp() {
+ Config.Plugin.MARIADB.TRACE_SQL_PARAMETERS = true;
+ preparedStatementSetterInterceptor = new JDBCPreparedStatementSetterInterceptor();
+ serviceMethodInterceptor = new PreparedStatementExecuteMethodsInterceptor();
+
+ enhanceRequireCacheObject = new StatementEnhanceInfos(connectionInfo, SQL, "PreparedStatement");
+ when(objectInstance.getSkyWalkingDynamicField()).thenReturn(enhanceRequireCacheObject);
+ when(method.getName()).thenReturn("executeQuery");
+ when(connectionInfo.getComponent()).thenReturn(ComponentsDefine.MARIADB_JDBC);
+ when(connectionInfo.getDBType()).thenReturn("Mariadb");
+ when(connectionInfo.getDatabaseName()).thenReturn("test");
+ when(connectionInfo.getDatabasePeer()).thenReturn("localhost:3306");
+ }
+
+ @Test
+ public void testExecutePreparedStatement() throws Throwable {
+ preparedStatementSetterInterceptor.beforeMethod(objectInstance, method, new Object[]{1, "abcd"}, null, null);
+ preparedStatementSetterInterceptor.beforeMethod(objectInstance, method, new Object[]{2, "efgh"}, null, null);
+
+ serviceMethodInterceptor.beforeMethod(objectInstance, method, new Object[]{SQL}, null, null);
+ serviceMethodInterceptor.afterMethod(objectInstance, method, new Object[]{SQL}, null, null);
+
+ assertThat(segmentStorage.getTraceSegments().size(), is(1));
+ TraceSegment segment = segmentStorage.getTraceSegments().get(0);
+ assertThat(SegmentHelper.getSpans(segment).size(), is(1));
+ AbstractTracingSpan span = SegmentHelper.getSpans(segment).get(0);
+ SpanAssert.assertLayer(span, SpanLayer.DB);
+ assertThat(span.getOperationName(), is("Mariadb/JDBI/PreparedStatement/"));
+ SpanAssert.assertTag(span, 0, "sql");
+ SpanAssert.assertTag(span, 1, "test");
+ SpanAssert.assertTag(span, 2, SQL);
+ SpanAssert.assertTag(span, 3, "[abcd,efgh]");
+ }
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/StatementExecuteMethodsInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/StatementExecuteMethodsInterceptorTest.java
new file mode 100644
index 000000000..9b877bb6c
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/StatementExecuteMethodsInterceptorTest.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2;
+
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
+import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
+import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
+import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
+import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
+import org.apache.skywalking.apm.agent.test.tools.SpanAssert;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.modules.junit4.PowerMockRunnerDelegate;
+
+import java.lang.reflect.Method;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+@RunWith(PowerMockRunner.class)
+@PowerMockRunnerDelegate(TracingSegmentRunner.class)
+public class StatementExecuteMethodsInterceptorTest {
+
+ private static final String SQL = "Select * from test";
+
+ @SegmentStoragePoint
+ private SegmentStorage segmentStorage;
+
+ @Rule
+ public AgentServiceRule serviceRule = new AgentServiceRule();
+
+ private StatementExecuteMethodsInterceptor serviceMethodInterceptor;
+
+ @Mock
+ private ConnectionInfo connectionInfo;
+ @Mock
+ private EnhancedInstance objectInstance;
+ @Mock
+ private Method method;
+ private StatementEnhanceInfos enhanceRequireCacheObject;
+
+ @Before
+ public void setUp() {
+ serviceMethodInterceptor = new StatementExecuteMethodsInterceptor();
+
+ enhanceRequireCacheObject = new StatementEnhanceInfos(connectionInfo, SQL, "CallableStatement");
+ when(objectInstance.getSkyWalkingDynamicField()).thenReturn(enhanceRequireCacheObject);
+ when(method.getName()).thenReturn("executeQuery");
+ when(connectionInfo.getComponent()).thenReturn(ComponentsDefine.MARIADB_JDBC);
+ when(connectionInfo.getDBType()).thenReturn("Mariadb");
+ when(connectionInfo.getDatabaseName()).thenReturn("test");
+ when(connectionInfo.getDatabasePeer()).thenReturn("localhost:3306");
+ }
+
+ @Test
+ public void testExecuteStatement() {
+ serviceMethodInterceptor.beforeMethod(objectInstance, method, new Object[]{SQL}, null, null);
+ serviceMethodInterceptor.afterMethod(objectInstance, method, new Object[]{SQL}, null, null);
+
+ assertThat(segmentStorage.getTraceSegments().size(), is(1));
+ TraceSegment segment = segmentStorage.getTraceSegments().get(0);
+ assertThat(SegmentHelper.getSpans(segment).size(), is(1));
+ AbstractTracingSpan span = SegmentHelper.getSpans(segment).get(0);
+ SpanAssert.assertLayer(span, SpanLayer.DB);
+ assertThat(span.getOperationName(), is("Mariadb/JDBI/CallableStatement/"));
+ SpanAssert.assertTag(span, 0, "sql");
+ SpanAssert.assertTag(span, 1, "test");
+ SpanAssert.assertTag(span, 2, SQL);
+ }
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/PreparedStatementExecuteMethodsInterceptor.java b/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/PreparedStatementExecuteMethodsInterceptor.java
index 91b01862d..fa0613af9 100644
--- a/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/PreparedStatementExecuteMethodsInterceptor.java
+++ b/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/PreparedStatementExecuteMethodsInterceptor.java
@@ -26,6 +26,7 @@ import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.plugin.jdbc.PreparedStatementParameterBuilder;
import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos;
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
@@ -37,7 +38,7 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho
@Override
public final void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
- Class>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
+ Class>[] argumentsTypes, MethodInterceptResult result) {
StatementEnhanceInfos cacheObject = (StatementEnhanceInfos) objInst.getSkyWalkingDynamicField();
ConnectionInfo connectInfo = cacheObject.getConnectionInfo();
/**
@@ -49,7 +50,7 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho
if (connectInfo != null) {
AbstractSpan span = ContextManager.createExitSpan(buildOperationName(connectInfo, method.getName(), cacheObject
- .getStatementName()), connectInfo.getDatabasePeer());
+ .getStatementName()), connectInfo.getDatabasePeer());
Tags.DB_TYPE.set(span, "sql");
Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName());
Tags.DB_STATEMENT.set(span, cacheObject.getSql());
@@ -59,11 +60,7 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho
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) + "...";
- }
+ String parameterString = getParameterString(parameters, maxIndex);
SQL_PARAMETERS.set(span, parameterString);
}
}
@@ -74,7 +71,7 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho
@Override
public final Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
- Class>[] argumentsTypes, Object ret) throws Throwable {
+ Class>[] argumentsTypes, Object ret) {
StatementEnhanceInfos cacheObject = (StatementEnhanceInfos) objInst.getSkyWalkingDynamicField();
if (cacheObject.getConnectionInfo() != null) {
ContextManager.stopSpan();
@@ -84,7 +81,7 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho
@Override
public final void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
- Class>[] argumentsTypes, Throwable t) {
+ Class>[] argumentsTypes, Throwable t) {
StatementEnhanceInfos cacheObject = (StatementEnhanceInfos) objInst.getSkyWalkingDynamicField();
if (cacheObject.getConnectionInfo() != null) {
ContextManager.activeSpan().errorOccurred().log(t);
@@ -95,18 +92,11 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho
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;
+ private String getParameterString(Object[] parameters, int maxIndex) {
+ return new PreparedStatementParameterBuilder()
+ .setParameters(parameters)
+ .setMaxIndex(maxIndex)
+ .setMaxLength(Config.Plugin.MySQL.SQL_PARAMETERS_MAX_LENGTH)
+ .build();
}
}
diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml
index 2db840d29..1c9d9d249 100644
--- a/apm-sniffer/apm-sdk-plugin/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/pom.xml
@@ -88,6 +88,7 @@
lettuce-5.x-pluginavro-pluginfinagle-6.25.x-plugin
+ mariadb-2.x-pluginpom
diff --git a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/PreparedStatementExecuteMethodsInterceptor.java b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/PreparedStatementExecuteMethodsInterceptor.java
index 5a76cf3f9..151c37ecb 100755
--- a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/PreparedStatementExecuteMethodsInterceptor.java
+++ b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/PreparedStatementExecuteMethodsInterceptor.java
@@ -18,7 +18,6 @@
package org.apache.skywalking.apm.plugin.jdbc.postgresql;
-import java.lang.reflect.Method;
import org.apache.skywalking.apm.agent.core.conf.Config;
import org.apache.skywalking.apm.agent.core.context.ContextManager;
import org.apache.skywalking.apm.agent.core.context.tag.StringTag;
@@ -28,9 +27,12 @@ import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.plugin.jdbc.PreparedStatementParameterBuilder;
import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos;
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+import java.lang.reflect.Method;
+
/**
* {@link PreparedStatementExecuteMethodsInterceptor} create the exit span when the client call the interceptor
* methods.
@@ -41,11 +43,11 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho
@Override
public final void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
- Class>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
+ Class>[] argumentsTypes, MethodInterceptResult result) {
StatementEnhanceInfos cacheObject = (StatementEnhanceInfos) objInst.getSkyWalkingDynamicField();
ConnectionInfo connectInfo = cacheObject.getConnectionInfo();
AbstractSpan span = ContextManager.createExitSpan(buildOperationName(connectInfo, method.getName(), cacheObject.getStatementName()), connectInfo
- .getDatabasePeer());
+ .getDatabasePeer());
Tags.DB_TYPE.set(span, "sql");
Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName());
Tags.DB_STATEMENT.set(span, cacheObject.getSql());
@@ -55,11 +57,7 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho
final Object[] parameters = cacheObject.getParameters();
if (parameters != null && parameters.length > 0) {
int maxIndex = cacheObject.getMaxIndex();
- String parameterString = buildParameterString(parameters, maxIndex);
- int sqlParametersMaxLength = Config.Plugin.POSTGRESQL.SQL_PARAMETERS_MAX_LENGTH;
- if (sqlParametersMaxLength > 0 && parameterString.length() > sqlParametersMaxLength) {
- parameterString = parameterString.substring(0, sqlParametersMaxLength) + "..." + "]";
- }
+ String parameterString = getParameterString(parameters, maxIndex);
SQL_PARAMETERS.set(span, parameterString);
}
}
@@ -69,7 +67,7 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho
@Override
public final Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
- Class>[] argumentsTypes, Object ret) throws Throwable {
+ Class>[] argumentsTypes, Object ret) {
StatementEnhanceInfos cacheObject = (StatementEnhanceInfos) objInst.getSkyWalkingDynamicField();
if (cacheObject.getConnectionInfo() != null) {
ContextManager.stopSpan();
@@ -79,7 +77,7 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho
@Override
public final void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
- Class>[] argumentsTypes, Throwable t) {
+ Class>[] argumentsTypes, Throwable t) {
StatementEnhanceInfos cacheObject = (StatementEnhanceInfos) objInst.getSkyWalkingDynamicField();
if (cacheObject.getConnectionInfo() != null) {
ContextManager.activeSpan().errorOccurred().log(t);
@@ -90,18 +88,11 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho
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;
+ private String getParameterString(Object[] parameters, int maxIndex) {
+ return new PreparedStatementParameterBuilder()
+ .setParameters(parameters)
+ .setMaxIndex(maxIndex)
+ .setMaxLength(Config.Plugin.POSTGRESQL.SQL_PARAMETERS_MAX_LENGTH)
+ .build();
}
}
diff --git a/docs/en/setup/service-agent/java-agent/README.md b/docs/en/setup/service-agent/java-agent/README.md
index acd80bf6a..a1b4f6037 100755
--- a/docs/en/setup/service-agent/java-agent/README.md
+++ b/docs/en/setup/service-agent/java-agent/README.md
@@ -114,6 +114,8 @@ property key | Description | Default |
`plugin.mysql.sql_parameters_max_length`|If set to positive number, the `db.sql.parameters` would be truncated to this length, otherwise it would be completely saved, which may cause performance problem.|`512`|
`plugin.postgresql.trace_sql_parameters`|If set to true, the parameters of the sql (typically `java.sql.PreparedStatement`) would be collected.|`false`|
`plugin.postgresql.sql_parameters_max_length`|If set to positive number, the `db.sql.parameters` would be truncated to this length, otherwise it would be completely saved, which may cause performance problem.|`512`|
+`plugin.mariadb.trace_sql_parameters`|If set to true, the parameters of the sql (typically `java.sql.PreparedStatement`) would be collected.|`false`|
+`plugin.mariadb.sql_parameters_max_length`|If set to positive number, the `db.sql.parameters` would be truncated to this length, otherwise it would be completely saved, which may cause performance problem.|`512`|
`plugin.solrj.trace_statement`|If true, trace all the query parameters(include deleteByIds and deleteByQuery) in Solr query request, default is false.|`false`|
`plugin.solrj.trace_ops_params`|If true, trace all the operation parameters in Solr request, default is false.|`false`|
`plugin.light4j.trace_handler_chain`|If true, trace all middleware/business handlers that are part of the Light4J handler chain for a request.|false|
diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md
index 735f18540..abb85332f 100644
--- a/docs/en/setup/service-agent/java-agent/Supported-list.md
+++ b/docs/en/setup/service-agent/java-agent/Supported-list.md
@@ -32,6 +32,7 @@
* [Sharding-JDBC](https://github.com/shardingjdbc/sharding-jdbc) 1.5.x
* [ShardingSphere](https://github.com/apache/incubator-shardingsphere) 3.0.0, 4.0.0-RC1
* PostgreSQL Driver 8.x, 9.x, 42.x
+ * Mariadb Driver 2.x, 1.8
* RPC Frameworks
* [Dubbo](https://github.com/alibaba/dubbo) 2.5.4 -> 2.6.0
* [Dubbox](https://github.com/dangdangdotcom/dubbox) 2.8.4
diff --git a/oap-server/server-bootstrap/src/main/resources/component-libraries.yml b/oap-server/server-bootstrap/src/main/resources/component-libraries.yml
index 04d829842..9de8925b1 100755
--- a/oap-server/server-bootstrap/src/main/resources/component-libraries.yml
+++ b/oap-server/server-bootstrap/src/main/resources/component-libraries.yml
@@ -287,6 +287,12 @@ Undertow:
Finagle:
id: 85
languages: Java,Scala
+Mariadb:
+ id: 86
+ languages: Java
+mariadb-jdbc:
+ id: 87
+ languages: Java
# .NET/.NET Core components
# [3000, 4000) for C#/.NET only
@@ -414,3 +420,4 @@ Component-Server-Mappings:
pulsar-producer: Pulsar
pulsar-consumer: Pulsar
rest-high-level-client: Elasticsearch
+ mariadb-jdbc: Mariadb
diff --git a/oap-server/server-core/src/test/resources/component-libraries.yml b/oap-server/server-core/src/test/resources/component-libraries.yml
index 643b0b2b7..44a9d127a 100755
--- a/oap-server/server-core/src/test/resources/component-libraries.yml
+++ b/oap-server/server-core/src/test/resources/component-libraries.yml
@@ -251,6 +251,12 @@ AvroClient:
Finagle:
id: 85
languages: Java,Scala
+Mariadb:
+ id: 86
+ languages: Java
+mariadb-jdbc:
+ id: 87
+ languages: Java
# .NET/.NET Core components
@@ -352,3 +358,4 @@ Component-Server-Mappings:
rest-high-level-client: Elasticsearch
SolrJ: Solr
cassandra-java-driver: Cassandra
+ mariadb-jdbc: Mariadb
diff --git a/test/plugin/scenarios/mariadb-scenario/bin/startup.sh b/test/plugin/scenarios/mariadb-scenario/bin/startup.sh
new file mode 100644
index 000000000..58858857e
--- /dev/null
+++ b/test/plugin/scenarios/mariadb-scenario/bin/startup.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+home="$(cd "$(dirname $0)"; pwd)"
+
+java -jar ${agent_opts} ${home}/../libs/mariadb-scenario.jar &
\ No newline at end of file
diff --git a/test/plugin/scenarios/mariadb-scenario/config/expectedData.yaml b/test/plugin/scenarios/mariadb-scenario/config/expectedData.yaml
new file mode 100644
index 000000000..37e1b3465
--- /dev/null
+++ b/test/plugin/scenarios/mariadb-scenario/config/expectedData.yaml
@@ -0,0 +1,119 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+segmentItems:
+- serviceName: mariadb-scenario
+ segmentSize: ge 1
+ segments:
+ - segmentId: not null
+ spans:
+ - operationName: Mariadb/JDBI/Statement/execute
+ operationId: eq 0
+ parentSpanId: 0
+ spanId: 1
+ spanLayer: Database
+ startTime: nq 0
+ endTime: nq 0
+ componentId: 87
+ isError: false
+ spanType: Exit
+ peer: mariadb-server:3306
+ skipAnalysis: 'false'
+ tags:
+ - {key: db.type, value: sql}
+ - {key: db.instance, value: test}
+ - key: db.statement
+ value: "CREATE TABLE test_table(\nid VARCHAR(1) PRIMARY KEY, \nvalue VARCHAR(10)\
+ \ NOT NULL)"
+ - operationName: Mariadb/JDBI/PreparedStatement/execute
+ operationId: eq 0
+ parentSpanId: 0
+ spanId: 2
+ spanLayer: Database
+ startTime: nq 0
+ endTime: nq 0
+ componentId: 87
+ isError: false
+ spanType: Exit
+ peer: mariadb-server:3306
+ skipAnalysis: 'false'
+ tags:
+ - {key: db.type, value: sql}
+ - {key: db.instance, value: test}
+ - {key: db.statement, value: "INSERT INTO test_table(id, value) VALUES(?,?)"}
+ - operationName: Mariadb/JDBI/PreparedStatement/execute
+ operationId: eq 0
+ parentSpanId: 0
+ spanId: 3
+ spanLayer: Database
+ startTime: nq 0
+ endTime: nq 0
+ componentId: 87
+ isError: false
+ spanType: Exit
+ peer: mariadb-server:3306
+ skipAnalysis: 'false'
+ tags:
+ - {key: db.type, value: sql}
+ - {key: db.instance, value: test}
+ - {key: db.statement, value: "SELECT id, value FROM test_table WHERE id = ?"}
+ - operationName: Mariadb/JDBI/Statement/execute
+ operationId: eq 0
+ parentSpanId: 0
+ spanId: 4
+ spanLayer: Database
+ startTime: nq 0
+ endTime: nq 0
+ componentId: 87
+ isError: false
+ spanType: Exit
+ peer: mariadb-server:3306
+ skipAnalysis: 'false'
+ tags:
+ - {key: db.type, value: sql}
+ - {key: db.instance, value: test}
+ - {key: db.statement, value: "DROP table test_table"}
+ - operationName: Mariadb/JDBI/Connection/close
+ operationId: eq 0
+ parentSpanId: 0
+ spanId: 5
+ spanLayer: Database
+ startTime: nq 0
+ endTime: nq 0
+ componentId: 87
+ isError: false
+ spanType: Exit
+ peer: mariadb-server:3306
+ skipAnalysis: 'false'
+ tags:
+ - {key: db.type, value: sql}
+ - {key: db.instance, value: test}
+ - {key: db.statement, value: ''}
+ - operationName: /mariadb-scenario/case/mariadb-scenario
+ operationId: eq 0
+ parentSpanId: -1
+ spanId: 0
+ startTime: nq 0
+ endTime: nq 0
+ spanLayer: Http
+ isError: false
+ spanType: Entry
+ peer: ''
+ componentId: 1
+ tags:
+ - {key: url, value: 'http://localhost:8080/mariadb-scenario/case/mariadb-scenario'}
+ - {key: http.method, value: GET}
+ logs: []
+ skipAnalysis: 'false'
diff --git a/test/plugin/scenarios/mariadb-scenario/configuration.yml b/test/plugin/scenarios/mariadb-scenario/configuration.yml
new file mode 100644
index 000000000..73e4c48c8
--- /dev/null
+++ b/test/plugin/scenarios/mariadb-scenario/configuration.yml
@@ -0,0 +1,32 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+type: jvm
+entryService: http://localhost:8080/mariadb-scenario/case/mariadb-scenario
+healthCheck: http://localhost:8080/mariadb-scenario/case/healthCheck
+startScript: ./bin/startup.sh
+environment:
+depends_on:
+ - mariadb-server
+dependencies:
+ mariadb-server:
+ image: mariadb:10.5.2
+ hostname: mariadb-server
+ expose:
+ - "3306"
+ environment:
+ - MYSQL_ROOT_PASSWORD=root
+ - MYSQL_DATABASE=test
diff --git a/test/plugin/scenarios/mariadb-scenario/pom.xml b/test/plugin/scenarios/mariadb-scenario/pom.xml
new file mode 100644
index 000000000..6e155ba16
--- /dev/null
+++ b/test/plugin/scenarios/mariadb-scenario/pom.xml
@@ -0,0 +1,120 @@
+
+
+
+
+ org.apache.skywalking.apm.testcase
+ mariadb-scenario
+ 1.0.0
+ jar
+
+ 4.0.0
+
+
+ UTF-8
+ 1.8
+
+ 2.6.0
+ ${test.framework.version}
+
+ 2.1.6.RELEASE
+
+
+ skywalking-mariadb-scenario
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot-version}
+ pom
+ import
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-logging
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-log4j2
+
+
+
+ org.mariadb.jdbc
+ mariadb-java-client
+ ${test.framework.version}
+
+
+
+
+ mariadb-scenario
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+ maven-compiler-plugin
+
+ ${compiler.version}
+ ${compiler.version}
+ ${project.build.sourceEncoding}
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ assemble
+ package
+
+ single
+
+
+
+ src/main/assembly/assembly.xml
+
+ ./target/
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/plugin/scenarios/mariadb-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/mariadb-scenario/src/main/assembly/assembly.xml
new file mode 100644
index 000000000..54b00bcbe
--- /dev/null
+++ b/test/plugin/scenarios/mariadb-scenario/src/main/assembly/assembly.xml
@@ -0,0 +1,41 @@
+
+
+
+
+ zip
+
+
+
+
+ ./bin
+ 0775
+
+
+
+
+
+ ${project.build.directory}/mariadb-scenario.jar
+ ./libs
+ 0775
+
+
+
diff --git a/test/plugin/scenarios/mariadb-scenario/src/main/java/org/apache/skywalking/apm/testcase/mariadb/Application.java b/test/plugin/scenarios/mariadb-scenario/src/main/java/org/apache/skywalking/apm/testcase/mariadb/Application.java
new file mode 100644
index 000000000..2c71b3bc9
--- /dev/null
+++ b/test/plugin/scenarios/mariadb-scenario/src/main/java/org/apache/skywalking/apm/testcase/mariadb/Application.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.testcase.mariadb;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+ private static final Logger logger = LogManager.getLogger(Application.class);
+
+ public static void main(String[] args) {
+ try {
+ SpringApplication.run(Application.class, args);
+ } catch (Exception ex) {
+ logger.error("Application start error", ex);
+ throw ex;
+ }
+ }
+}
diff --git a/test/plugin/scenarios/mariadb-scenario/src/main/java/org/apache/skywalking/apm/testcase/mariadb/MariadbConfig.java b/test/plugin/scenarios/mariadb-scenario/src/main/java/org/apache/skywalking/apm/testcase/mariadb/MariadbConfig.java
new file mode 100644
index 000000000..d4e873b0b
--- /dev/null
+++ b/test/plugin/scenarios/mariadb-scenario/src/main/java/org/apache/skywalking/apm/testcase/mariadb/MariadbConfig.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.testcase.mariadb;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+public class MariadbConfig {
+ private static Logger logger = LogManager.getLogger(MariadbConfig.class);
+ private static String url;
+ private static String userName;
+ private static String password;
+
+ static {
+ InputStream inputStream = MariadbConfig.class.getClassLoader().getResourceAsStream("/jdbc.properties");
+ Properties properties = new Properties();
+ try {
+ properties.load(inputStream);
+ } catch (IOException e) {
+ logger.error("Failed to load config", e);
+ }
+
+ url = properties.getProperty("mariadb.url");
+ userName = properties.getProperty("mariadb.username");
+ password = properties.getProperty("mariadb.password");
+ }
+
+ public static String getUrl() {
+ return url;
+ }
+
+ public static String getUserName() {
+ return userName;
+ }
+
+ public static String getPassword() {
+ return password;
+ }
+}
diff --git a/test/plugin/scenarios/mariadb-scenario/src/main/java/org/apache/skywalking/apm/testcase/mariadb/SQLExecutor.java b/test/plugin/scenarios/mariadb-scenario/src/main/java/org/apache/skywalking/apm/testcase/mariadb/SQLExecutor.java
new file mode 100644
index 000000000..e56b33f8a
--- /dev/null
+++ b/test/plugin/scenarios/mariadb-scenario/src/main/java/org/apache/skywalking/apm/testcase/mariadb/SQLExecutor.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.testcase.mariadb;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+public class SQLExecutor implements AutoCloseable {
+ private static Logger logger = LogManager.getLogger(SQLExecutor.class);
+ private Connection connection;
+
+ public SQLExecutor() throws SQLException {
+ try {
+ Class.forName("org.mariadb.jdbc.Driver");
+ } catch (ClassNotFoundException ex) {
+ logger.error(ex);
+ }
+ connection = DriverManager.getConnection(MariadbConfig.getUrl(), MariadbConfig.getUserName(), MariadbConfig.getPassword());
+ }
+
+ public void execute(String sql) throws SQLException {
+ Statement statement = connection.createStatement();
+ statement.execute(sql);
+ }
+
+ public void insertData(String sql, String id, String value) throws SQLException {
+ PreparedStatement preparedStatement = connection.prepareStatement(sql);
+ preparedStatement.setString(1, id);
+ preparedStatement.setString(2, value);
+ preparedStatement.execute();
+ }
+
+ public void queryData(String sql, String id) throws SQLException {
+ PreparedStatement preparedStatement = connection.prepareStatement(sql);
+ preparedStatement.setString(1, id);
+ preparedStatement.execute();
+ }
+
+ public void closeConnection() throws SQLException {
+ if (this.connection != null) {
+ this.connection.close();
+ }
+ }
+
+ @Override
+ public void close() throws Exception {
+ closeConnection();
+ }
+}
diff --git a/test/plugin/scenarios/mariadb-scenario/src/main/java/org/apache/skywalking/apm/testcase/mariadb/controller/CaseController.java b/test/plugin/scenarios/mariadb-scenario/src/main/java/org/apache/skywalking/apm/testcase/mariadb/controller/CaseController.java
new file mode 100644
index 000000000..72136c53b
--- /dev/null
+++ b/test/plugin/scenarios/mariadb-scenario/src/main/java/org/apache/skywalking/apm/testcase/mariadb/controller/CaseController.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.testcase.mariadb.controller;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.skywalking.apm.testcase.mariadb.SQLExecutor;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.sql.SQLException;
+
+@RestController
+@RequestMapping("/case")
+public class CaseController {
+
+ private static final Logger logger = LogManager.getLogger(CaseController.class);
+
+ private static final String SUCCESS = "Success";
+
+ private static final String CREATE_TABLE_SQL = "CREATE TABLE test_table(\n" + "id VARCHAR(1) PRIMARY KEY, \n" + "value VARCHAR(10) NOT NULL)";
+ private static final String INSERT_DATA_SQL = "INSERT INTO test_table(id, value) VALUES(?,?)";
+ private static final String QUERY_DATA_SQL = "SELECT id, value FROM test_table WHERE id = ?";
+ private static final String DELETE_DATA_SQL = "DELETE FROM test_table WHERE id=?";
+ private static final String DROP_TABLE_SQL = "DROP table test_table";
+
+ @RequestMapping("/mariadb-scenario")
+ @ResponseBody
+ public String testcase() throws Exception {
+ try (SQLExecutor sqlExecute = new SQLExecutor()) {
+ sqlExecute.execute(CREATE_TABLE_SQL);
+ sqlExecute.insertData(INSERT_DATA_SQL, "1", "value");
+ sqlExecute.queryData(QUERY_DATA_SQL, "1");
+ sqlExecute.execute(DROP_TABLE_SQL);
+ } catch (Exception ex) {
+ logger.error("Failed to execute sql.", ex);
+ throw ex;
+ }
+ return SUCCESS;
+ }
+
+ @RequestMapping("/healthCheck")
+ @ResponseBody
+ public String healthCheck() throws Exception {
+ return SUCCESS;
+ }
+
+}
diff --git a/test/plugin/scenarios/mariadb-scenario/src/main/resources/application.yaml b/test/plugin/scenarios/mariadb-scenario/src/main/resources/application.yaml
new file mode 100644
index 000000000..cb7ac89bb
--- /dev/null
+++ b/test/plugin/scenarios/mariadb-scenario/src/main/resources/application.yaml
@@ -0,0 +1,23 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+server:
+ port: 8080
+ servlet:
+ context-path: /mariadb-scenario
+logging:
+ config: classpath:log4j2.xml
diff --git a/test/plugin/scenarios/mariadb-scenario/src/main/resources/jdbc.properties b/test/plugin/scenarios/mariadb-scenario/src/main/resources/jdbc.properties
new file mode 100644
index 000000000..c494405b6
--- /dev/null
+++ b/test/plugin/scenarios/mariadb-scenario/src/main/resources/jdbc.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version
+# "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.
+mariadb.url=jdbc:mariadb://mariadb-server:3306/test
+mariadb.username=root
+mariadb.password=root
diff --git a/test/plugin/scenarios/mariadb-scenario/src/main/resources/log4j2.xml b/test/plugin/scenarios/mariadb-scenario/src/main/resources/log4j2.xml
new file mode 100644
index 000000000..b5cda5ae8
--- /dev/null
+++ b/test/plugin/scenarios/mariadb-scenario/src/main/resources/log4j2.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/plugin/scenarios/mariadb-scenario/support-version.list b/test/plugin/scenarios/mariadb-scenario/support-version.list
new file mode 100644
index 000000000..693cd2bd4
--- /dev/null
+++ b/test/plugin/scenarios/mariadb-scenario/support-version.list
@@ -0,0 +1,27 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version
+# "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.
+
+# lists your version here
+
+2.6.0
+2.5.4
+2.4.4
+2.3.0
+2.2.6
+2.1.2
+2.0.3
+1.8.0
+