Mariadb JDBC plugin (#4740)
* Add Mariadb JDBC plugin and provide tests
* Refactor component name
* Reformat plugin description and remove healthcheck span from the test
Co-authored-by: Efe Kaptan <Efe.Kaptan@webtrekk.com>
Co-authored-by: zhang-wei <pknfe@outlook.com>
Co-authored-by: 吴晟 Wu Sheng <wu.sheng@foxmail.com>
diff --git a/.github/workflows/plugins-test.3.yaml b/.github/workflows/plugins-test.3.yaml
index 42069a5..d06107e 100644
--- a/.github/workflows/plugins-test.3.yaml
+++ b/.github/workflows/plugins-test.3.yaml
@@ -43,6 +43,7 @@
- { 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 136ebb6..c608ae3 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 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 764e514..8a4990d 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 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.
+ * <p>
+ * 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 bdb890a..d641ca6 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 ElementMatcher<MethodDescription> getMethodsMatcher() {
ElementMatcher.Junction<MethodDescription> 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<String> 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 0000000..1209b80
--- /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 0000000..65b21e6
--- /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 7b86ea7..d4ca1b8 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 @@
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 @@
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 9058065..12c6e04 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 @@
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 @@
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 0000000..11d6fa3
--- /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 50b9f50..b832b45 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 @@
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 0000000..0288fbe
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/pom.xml
@@ -0,0 +1,61 @@
+<!--
+ ~ 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.
+ ~
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>apm-sdk-plugin</artifactId>
+ <groupId>org.apache.skywalking</groupId>
+ <version>8.0.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>apm-mariadb-2.x-plugin</artifactId>
+ <packaging>jar</packaging>
+
+ <name>mariadb-2.x-plugin</name>
+ <url>http://maven.apache.org</url>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <mariadb-java-client.version>2.6.0</mariadb-java-client.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.mariadb.jdbc</groupId>
+ <artifactId>mariadb-java-client</artifactId>
+ <version>${mariadb-java-client.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.skywalking</groupId>
+ <artifactId>apm-jdbc-commons</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
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 0000000..8e717a6
--- /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 0000000..212b388
--- /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 0000000..3b286a6
--- /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 0000000..5113af0
--- /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 0000000..c17d94a
--- /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 0000000..8c25279
--- /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 0000000..8f636ce
--- /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 0000000..45ddf69
--- /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<MethodDescription> 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<MethodDescription> 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<MethodDescription> 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<MethodDescription> 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<MethodDescription> 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 0000000..f59ef43
--- /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 0000000..17f528e
--- /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 0000000..c1b1afe
--- /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<MethodDescription> 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 0000000..e4cb3ec
--- /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 0000000..7f58dfd
--- /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 0000000..8d7bfbd
--- /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<MethodDescription> 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 0000000..65c37bf
--- /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 0000000..5979c2c
--- /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 0000000..4141c04
--- /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 0000000..6292a4b
--- /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 0000000..8742842
--- /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 0000000..9b877bb
--- /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 91b0186..fa0613a 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.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 @@
@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 @@
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 @@
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 @@
@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 @@
@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 @@
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 2db840d..1c9d9d2 100644
--- a/apm-sniffer/apm-sdk-plugin/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/pom.xml
@@ -88,6 +88,7 @@
<module>lettuce-5.x-plugin</module>
<module>avro-plugin</module>
<module>finagle-6.25.x-plugin</module>
+ <module>mariadb-2.x-plugin</module>
</modules>
<packaging>pom</packaging>
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 5a76cf3..151c37e 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.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 @@
@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 @@
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 @@
@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 @@
@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 @@
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 acd80bf..a1b4f60 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 @@
`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 735f185..abb8533 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 04d8298..9de8925 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 @@
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 @@
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 643b0b2..44a9d12 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 @@
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 @@
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 0000000..5885885
--- /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 0000000..37e1b34
--- /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 0000000..73e4c48
--- /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 0000000..6e155ba
--- /dev/null
+++ b/test/plugin/scenarios/mariadb-scenario/pom.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ ~
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <groupId>org.apache.skywalking.apm.testcase</groupId>
+ <artifactId>mariadb-scenario</artifactId>
+ <version>1.0.0</version>
+ <packaging>jar</packaging>
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <compiler.version>1.8</compiler.version>
+
+ <test.framework.version>2.6.0</test.framework.version>
+ <docker.image.version>${test.framework.version}</docker.image.version>
+
+ <spring-boot-version>2.1.6.RELEASE</spring-boot-version>
+ </properties>
+
+ <name>skywalking-mariadb-scenario</name>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-dependencies</artifactId>
+ <version>${spring-boot-version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-log4j2</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.mariadb.jdbc</groupId>
+ <artifactId>mariadb-java-client</artifactId>
+ <version>${test.framework.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>mariadb-scenario</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>${compiler.version}</source>
+ <target>${compiler.version}</target>
+ <encoding>${project.build.sourceEncoding}</encoding>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>assemble</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptors>
+ <descriptor>src/main/assembly/assembly.xml</descriptor>
+ </descriptors>
+ <outputDirectory>./target/</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
\ 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 0000000..54b00bc
--- /dev/null
+++ b/test/plugin/scenarios/mariadb-scenario/src/main/assembly/assembly.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ ~
+ -->
+<assembly
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+ <formats>
+ <format>zip</format>
+ </formats>
+
+ <fileSets>
+ <fileSet>
+ <directory>./bin</directory>
+ <fileMode>0775</fileMode>
+ </fileSet>
+ </fileSets>
+
+ <files>
+ <file>
+ <source>${project.build.directory}/mariadb-scenario.jar</source>
+ <outputDirectory>./libs</outputDirectory>
+ <fileMode>0775</fileMode>
+ </file>
+ </files>
+</assembly>
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 0000000..2c71b3b
--- /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 0000000..d4e873b
--- /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 0000000..e56b33f
--- /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 0000000..72136c5
--- /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 0000000..cb7ac89
--- /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 0000000..c494405
--- /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 0000000..b5cda5a
--- /dev/null
+++ b/test/plugin/scenarios/mariadb-scenario/src/main/resources/log4j2.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ ~
+ -->
+<Configuration status="WARN">
+ <Appenders>
+ <Console name="Console" target="SYSTEM_ERR">
+ <PatternLayout charset="UTF-8" pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
+ </Console>
+ </Appenders>
+ <Loggers>
+ <Root level="WARN">
+ <AppenderRef ref="Console"/>
+ </Root>
+ </Loggers>
+</Configuration>
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 0000000..693cd2b
--- /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
+