diff --git a/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/HttpClientExecuteInterceptor.java b/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/HttpClientExecuteInterceptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..335065b19131127027c83dc841d2176b1f1c1019
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/HttpClientExecuteInterceptor.java
@@ -0,0 +1,84 @@
+package com.a.eye.skywalking.plugin.httpClient.v4;
+
+
+import com.a.eye.skywalking.api.context.ContextCarrier;
+import com.a.eye.skywalking.api.context.ContextManager;
+import com.a.eye.skywalking.api.plugin.interceptor.EnhancedClassInstanceContext;
+import com.a.eye.skywalking.api.plugin.interceptor.enhance.InstanceMethodInvokeContext;
+import com.a.eye.skywalking.api.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import com.a.eye.skywalking.api.plugin.interceptor.enhance.MethodInterceptResult;
+import com.a.eye.skywalking.trace.Span;
+import com.a.eye.skywalking.trace.tag.Tags;
+
+import org.apache.http.Header;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+
+/**
+ * {@link HttpClientExecuteInterceptor} create span and set the serialized context
+ * data to {@link HttpRequest#setHeader(Header)} by using {@link #HEADER_NAME_OF_CONTEXT_DATA} for the header key.
+ *
+ * @author zhangxin
+ */
+public class HttpClientExecuteInterceptor implements InstanceMethodsAroundInterceptor {
+ public static final String HEADER_NAME_OF_CONTEXT_DATA = "SKYWALKING_CONTEXT_DATA";
+
+ @Override
+ public void beforeMethod(EnhancedClassInstanceContext context,
+ InstanceMethodInvokeContext interceptorContext, MethodInterceptResult result) {
+ Object[] allArguments = interceptorContext.allArguments();
+ if (allArguments[0] == null || allArguments[1] == null) {
+ // illegal args, can't trace. ignore.
+ return;
+ }
+ HttpHost httpHost = (HttpHost) allArguments[0];
+ HttpRequest httpRequest = (HttpRequest) allArguments[1];
+
+ Span span = ContextManager.INSTANCE.createSpan(httpRequest.getRequestLine().getUri());
+ Tags.PEER_PORT.set(span, httpHost.getPort());
+ Tags.PEER_HOST.set(span, httpHost.getHostName());
+ Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT);
+ Tags.URL.set(span, generateURL(httpHost, httpRequest));
+ Tags.SPAN_LAYER.asHttp(span);
+
+ ContextCarrier contextCarrier = new ContextCarrier();
+ ContextManager.INSTANCE.inject(contextCarrier);
+ httpRequest.setHeader(HEADER_NAME_OF_CONTEXT_DATA, contextCarrier.serialize());
+ }
+
+ /**
+ * Generate request URL by using {@link HttpRequest} and {@link HttpHost}
+ *
+ * @return request URL
+ */
+ private String generateURL(HttpHost httpHost, HttpRequest httpRequest) {
+ return httpHost.getSchemeName() + "://" + httpHost.getHostName() + ":" + httpHost.getPort() + httpRequest.getRequestLine().getUri();
+ }
+
+ @Override
+ public Object afterMethod(EnhancedClassInstanceContext context,
+ InstanceMethodInvokeContext interceptorContext, Object ret) {
+ Object[] allArguments = interceptorContext.allArguments();
+ if (allArguments[0] == null || allArguments[1] == null) {
+ return ret;
+ }
+
+ HttpResponse response = (HttpResponse) ret;
+ int statusCode = response.getStatusLine().getStatusCode();
+ Span span = ContextManager.INSTANCE.activeSpan();
+ if (statusCode != 200) {
+ Tags.ERROR.set(span, true);
+ }
+
+ Tags.STATUS_CODE.set(span, statusCode);
+ ContextManager.INSTANCE.stopSpan();
+ return ret;
+ }
+
+ @Override
+ public void handleMethodException(Throwable t, EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext) {
+ ContextManager.INSTANCE.activeSpan().log(t);
+ }
+
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/define/AbstractHttpClientInstrumentation.java b/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/define/AbstractHttpClientInstrumentation.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a2a8eb23f26eaae1b546738d39cc65370154f16
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/define/AbstractHttpClientInstrumentation.java
@@ -0,0 +1,53 @@
+package com.a.eye.skywalking.plugin.httpClient.v4.define;
+
+
+import com.a.eye.skywalking.api.plugin.interceptor.InstanceMethodsInterceptPoint;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.protocol.HttpContext;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
+/**
+ * {@link AbstractHttpClientInstrumentation} presents that skywalking will intercept
+ * {@link org.apache.http.impl.client.AbstractHttpClient#doExecute(HttpHost, HttpRequest, HttpContext)}
+ * by using {@link HttpClientInstrumentation#INTERCEPT_CLASS}.
+ *
+ * @author zhangxin
+ */
+public class AbstractHttpClientInstrumentation extends HttpClientInstrumentation {
+
+ /**
+ * enhance class.
+ */
+ private static final String ENHANCE_CLASS = "org.apache.http.impl.client.AbstractHttpClient";
+
+ @Override
+ public String enhanceClassName() {
+ return ENHANCE_CLASS;
+ }
+
+ /**
+ * version 4.2, intercept method: execute, intercept
+ * public final HttpResponse execute(HttpHost target, HttpRequest request,
+ * HttpContext context)
+ */
+ @Override
+ protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return named("doExecute");
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return getInstanceMethodsInterceptor();
+ }
+ }};
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/define/DefaultRequestDirectorInstrumentation.java b/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/define/DefaultRequestDirectorInstrumentation.java
new file mode 100644
index 0000000000000000000000000000000000000000..d0fb67722dca74749e4a3b9c4d53c6e65e936c8e
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/define/DefaultRequestDirectorInstrumentation.java
@@ -0,0 +1,53 @@
+package com.a.eye.skywalking.plugin.httpClient.v4.define;
+
+
+import com.a.eye.skywalking.api.plugin.interceptor.InstanceMethodsInterceptPoint;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.protocol.HttpContext;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
+/**
+ * {@link AbstractHttpClientInstrumentation} presents that skywalking will intercept
+ * {@link org.apache.http.impl.client.DefaultRequestDirector#execute(HttpHost, HttpRequest, HttpContext)}
+ * by using {@link HttpClientInstrumentation#INTERCEPT_CLASS}.
+ *
+ * @author zhangxin
+ */
+public class DefaultRequestDirectorInstrumentation extends HttpClientInstrumentation {
+
+ /**
+ * Enhance class.
+ */
+ private static final String enhanceClass = "org.apache.http.impl.client.DefaultRequestDirector";
+
+ /**
+ * DefaultRequestDirector is default implement.
+ * usually use in version 4.0-4.2
+ * since 4.3, this class is Deprecated.
+ */
+ @Override
+ public String enhanceClassName() {
+ return enhanceClass;
+ }
+
+ @Override
+ protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return named("execute");
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return getInstanceMethodsInterceptor();
+ }
+ }};
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/define/HttpClientInstrumentation.java b/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/define/HttpClientInstrumentation.java
new file mode 100644
index 0000000000000000000000000000000000000000..8d7214427fa7855a07b2ee7b5d87e28ae636d2e6
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/define/HttpClientInstrumentation.java
@@ -0,0 +1,28 @@
+package com.a.eye.skywalking.plugin.httpClient.v4.define;
+
+
+import com.a.eye.skywalking.api.plugin.interceptor.ConstructorInterceptPoint;
+import com.a.eye.skywalking.api.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+
+/**
+ * {@link HttpClientInstrumentation} present that skywalking will intercept {@link HttpClientInstrumentation#enhanceClassName()}
+ * by using {@link com.a.eye.skywalking.plugin.httpClient.v4.HttpClientExecuteInterceptor}
+ *
+ * @author zhangxin
+ */
+public abstract class HttpClientInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+
+ /**
+ * Intercept class.
+ */
+ private static final String INTERCEPT_CLASS = "com.a.eye.skywalking.plugin.httpClient.v4.HttpClientExecuteInterceptor";
+
+ @Override
+ protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return null;
+ }
+
+ protected String getInstanceMethodsInterceptor() {
+ return INTERCEPT_CLASS;
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/define/InternalHttpClientInstrumentation.java b/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/define/InternalHttpClientInstrumentation.java
new file mode 100644
index 0000000000000000000000000000000000000000..b0ea0c262fc9282ede8a2af6ef1fbf4c22d51196
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/define/InternalHttpClientInstrumentation.java
@@ -0,0 +1,47 @@
+package com.a.eye.skywalking.plugin.httpClient.v4.define;
+
+
+import com.a.eye.skywalking.api.plugin.interceptor.InstanceMethodsInterceptPoint;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.protocol.HttpContext;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
+/**
+ * {@link AbstractHttpClientInstrumentation} presents that skywalking will intercept {@link org.apache.http.impl.client.InternalHttpClient#doExecute(HttpHost, HttpRequest, HttpContext)}
+ * by using {@link HttpClientInstrumentation#INTERCEPT_CLASS}.
+ *
+ * @author zhangxin
+ */
+public class InternalHttpClientInstrumentation extends HttpClientInstrumentation {
+
+ /**
+ * Enhance class.
+ */
+ private static final String ENHANCE_CLASS = "org.apache.http.impl.client.InternalHttpClient";
+
+ @Override
+ public String enhanceClassName() {
+ return ENHANCE_CLASS;
+ }
+
+ @Override
+ protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return named("doExecute");
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return getInstanceMethodsInterceptor();
+ }
+ }};
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/define/MinimalHttpClientInstrumentation.java b/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/define/MinimalHttpClientInstrumentation.java
new file mode 100644
index 0000000000000000000000000000000000000000..95b98d86797106bf570b1d905777756ef6ada80f
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/httpClient-4.x-plugin/src/main/java/com/a/eye/skywalking/plugin/httpClient/v4/define/MinimalHttpClientInstrumentation.java
@@ -0,0 +1,48 @@
+package com.a.eye.skywalking.plugin.httpClient.v4.define;
+
+
+import com.a.eye.skywalking.api.plugin.interceptor.InstanceMethodsInterceptPoint;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.protocol.HttpContext;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
+/**
+ * {@link AbstractHttpClientInstrumentation} presents that skywalking will
+ * intercept {@link org.apache.http.impl.client.MinimalHttpClient#doExecute(HttpHost, HttpRequest, HttpContext)}
+ * by using {@link HttpClientInstrumentation#INTERCEPT_CLASS}.
+ *
+ * @author zhangxin
+ */
+public class MinimalHttpClientInstrumentation extends HttpClientInstrumentation {
+
+ /**
+ * Enhance class.
+ */
+ private static final String ENHANCE_CLASS = "org.apache.http.impl.client.MinimalHttpClient";
+
+ @Override
+ public String enhanceClassName() {
+ return ENHANCE_CLASS;
+ }
+
+ @Override
+ protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return named("doExecute");
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return getInstanceMethodsInterceptor();
+ }
+ }};
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/CallableStatementTracing.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/CallableStatementTracing.java
new file mode 100644
index 0000000000000000000000000000000000000000..c295c3676c9e04974cb01e7d6f15fa23d7ce5309
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/CallableStatementTracing.java
@@ -0,0 +1,51 @@
+package com.a.eye.skywalking.plugin.jdbc;
+
+
+import com.a.eye.skywalking.api.context.ContextManager;
+import com.a.eye.skywalking.api.util.StringUtil;
+import com.a.eye.skywalking.trace.Span;
+import com.a.eye.skywalking.trace.tag.Tags;
+
+import java.sql.SQLException;
+
+/**
+ * {@link CallableStatementTracing} create span with the {@link Span#operationName} start with
+ * "JDBC/CallableStatement/"and set {@link ConnectionInfo#dbType} to the {@link Tags#COMPONENT}.
+ *
+ * Notice: {@link Tags#PEERS} may be is null if database connection url don't contain multiple hosts.
+ *
+ * @author zhangxin
+ */
+public class CallableStatementTracing {
+
+ public static R execute(java.sql.CallableStatement realStatement,
+ ConnectionInfo connectInfo, String method, String sql, Executable exec)
+ throws SQLException {
+ try {
+ Span span = ContextManager.INSTANCE.createSpan("JDBC/CallableStatement/" + method);
+ Tags.DB_TYPE.set(span, "sql");
+ Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName());
+ Tags.DB_STATEMENT.set(span, sql);
+ Tags.COMPONENT.set(span, connectInfo.getDBType());
+ if (!StringUtil.isEmpty(connectInfo.getHosts())) {
+ Tags.PEERS.set(span, connectInfo.getHosts());
+ } else {
+ Tags.PEER_PORT.set(span, connectInfo.getPort());
+ Tags.PEER_HOST.set(span, connectInfo.getHost());
+ }
+ return exec.exe(realStatement, sql);
+ } catch (SQLException e) {
+ Span span = ContextManager.INSTANCE.activeSpan();
+ Tags.ERROR.set(span, true);
+ span.log(e);
+ throw e;
+ } finally {
+ ContextManager.INSTANCE.stopSpan();
+ }
+ }
+
+ public interface Executable {
+ R exe(java.sql.CallableStatement realConnection, String sql)
+ throws SQLException;
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/ConnectionInfo.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/ConnectionInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..3cf0a3d28ca412308126d58de88cfac8c4eba0ab
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/ConnectionInfo.java
@@ -0,0 +1,63 @@
+package com.a.eye.skywalking.plugin.jdbc;
+
+/**
+ * {@link ConnectionInfo} stored the jdbc connection info, the connection info contains db type, host, port, database name.
+ * The {@link #hosts} be null if {@link #host} is not null.
+ *
+ * @author zhangxin
+ */
+public class ConnectionInfo {
+ /**
+ * DB type, such as mysql, oracle, h2.
+ */
+ private final String dbType;
+ /**
+ * Database host name.
+ */
+ private String host;
+ /**
+ * Database port.
+ */
+ private int port;
+ /**
+ * Operation database name.
+ */
+ private final String databaseName;
+ /**
+ * Database hosts.
+ */
+ private String hosts;
+
+ public ConnectionInfo(String dbType, String host, int port, String databaseName) {
+ this.dbType = dbType;
+ this.host = host;
+ this.port = port;
+ this.databaseName = databaseName;
+ }
+
+ public ConnectionInfo(String dbType, String hosts, String databaseName) {
+ this.dbType = dbType;
+ this.hosts = hosts;
+ this.databaseName = databaseName;
+ }
+
+ public String getDBType() {
+ return dbType;
+ }
+
+ public String getHost() {
+ return host;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public String getDatabaseName() {
+ return databaseName;
+ }
+
+ public String getHosts() {
+ return hosts;
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/ConnectionTracing.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/ConnectionTracing.java
new file mode 100755
index 0000000000000000000000000000000000000000..35d7417e41096f8d2d936b13ca6728189661138d
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/ConnectionTracing.java
@@ -0,0 +1,51 @@
+package com.a.eye.skywalking.plugin.jdbc;
+
+
+import com.a.eye.skywalking.api.context.ContextManager;
+import com.a.eye.skywalking.api.util.StringUtil;
+import com.a.eye.skywalking.trace.Span;
+import com.a.eye.skywalking.trace.tag.Tags;
+
+import java.sql.SQLException;
+
+/**
+ * {@link ConnectionTracing} create span with the {@link Span#operationName} start with
+ * "JDBC/Connection/"and set {@link ConnectionInfo#dbType} to the {@link Tags#COMPONENT}.
+ *
+ * Notice: {@link Tags#PEERS} may be is null if database connection url don't contain multiple hosts.
+ *
+ * @author zhangxin
+ */
+public class ConnectionTracing {
+
+ public static R execute(java.sql.Connection realConnection,
+ ConnectionInfo connectInfo, String method, String sql, Executable exec)
+ throws SQLException {
+ try {
+ Span span = ContextManager.INSTANCE.createSpan("JDBC/Connection/" + method);
+ Tags.DB_TYPE.set(span, "sql");
+ Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName());
+ Tags.DB_STATEMENT.set(span, sql);
+ Tags.COMPONENT.set(span, connectInfo.getDBType());
+ if (!StringUtil.isEmpty(connectInfo.getHosts())) {
+ Tags.PEERS.set(span, connectInfo.getHosts());
+ } else {
+ Tags.PEER_PORT.set(span, connectInfo.getPort());
+ Tags.PEER_HOST.set(span, connectInfo.getHost());
+ }
+ return exec.exe(realConnection, sql);
+ } catch (SQLException e) {
+ Span span = ContextManager.INSTANCE.activeSpan();
+ Tags.ERROR.set(span, true);
+ span.log(e);
+ throw e;
+ } finally {
+ ContextManager.INSTANCE.stopSpan();
+ }
+ }
+
+ public interface Executable {
+ R exe(java.sql.Connection realConnection, String sql)
+ throws SQLException;
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/PreparedStatementTracing.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/PreparedStatementTracing.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed181b94a139e2a626e7a7f5353402e8ac2411a5
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/PreparedStatementTracing.java
@@ -0,0 +1,50 @@
+package com.a.eye.skywalking.plugin.jdbc;
+
+import com.a.eye.skywalking.api.context.ContextManager;
+import com.a.eye.skywalking.api.util.StringUtil;
+import com.a.eye.skywalking.trace.Span;
+import com.a.eye.skywalking.trace.tag.Tags;
+
+import java.sql.SQLException;
+
+/**
+ * {@link PreparedStatementTracing} create span with the {@link Span#operationName} start with
+ * "JDBC/PreparedStatement/"and set {@link ConnectionInfo#dbType} to the {@link Tags#COMPONENT}.
+ *
+ * Notice: {@link Tags#PEERS} may be is null if database connection url don't contain multiple hosts.
+ *
+ * @author zhangxin
+ */
+public class PreparedStatementTracing {
+
+ public static R execute(java.sql.PreparedStatement realStatement,
+ ConnectionInfo connectInfo, String method, String sql, Executable exec)
+ throws SQLException {
+ try {
+ Span span = ContextManager.INSTANCE.createSpan("JDBC/PreparedStatement/" + method);
+ Tags.DB_TYPE.set(span, "sql");
+ Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName());
+ Tags.DB_STATEMENT.set(span, sql);
+ Tags.COMPONENT.set(span, connectInfo.getDBType());
+ if (!StringUtil.isEmpty(connectInfo.getHosts())) {
+ Tags.PEERS.set(span, connectInfo.getHosts());
+ } else {
+ Tags.PEER_PORT.set(span, connectInfo.getPort());
+ Tags.PEER_HOST.set(span, connectInfo.getHost());
+ }
+ return exec.exe(realStatement, sql);
+ } catch (SQLException e) {
+ Span span = ContextManager.INSTANCE.activeSpan();
+ Tags.ERROR.set(span, true);
+ span.log(e);
+ throw e;
+ } finally {
+ ContextManager.INSTANCE.stopSpan();
+ }
+ }
+
+ public interface Executable {
+ R exe(java.sql.PreparedStatement realConnection, String sql)
+ throws SQLException;
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/SWCallableStatement.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/SWCallableStatement.java
new file mode 100644
index 0000000000000000000000000000000000000000..6b9fa5a6fdc9bac5f2925b57639f0f31655d4e96
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/SWCallableStatement.java
@@ -0,0 +1,1039 @@
+package com.a.eye.skywalking.plugin.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.util.Calendar;
+import java.util.Map;
+
+public class SWCallableStatement implements CallableStatement {
+ private Connection realConnection;
+ private CallableStatement realStatement;
+ private ConnectionInfo connectInfo;
+ private String sql;
+
+ SWCallableStatement(Connection realConnection,
+ CallableStatement realStatement, ConnectionInfo connectInfo,
+ String sql) {
+ this.realConnection = realConnection;
+ this.realStatement = realStatement;
+ this.connectInfo = connectInfo;
+ this.sql = sql;
+ }
+
+ public ResultSet executeQuery() throws SQLException {
+ return CallableStatementTracing.execute(realStatement, connectInfo,
+ "executeQuery", sql, new CallableStatementTracing.Executable() {
+ public ResultSet exe(
+ CallableStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeQuery();
+ }
+ });
+ }
+
+ public int executeUpdate() throws SQLException {
+ return CallableStatementTracing.execute(realStatement, connectInfo,
+ "executeUpdate", sql, new CallableStatementTracing.Executable() {
+ public Integer exe(
+ CallableStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeUpdate();
+ }
+ });
+ }
+
+ public void setNull(int parameterIndex, int sqlType) throws SQLException {
+ realStatement.setNull(parameterIndex, sqlType);
+ }
+
+ public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+ realStatement.setBoolean(parameterIndex, x);
+ }
+
+ public void setByte(int parameterIndex, byte x) throws SQLException {
+ realStatement.setByte(parameterIndex, x);
+ }
+
+ public void setShort(int parameterIndex, short x) throws SQLException {
+ realStatement.setShort(parameterIndex, x);
+ }
+
+ public void setInt(int parameterIndex, int x) throws SQLException {
+ realStatement.setInt(parameterIndex, x);
+ }
+
+ public void setLong(int parameterIndex, long x) throws SQLException {
+ realStatement.setLong(parameterIndex, x);
+ }
+
+ public void setFloat(int parameterIndex, float x) throws SQLException {
+ realStatement.setFloat(parameterIndex, x);
+ }
+
+ public void setDouble(int parameterIndex, double x) throws SQLException {
+ realStatement.setDouble(parameterIndex, x);
+ }
+
+ public void setBigDecimal(int parameterIndex, BigDecimal x)
+ throws SQLException {
+ realStatement.setBigDecimal(parameterIndex, x);
+ }
+
+ public void setString(int parameterIndex, String x) throws SQLException {
+ realStatement.setString(parameterIndex, x);
+ }
+
+ public void setBytes(int parameterIndex, byte[] x) throws SQLException {
+ realStatement.setBytes(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x) throws SQLException {
+ realStatement.setDate(parameterIndex, x);
+ }
+
+ public void setTime(int parameterIndex, Time x) throws SQLException {
+ realStatement.setTime(parameterIndex, x);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x)
+ throws SQLException {
+ realStatement.setTimestamp(parameterIndex, x);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, int length)
+ throws SQLException {
+ realStatement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ @Deprecated
+ public void setUnicodeStream(int parameterIndex, InputStream x, int length)
+ throws SQLException {
+ realStatement.setUnicodeStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, int length)
+ throws SQLException {
+ realStatement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void clearParameters() throws SQLException {
+ realStatement.clearParameters();
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType)
+ throws SQLException {
+ realStatement.setObject(parameterIndex, x, targetSqlType);
+ }
+
+ public void setObject(int parameterIndex, Object x) throws SQLException {
+ realStatement.setObject(parameterIndex, x);
+ }
+
+ public boolean execute() throws SQLException {
+ return CallableStatementTracing.execute(realStatement, connectInfo,
+ "execute", sql, new CallableStatementTracing.Executable() {
+ public Boolean exe(
+ CallableStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.execute();
+ }
+ });
+ }
+
+ public void addBatch() throws SQLException {
+ realStatement.addBatch();
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, int length)
+ throws SQLException {
+ realStatement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setRef(int parameterIndex, Ref x) throws SQLException {
+ realStatement.setRef(parameterIndex, x);
+ }
+
+ public void setBlob(int parameterIndex, Blob x) throws SQLException {
+ realStatement.setBlob(parameterIndex, x);
+ }
+
+ public void setClob(int parameterIndex, Clob x) throws SQLException {
+ realStatement.setClob(parameterIndex, x);
+ }
+
+ public void setArray(int parameterIndex, Array x) throws SQLException {
+ realStatement.setArray(parameterIndex, x);
+ }
+
+ public ResultSetMetaData getMetaData() throws SQLException {
+ return realStatement.getMetaData();
+ }
+
+ public void setDate(int parameterIndex, Date x, Calendar cal)
+ throws SQLException {
+ realStatement.setDate(parameterIndex, x, cal);
+ }
+
+ public void setTime(int parameterIndex, Time x, Calendar cal)
+ throws SQLException {
+ realStatement.setTime(parameterIndex, x, cal);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
+ throws SQLException {
+ realStatement.setTimestamp(parameterIndex, x, cal);
+ }
+
+ public void setNull(int parameterIndex, int sqlType, String typeName)
+ throws SQLException {
+ realStatement.setNull(parameterIndex, sqlType, typeName);
+ }
+
+ public void setURL(int parameterIndex, URL x) throws SQLException {
+ realStatement.setURL(parameterIndex, x);
+ }
+
+ public ParameterMetaData getParameterMetaData() throws SQLException {
+ return realStatement.getParameterMetaData();
+ }
+
+ public void setRowId(int parameterIndex, RowId x) throws SQLException {
+ realStatement.setRowId(parameterIndex, x);
+ }
+
+ public void setNString(int parameterIndex, String value)
+ throws SQLException {
+ realStatement.setNString(parameterIndex, value);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value,
+ long length) throws SQLException {
+ realStatement.setNCharacterStream(parameterIndex, value, length);
+ }
+
+ public void setNClob(int parameterIndex, NClob value) throws SQLException {
+ realStatement.setNClob(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader, long length)
+ throws SQLException {
+ realStatement.setClob(parameterIndex, reader, length);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream, long length)
+ throws SQLException {
+ realStatement.setBlob(parameterIndex, inputStream, length);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader, long length)
+ throws SQLException {
+ realStatement.setNClob(parameterIndex, reader, length);
+ }
+
+ public void setSQLXML(int parameterIndex, SQLXML xmlObject)
+ throws SQLException {
+ realStatement.setSQLXML(parameterIndex, xmlObject);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType,
+ int scaleOrLength) throws SQLException {
+ realStatement
+ .setObject(parameterIndex, x, targetSqlType, scaleOrLength);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, long length)
+ throws SQLException {
+ realStatement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, long length)
+ throws SQLException {
+ realStatement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader,
+ long length) throws SQLException {
+ realStatement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x)
+ throws SQLException {
+ realStatement.setAsciiStream(parameterIndex, x);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x)
+ throws SQLException {
+ realStatement.setBinaryStream(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader)
+ throws SQLException {
+ realStatement.setCharacterStream(parameterIndex, reader);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value)
+ throws SQLException {
+ realStatement.setNCharacterStream(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader) throws SQLException {
+ realStatement.setClob(parameterIndex, reader);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream)
+ throws SQLException {
+ realStatement.setBlob(parameterIndex, inputStream);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+ realStatement.setNClob(parameterIndex, reader);
+ }
+
+ public ResultSet executeQuery(String sql) throws SQLException {
+ return CallableStatementTracing.execute(realStatement, connectInfo,
+ "executeQuery", sql, new CallableStatementTracing.Executable() {
+ public ResultSet exe(
+ CallableStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeQuery(sql);
+ }
+ });
+ }
+
+ public int executeUpdate(String sql) throws SQLException {
+ return CallableStatementTracing.execute(realStatement, connectInfo,
+ "executeUpdate", sql, new CallableStatementTracing.Executable() {
+ public Integer exe(
+ CallableStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeUpdate(sql);
+ }
+ });
+ }
+
+ public void close() throws SQLException {
+ realStatement.close();
+ }
+
+ public int getMaxFieldSize() throws SQLException {
+ return realStatement.getMaxFieldSize();
+ }
+
+ public void setMaxFieldSize(int max) throws SQLException {
+ realStatement.setMaxFieldSize(max);
+ }
+
+ public int getMaxRows() throws SQLException {
+ return realStatement.getMaxRows();
+ }
+
+ public void setMaxRows(int max) throws SQLException {
+ realStatement.setMaxRows(max);
+ }
+
+ public void setEscapeProcessing(boolean enable) throws SQLException {
+ realStatement.setEscapeProcessing(enable);
+ }
+
+ public int getQueryTimeout() throws SQLException {
+ return realStatement.getQueryTimeout();
+ }
+
+ public void setQueryTimeout(int seconds) throws SQLException {
+ realStatement.setQueryTimeout(seconds);
+ }
+
+ public void cancel() throws SQLException {
+ realStatement.cancel();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return realStatement.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ realStatement.clearWarnings();
+ }
+
+ public void setCursorName(String name) throws SQLException {
+ realStatement.setCursorName(name);
+ }
+
+ public boolean execute(String sql) throws SQLException {
+ return CallableStatementTracing.execute(realStatement, connectInfo,
+ "execute", sql, new CallableStatementTracing.Executable() {
+ public Boolean exe(
+ CallableStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.execute(sql);
+ }
+ });
+ }
+
+ public ResultSet getResultSet() throws SQLException {
+ return realStatement.getResultSet();
+ }
+
+ public int getUpdateCount() throws SQLException {
+ return realStatement.getUpdateCount();
+ }
+
+ public boolean getMoreResults() throws SQLException {
+ return realStatement.getMoreResults();
+ }
+
+ public void setFetchDirection(int direction) throws SQLException {
+ realStatement.setFetchDirection(direction);
+ }
+
+ public int getFetchDirection() throws SQLException {
+ return realStatement.getFetchDirection();
+ }
+
+ public void setFetchSize(int rows) throws SQLException {
+ realStatement.setFetchSize(rows);
+ }
+
+ public int getFetchSize() throws SQLException {
+ return realStatement.getFetchSize();
+ }
+
+ public int getResultSetConcurrency() throws SQLException {
+ return realStatement.getResultSetConcurrency();
+ }
+
+ public int getResultSetType() throws SQLException {
+ return realStatement.getResultSetType();
+ }
+
+ public void addBatch(String sql) throws SQLException {
+ realStatement.addBatch();
+ }
+
+ public void clearBatch() throws SQLException {
+ realStatement.clearBatch();
+ }
+
+ public int[] executeBatch() throws SQLException {
+ return CallableStatementTracing.execute(realStatement, connectInfo,
+ "executeBatch", "", new CallableStatementTracing.Executable() {
+ public int[] exe(
+ CallableStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeBatch();
+ }
+ });
+ }
+
+ public Connection getConnection() throws SQLException {
+ return this.realConnection;
+ }
+
+ public boolean getMoreResults(int current) throws SQLException {
+ return realStatement.getMoreResults(current);
+ }
+
+ public ResultSet getGeneratedKeys() throws SQLException {
+ return realStatement.getGeneratedKeys();
+ }
+
+ public int executeUpdate(String sql, final int autoGeneratedKeys)
+ throws SQLException {
+ return CallableStatementTracing.execute(realStatement, connectInfo,
+ "executeUpdate", sql, new CallableStatementTracing.Executable() {
+ public Integer exe(
+ CallableStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeUpdate(sql, autoGeneratedKeys);
+ }
+ });
+ }
+
+ public int executeUpdate(String sql, final int[] columnIndexes)
+ throws SQLException {
+ return CallableStatementTracing.execute(realStatement, connectInfo,
+ "executeUpdate", sql, new CallableStatementTracing.Executable() {
+ public Integer exe(
+ CallableStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeUpdate(sql, columnIndexes);
+ }
+ });
+ }
+
+ public int executeUpdate(String sql, final String[] columnNames)
+ throws SQLException {
+ return CallableStatementTracing.execute(realStatement, connectInfo,
+ "executeUpdate", sql, new CallableStatementTracing.Executable() {
+ public Integer exe(
+ CallableStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeUpdate(sql, columnNames);
+ }
+ });
+ }
+
+ public boolean execute(String sql, final int autoGeneratedKeys)
+ throws SQLException {
+ return CallableStatementTracing.execute(realStatement, connectInfo,
+ "execute", sql, new CallableStatementTracing.Executable() {
+ public Boolean exe(
+ CallableStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.execute(sql, autoGeneratedKeys);
+ }
+ });
+ }
+
+ public boolean execute(String sql, final int[] columnIndexes) throws SQLException {
+ return CallableStatementTracing.execute(realStatement, connectInfo,
+ "execute", sql, new CallableStatementTracing.Executable() {
+ public Boolean exe(
+ CallableStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.execute(sql, columnIndexes);
+ }
+ });
+ }
+
+ public boolean execute(String sql, final String[] columnNames)
+ throws SQLException {
+ return CallableStatementTracing.execute(realStatement, connectInfo,
+ "execute", sql, new CallableStatementTracing.Executable() {
+ public Boolean exe(
+ CallableStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.execute(sql, columnNames);
+ }
+ });
+ }
+
+ public int getResultSetHoldability() throws SQLException {
+ return realStatement.getResultSetHoldability();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return realStatement.isClosed();
+ }
+
+ public void setPoolable(boolean poolable) throws SQLException {
+ realStatement.setPoolable(poolable);
+ }
+
+ public boolean isPoolable() throws SQLException {
+ return realStatement.isPoolable();
+ }
+
+ public void closeOnCompletion() throws SQLException {
+ realStatement.closeOnCompletion();
+ }
+
+ public boolean isCloseOnCompletion() throws SQLException {
+ return realStatement.isCloseOnCompletion();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return realStatement.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return realStatement.isWrapperFor(iface);
+ }
+
+ public void registerOutParameter(int parameterIndex, int sqlType)
+ throws SQLException {
+ realStatement.registerOutParameter(parameterIndex, sqlType);
+ }
+
+ public void registerOutParameter(int parameterIndex, int sqlType, int scale)
+ throws SQLException {
+ realStatement.registerOutParameter(parameterIndex, sqlType, scale);
+ }
+
+ public boolean wasNull() throws SQLException {
+ return realStatement.wasNull();
+ }
+
+ public String getString(int parameterIndex) throws SQLException {
+ return realStatement.getString(parameterIndex);
+ }
+
+ public boolean getBoolean(int parameterIndex) throws SQLException {
+ return realStatement.getBoolean(parameterIndex);
+ }
+
+ public byte getByte(int parameterIndex) throws SQLException {
+ return realStatement.getByte(parameterIndex);
+ }
+
+ public short getShort(int parameterIndex) throws SQLException {
+ return realStatement.getShort(parameterIndex);
+ }
+
+ public int getInt(int parameterIndex) throws SQLException {
+ return realStatement.getInt(parameterIndex);
+ }
+
+ public long getLong(int parameterIndex) throws SQLException {
+ return realStatement.getLong(parameterIndex);
+ }
+
+ public float getFloat(int parameterIndex) throws SQLException {
+ return realStatement.getFloat(parameterIndex);
+ }
+
+ public double getDouble(int parameterIndex) throws SQLException {
+ return realStatement.getDouble(parameterIndex);
+ }
+
+ @Deprecated
+ public BigDecimal getBigDecimal(int parameterIndex, int scale)
+ throws SQLException {
+ return realStatement.getBigDecimal(parameterIndex, scale);
+ }
+
+ public byte[] getBytes(int parameterIndex) throws SQLException {
+ return realStatement.getBytes(parameterIndex);
+ }
+
+ public Date getDate(int parameterIndex) throws SQLException {
+ return realStatement.getDate(parameterIndex);
+ }
+
+ public Time getTime(int parameterIndex) throws SQLException {
+ return realStatement.getTime(parameterIndex);
+ }
+
+ public Timestamp getTimestamp(int parameterIndex) throws SQLException {
+ return realStatement.getTimestamp(parameterIndex);
+ }
+
+ public Object getObject(int parameterIndex) throws SQLException {
+ return realStatement.getObject(parameterIndex);
+ }
+
+ public BigDecimal getBigDecimal(int parameterIndex) throws SQLException {
+ return realStatement.getBigDecimal(parameterIndex);
+ }
+
+ public Object getObject(int parameterIndex, Map> map)
+ throws SQLException {
+ return realStatement.getObject(parameterIndex, map);
+ }
+
+ public Ref getRef(int parameterIndex) throws SQLException {
+ return realStatement.getRef(parameterIndex);
+ }
+
+ public Blob getBlob(int parameterIndex) throws SQLException {
+ return realStatement.getBlob(parameterIndex);
+ }
+
+ public Clob getClob(int parameterIndex) throws SQLException {
+ return realStatement.getClob(parameterIndex);
+ }
+
+ public Array getArray(int parameterIndex) throws SQLException {
+ return realStatement.getArray(parameterIndex);
+ }
+
+ public Date getDate(int parameterIndex, Calendar cal) throws SQLException {
+ return realStatement.getDate(parameterIndex, cal);
+ }
+
+ public Time getTime(int parameterIndex, Calendar cal) throws SQLException {
+ return realStatement.getTime(parameterIndex, cal);
+ }
+
+ public Timestamp getTimestamp(int parameterIndex, Calendar cal)
+ throws SQLException {
+ return realStatement.getTimestamp(parameterIndex, cal);
+ }
+
+ public void registerOutParameter(int parameterIndex, int sqlType,
+ String typeName) throws SQLException {
+ realStatement.registerOutParameter(parameterIndex, sqlType, typeName);
+ }
+
+ public void registerOutParameter(String parameterName, int sqlType)
+ throws SQLException {
+ realStatement.registerOutParameter(parameterName, sqlType);
+ }
+
+ public void registerOutParameter(String parameterName, int sqlType,
+ int scale) throws SQLException {
+ realStatement.registerOutParameter(parameterName, sqlType, scale);
+ }
+
+ public void registerOutParameter(String parameterName, int sqlType,
+ String typeName) throws SQLException {
+ realStatement.registerOutParameter(parameterName, sqlType, typeName);
+ }
+
+ public URL getURL(int parameterIndex) throws SQLException {
+ return realStatement.getURL(parameterIndex);
+ }
+
+ public void setURL(String parameterName, URL val) throws SQLException {
+ realStatement.setURL(parameterName, val);
+ }
+
+ public void setNull(String parameterName, int sqlType) throws SQLException {
+ realStatement.setNull(parameterName, sqlType);
+ }
+
+ public void setBoolean(String parameterName, boolean x) throws SQLException {
+ realStatement.setBoolean(parameterName, x);
+ }
+
+ public void setByte(String parameterName, byte x) throws SQLException {
+ realStatement.setByte(parameterName, x);
+ }
+
+ public void setShort(String parameterName, short x) throws SQLException {
+ realStatement.setShort(parameterName, x);
+ }
+
+ public void setInt(String parameterName, int x) throws SQLException {
+ realStatement.setInt(parameterName, x);
+ }
+
+ public void setLong(String parameterName, long x) throws SQLException {
+ realStatement.setLong(parameterName, x);
+ }
+
+ public void setFloat(String parameterName, float x) throws SQLException {
+ realStatement.setFloat(parameterName, x);
+ }
+
+ public void setDouble(String parameterName, double x) throws SQLException {
+ realStatement.setDouble(parameterName, x);
+ }
+
+ public void setBigDecimal(String parameterName, BigDecimal x)
+ throws SQLException {
+ realStatement.setBigDecimal(parameterName, x);
+ }
+
+ public void setString(String parameterName, String x) throws SQLException {
+ realStatement.setString(parameterName, x);
+ }
+
+ public void setBytes(String parameterName, byte[] x) throws SQLException {
+ realStatement.setBytes(parameterName, x);
+ }
+
+ public void setDate(String parameterName, Date x) throws SQLException {
+ realStatement.setDate(parameterName, x);
+ }
+
+ public void setTime(String parameterName, Time x) throws SQLException {
+ realStatement.setTime(parameterName, x);
+ }
+
+ public void setTimestamp(String parameterName, Timestamp x)
+ throws SQLException {
+ realStatement.setTimestamp(parameterName, x);
+ }
+
+ public void setAsciiStream(String parameterName, InputStream x, int length)
+ throws SQLException {
+ realStatement.setAsciiStream(parameterName, x, length);
+ }
+
+ public void setBinaryStream(String parameterName, InputStream x, int length)
+ throws SQLException {
+ realStatement.setBinaryStream(parameterName, x, length);
+ }
+
+ public void setObject(String parameterName, Object x, int targetSqlType,
+ int scale) throws SQLException {
+ realStatement.setObject(parameterName, x, targetSqlType, scale);
+ }
+
+ public void setObject(String parameterName, Object x, int targetSqlType)
+ throws SQLException {
+ realStatement.setObject(parameterName, x, targetSqlType);
+ }
+
+ public void setObject(String parameterName, Object x) throws SQLException {
+ realStatement.setObject(parameterName, x);
+ }
+
+ public void setCharacterStream(String parameterName, Reader reader,
+ int length) throws SQLException {
+ realStatement.setCharacterStream(parameterName, reader, length);
+ }
+
+ public void setDate(String parameterName, Date x, Calendar cal)
+ throws SQLException {
+ realStatement.setDate(parameterName, x, cal);
+ }
+
+ public void setTime(String parameterName, Time x, Calendar cal)
+ throws SQLException {
+ realStatement.setTime(parameterName, x, cal);
+ }
+
+ public void setTimestamp(String parameterName, Timestamp x, Calendar cal)
+ throws SQLException {
+ realStatement.setTimestamp(parameterName, x, cal);
+ }
+
+ public void setNull(String parameterName, int sqlType, String typeName)
+ throws SQLException {
+ realStatement.setNull(parameterName, sqlType, typeName);
+ }
+
+ public String getString(String parameterName) throws SQLException {
+ return realStatement.getString(parameterName);
+ }
+
+ public boolean getBoolean(String parameterName) throws SQLException {
+ return realStatement.getBoolean(parameterName);
+ }
+
+ public byte getByte(String parameterName) throws SQLException {
+ return realStatement.getByte(parameterName);
+ }
+
+ public short getShort(String parameterName) throws SQLException {
+ return realStatement.getShort(parameterName);
+ }
+
+ public int getInt(String parameterName) throws SQLException {
+ return realStatement.getInt(parameterName);
+ }
+
+ public long getLong(String parameterName) throws SQLException {
+ return realStatement.getLong(parameterName);
+ }
+
+ public float getFloat(String parameterName) throws SQLException {
+ return realStatement.getFloat(parameterName);
+ }
+
+ public double getDouble(String parameterName) throws SQLException {
+ return realStatement.getDouble(parameterName);
+ }
+
+ public byte[] getBytes(String parameterName) throws SQLException {
+ return realStatement.getBytes(parameterName);
+ }
+
+ public Date getDate(String parameterName) throws SQLException {
+ return realStatement.getDate(parameterName);
+ }
+
+ public Time getTime(String parameterName) throws SQLException {
+ return realStatement.getTime(parameterName);
+ }
+
+ public Timestamp getTimestamp(String parameterName) throws SQLException {
+ return realStatement.getTimestamp(parameterName);
+ }
+
+ public Object getObject(String parameterName) throws SQLException {
+ return realStatement.getObject(parameterName);
+ }
+
+ public BigDecimal getBigDecimal(String parameterName) throws SQLException {
+ return realStatement.getBigDecimal(parameterName);
+ }
+
+ public Object getObject(String parameterName, Map> map)
+ throws SQLException {
+ return realStatement.getObject(parameterName, map);
+ }
+
+ public Ref getRef(String parameterName) throws SQLException {
+ return realStatement.getRef(parameterName);
+ }
+
+ public Blob getBlob(String parameterName) throws SQLException {
+ return realStatement.getBlob(parameterName);
+ }
+
+ public Clob getClob(String parameterName) throws SQLException {
+ return realStatement.getClob(parameterName);
+ }
+
+ public Array getArray(String parameterName) throws SQLException {
+ return realStatement.getArray(parameterName);
+ }
+
+ public Date getDate(String parameterName, Calendar cal) throws SQLException {
+ return realStatement.getDate(parameterName, cal);
+ }
+
+ public Time getTime(String parameterName, Calendar cal) throws SQLException {
+ return realStatement.getTime(parameterName, cal);
+ }
+
+ public Timestamp getTimestamp(String parameterName, Calendar cal)
+ throws SQLException {
+ return realStatement.getTimestamp(parameterName, cal);
+ }
+
+ public URL getURL(String parameterName) throws SQLException {
+ return realStatement.getURL(parameterName);
+ }
+
+ public RowId getRowId(int parameterIndex) throws SQLException {
+ return realStatement.getRowId(parameterIndex);
+ }
+
+ public RowId getRowId(String parameterName) throws SQLException {
+ return realStatement.getRowId(parameterName);
+ }
+
+ public void setRowId(String parameterName, RowId x) throws SQLException {
+ realStatement.setRowId(parameterName, x);
+ }
+
+ public void setNString(String parameterName, String value)
+ throws SQLException {
+ realStatement.setNString(parameterName, value);
+ }
+
+ public void setNCharacterStream(String parameterName, Reader value,
+ long length) throws SQLException {
+ realStatement.setNCharacterStream(parameterName, value, length);
+ }
+
+ public void setNClob(String parameterName, NClob value) throws SQLException {
+ realStatement.setNClob(parameterName, value);
+ }
+
+ public void setClob(String parameterName, Reader reader, long length)
+ throws SQLException {
+ realStatement.setClob(parameterName, reader, length);
+ }
+
+ public void setBlob(String parameterName, InputStream inputStream,
+ long length) throws SQLException {
+ realStatement.setBlob(parameterName, inputStream, length);
+ }
+
+ public void setNClob(String parameterName, Reader reader, long length)
+ throws SQLException {
+ realStatement.setNClob(parameterName, reader, length);
+ }
+
+ public NClob getNClob(int parameterIndex) throws SQLException {
+ return realStatement.getNClob(parameterIndex);
+ }
+
+ public NClob getNClob(String parameterName) throws SQLException {
+ return realStatement.getNClob(parameterName);
+ }
+
+ public void setSQLXML(String parameterName, SQLXML xmlObject)
+ throws SQLException {
+ realStatement.setSQLXML(parameterName, xmlObject);
+ }
+
+ public SQLXML getSQLXML(int parameterIndex) throws SQLException {
+ return realStatement.getSQLXML(parameterIndex);
+ }
+
+ public SQLXML getSQLXML(String parameterName) throws SQLException {
+ return realStatement.getSQLXML(parameterName);
+ }
+
+ public String getNString(int parameterIndex) throws SQLException {
+ return realStatement.getNString(parameterIndex);
+ }
+
+ public String getNString(String parameterName) throws SQLException {
+ return realStatement.getNString(parameterName);
+ }
+
+ public Reader getNCharacterStream(int parameterIndex) throws SQLException {
+ return realStatement.getNCharacterStream(parameterIndex);
+ }
+
+ public Reader getNCharacterStream(String parameterName) throws SQLException {
+ return realStatement.getNCharacterStream(parameterName);
+ }
+
+ public Reader getCharacterStream(int parameterIndex) throws SQLException {
+ return realStatement.getCharacterStream(parameterIndex);
+ }
+
+ public Reader getCharacterStream(String parameterName) throws SQLException {
+ return realStatement.getCharacterStream(parameterName);
+ }
+
+ public void setBlob(String parameterName, Blob x) throws SQLException {
+ realStatement.setBlob(parameterName, x);
+ }
+
+ public void setClob(String parameterName, Clob x) throws SQLException {
+ realStatement.setClob(parameterName, x);
+ }
+
+ public void setAsciiStream(String parameterName, InputStream x, long length)
+ throws SQLException {
+ realStatement.setAsciiStream(parameterName, x, length);
+ }
+
+ public void setBinaryStream(String parameterName, InputStream x, long length)
+ throws SQLException {
+ realStatement.setBinaryStream(parameterName, x, length);
+ }
+
+ public void setCharacterStream(String parameterName, Reader reader,
+ long length) throws SQLException {
+ realStatement.setCharacterStream(parameterName, reader, length);
+ }
+
+ public void setAsciiStream(String parameterName, InputStream x)
+ throws SQLException {
+ realStatement.setAsciiStream(parameterName, x);
+ }
+
+ public void setBinaryStream(String parameterName, InputStream x)
+ throws SQLException {
+ realStatement.setBinaryStream(parameterName, x);
+ }
+
+ public void setCharacterStream(String parameterName, Reader reader)
+ throws SQLException {
+ realStatement.setCharacterStream(parameterName, reader);
+ }
+
+ public void setNCharacterStream(String parameterName, Reader value)
+ throws SQLException {
+ realStatement.setNCharacterStream(parameterName, value);
+ }
+
+ public void setClob(String parameterName, Reader reader)
+ throws SQLException {
+ realStatement.setClob(parameterName, reader);
+ }
+
+ public void setBlob(String parameterName, InputStream inputStream)
+ throws SQLException {
+ realStatement.setBlob(parameterName, inputStream);
+ }
+
+ public void setNClob(String parameterName, Reader reader)
+ throws SQLException {
+ realStatement.setNClob(parameterName, reader);
+ }
+
+ public T getObject(int parameterIndex, Class type)
+ throws SQLException {
+ return realStatement.getObject(parameterIndex, type);
+ }
+
+ public T getObject(String parameterName, Class type)
+ throws SQLException {
+ return realStatement.getObject(parameterName, type);
+ }
+
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/SWConnection.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/SWConnection.java
new file mode 100755
index 0000000000000000000000000000000000000000..919927cd7beefaedded1e89f184ecc59ea845eaa
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/SWConnection.java
@@ -0,0 +1,318 @@
+package com.a.eye.skywalking.plugin.jdbc;
+
+import com.a.eye.skywalking.plugin.jdbc.connectionurl.parser.URLParser;
+
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+public class SWConnection implements Connection {
+ private ConnectionInfo connectInfo;
+ private final Connection realConnection;
+
+ public SWConnection(String url, Properties info, Connection realConnection) {
+ super();
+ this.connectInfo = URLParser.parser(url);
+ this.realConnection = realConnection;
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return realConnection.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return realConnection.isWrapperFor(iface);
+ }
+
+ public Statement createStatement() throws SQLException {
+ return new SWStatement(this, realConnection.createStatement(),
+ this.connectInfo);
+ }
+
+ public PreparedStatement prepareStatement(String sql) throws SQLException {
+ return new SWPreparedStatement(this,
+ realConnection.prepareStatement(sql), this.connectInfo, sql);
+ }
+
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ return new SWCallableStatement(this, realConnection.prepareCall(sql),
+ this.connectInfo, sql);
+ }
+
+ public String nativeSQL(String sql) throws SQLException {
+ return realConnection.nativeSQL(sql);
+ }
+
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ realConnection.setAutoCommit(autoCommit);
+ }
+
+ public boolean getAutoCommit() throws SQLException {
+ return realConnection.getAutoCommit();
+ }
+
+ public void commit() throws SQLException {
+ ConnectionTracing.execute(realConnection, connectInfo, "commit", "",
+ new ConnectionTracing.Executable() {
+ public String exe(java.sql.Connection realConnection,
+ String sql) throws SQLException {
+ realConnection.commit();
+ return null;
+ }
+ });
+ }
+
+ public void rollback() throws SQLException {
+ ConnectionTracing.execute(realConnection, connectInfo, "rollback", "",
+ new ConnectionTracing.Executable() {
+ public String exe(java.sql.Connection realConnection,
+ String sql) throws SQLException {
+ realConnection.rollback();
+ return null;
+ }
+ });
+ }
+
+ public void close() throws SQLException {
+ ConnectionTracing.execute(realConnection, connectInfo, "close", "",
+ new ConnectionTracing.Executable() {
+ public String exe(java.sql.Connection realConnection,
+ String sql) throws SQLException {
+ realConnection.close();
+ return null;
+ }
+ });
+ }
+
+ public boolean isClosed() throws SQLException {
+ return realConnection.isClosed();
+ }
+
+ public DatabaseMetaData getMetaData() throws SQLException {
+ return realConnection.getMetaData();
+ }
+
+ public void setReadOnly(boolean readOnly) throws SQLException {
+ realConnection.setReadOnly(readOnly);
+ }
+
+ public boolean isReadOnly() throws SQLException {
+ return realConnection.isReadOnly();
+ }
+
+ public void setCatalog(String catalog) throws SQLException {
+ realConnection.setCatalog(catalog);
+ }
+
+ public String getCatalog() throws SQLException {
+ return realConnection.getCatalog();
+ }
+
+ public void setTransactionIsolation(int level) throws SQLException {
+ realConnection.setTransactionIsolation(level);
+ }
+
+ public int getTransactionIsolation() throws SQLException {
+ return realConnection.getTransactionIsolation();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return realConnection.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ realConnection.clearWarnings();
+ }
+
+ public Statement createStatement(int resultSetType, int resultSetConcurrency)
+ throws SQLException {
+ return new SWStatement(this, realConnection.createStatement(
+ resultSetType, resultSetConcurrency), this.connectInfo);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType,
+ int resultSetConcurrency) throws SQLException {
+ return new SWPreparedStatement(this, realConnection.prepareStatement(
+ sql, resultSetType, resultSetConcurrency), this.connectInfo,
+ sql);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType,
+ int resultSetConcurrency) throws SQLException {
+ return new SWCallableStatement(this, realConnection.prepareCall(sql,
+ resultSetType, resultSetConcurrency), this.connectInfo, sql);
+ }
+
+ public Map> getTypeMap() throws SQLException {
+ return realConnection.getTypeMap();
+ }
+
+ public void setTypeMap(Map> map) throws SQLException {
+ realConnection.setTypeMap(map);
+ }
+
+ public void setHoldability(int holdability) throws SQLException {
+ realConnection.setHoldability(holdability);
+ }
+
+ public int getHoldability() throws SQLException {
+ return realConnection.getHoldability();
+ }
+
+ public Savepoint setSavepoint() throws SQLException {
+ return realConnection.setSavepoint();
+ }
+
+ public Savepoint setSavepoint(String name) throws SQLException {
+ return realConnection.setSavepoint(name);
+ }
+
+ public void rollback(final Savepoint savepoint) throws SQLException {
+ ConnectionTracing.execute(realConnection, connectInfo,
+ "rollback to savepoint", "", new ConnectionTracing.Executable() {
+ public String exe(java.sql.Connection realConnection,
+ String sql) throws SQLException {
+ realConnection.rollback(savepoint);
+ return null;
+ }
+ });
+ }
+
+ public void releaseSavepoint(final Savepoint savepoint) throws SQLException {
+ ConnectionTracing.execute(realConnection, connectInfo,
+ "releaseSavepoint savepoint", "", new ConnectionTracing.Executable() {
+ public String exe(java.sql.Connection realConnection,
+ String sql) throws SQLException {
+ realConnection.releaseSavepoint(savepoint);
+ return null;
+ }
+ });
+ }
+
+ public Statement createStatement(int resultSetType,
+ int resultSetConcurrency, int resultSetHoldability)
+ throws SQLException {
+ return new SWStatement(this, realConnection.createStatement(
+ resultSetType, resultSetConcurrency, resultSetHoldability),
+ this.connectInfo);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int resultSetType,
+ int resultSetConcurrency, int resultSetHoldability)
+ throws SQLException {
+ return new SWPreparedStatement(this,
+ realConnection.prepareStatement(sql, resultSetType,
+ resultSetConcurrency, resultSetHoldability),
+ this.connectInfo, sql);
+ }
+
+ public CallableStatement prepareCall(String sql, int resultSetType,
+ int resultSetConcurrency, int resultSetHoldability)
+ throws SQLException {
+ return new SWCallableStatement(this, realConnection.prepareCall(sql,
+ resultSetType, resultSetConcurrency, resultSetHoldability), this.connectInfo, sql);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
+ throws SQLException {
+ return new SWPreparedStatement(this, realConnection.prepareStatement(
+ sql, autoGeneratedKeys), this.connectInfo, sql);
+ }
+
+ public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
+ throws SQLException {
+ return new SWPreparedStatement(this, realConnection.prepareStatement(
+ sql, columnIndexes), this.connectInfo, sql);
+ }
+
+ public PreparedStatement prepareStatement(String sql, String[] columnNames)
+ throws SQLException {
+ return new SWPreparedStatement(this, realConnection.prepareStatement(
+ sql, columnNames), this.connectInfo, sql);
+ }
+
+ public Clob createClob() throws SQLException {
+ return realConnection.createClob();
+ }
+
+ public Blob createBlob() throws SQLException {
+ return realConnection.createBlob();
+ }
+
+ public NClob createNClob() throws SQLException {
+ return realConnection.createNClob();
+ }
+
+ public SQLXML createSQLXML() throws SQLException {
+ return realConnection.createSQLXML();
+ }
+
+ public boolean isValid(int timeout) throws SQLException {
+ return realConnection.isValid(timeout);
+ }
+
+ public void setClientInfo(String name, String value)
+ throws SQLClientInfoException {
+ realConnection.setClientInfo(name, value);
+ }
+
+ public void setClientInfo(Properties properties)
+ throws SQLClientInfoException {
+ realConnection.setClientInfo(properties);
+ }
+
+ public String getClientInfo(String name) throws SQLException {
+ return realConnection.getClientInfo(name);
+ }
+
+ public Properties getClientInfo() throws SQLException {
+ return realConnection.getClientInfo();
+ }
+
+ public Array createArrayOf(String typeName, Object[] elements)
+ throws SQLException {
+ return realConnection.createArrayOf(typeName, elements);
+ }
+
+ public Struct createStruct(String typeName, Object[] attributes)
+ throws SQLException {
+ return realConnection.createStruct(typeName, attributes);
+ }
+
+ public void setSchema(String schema) throws SQLException {
+ realConnection.setSchema(schema);
+ }
+
+ public String getSchema() throws SQLException {
+ return realConnection.getSchema();
+ }
+
+ public void abort(Executor executor) throws SQLException {
+ realConnection.abort(executor);
+ }
+
+ public void setNetworkTimeout(Executor executor, int milliseconds)
+ throws SQLException {
+ realConnection.setNetworkTimeout(executor, milliseconds);
+ }
+
+ public int getNetworkTimeout() throws SQLException {
+ return realConnection.getNetworkTimeout();
+ }
+
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/SWPreparedStatement.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/SWPreparedStatement.java
new file mode 100644
index 0000000000000000000000000000000000000000..57186d0ce3deba05fb348b8a14fe19e8f457e8ea
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/SWPreparedStatement.java
@@ -0,0 +1,518 @@
+package com.a.eye.skywalking.plugin.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.*;
+import java.util.Calendar;
+
+public class SWPreparedStatement implements PreparedStatement {
+ private Connection realConnection;
+ private PreparedStatement realStatement;
+ private ConnectionInfo connectInfo;
+ private String sql;
+
+ SWPreparedStatement(Connection realConnection,
+ PreparedStatement realStatement, ConnectionInfo connectInfo,
+ String sql) {
+ this.realConnection = realConnection;
+ this.realStatement = realStatement;
+ this.connectInfo = connectInfo;
+ this.sql = sql;
+ }
+
+ public ResultSet executeQuery(String sql) throws SQLException {
+ return PreparedStatementTracing.execute(realStatement, connectInfo, "executeQuery", sql, new PreparedStatementTracing.Executable() {
+ public ResultSet exe(PreparedStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeQuery(sql);
+ }
+ });
+ }
+
+ public int executeUpdate(String sql) throws SQLException {
+ return PreparedStatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new PreparedStatementTracing.Executable() {
+ public Integer exe(PreparedStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeUpdate(sql);
+ }
+ });
+ }
+
+ public void close() throws SQLException {
+ realStatement.close();
+ }
+
+ public int getMaxFieldSize() throws SQLException {
+ return realStatement.getMaxFieldSize();
+ }
+
+ public void setMaxFieldSize(int max) throws SQLException {
+ realStatement.setMaxFieldSize(max);
+ }
+
+ public int getMaxRows() throws SQLException {
+ return realStatement.getMaxRows();
+ }
+
+ public void setMaxRows(int max) throws SQLException {
+ realStatement.setMaxRows(max);
+ }
+
+ public void setEscapeProcessing(boolean enable) throws SQLException {
+ realStatement.setEscapeProcessing(enable);
+ }
+
+ public int getQueryTimeout() throws SQLException {
+ return realStatement.getQueryTimeout();
+ }
+
+ public void setQueryTimeout(int seconds) throws SQLException {
+ realStatement.setQueryTimeout(seconds);
+ }
+
+ public void cancel() throws SQLException {
+ realStatement.cancel();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return realStatement.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ realStatement.clearWarnings();
+ }
+
+ public void setCursorName(String name) throws SQLException {
+ realStatement.setCursorName(name);
+ }
+
+ public boolean execute(String sql) throws SQLException {
+ return PreparedStatementTracing.execute(realStatement, connectInfo, "execute", sql, new PreparedStatementTracing.Executable() {
+ public Boolean exe(PreparedStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.execute(sql);
+ }
+ });
+ }
+
+ public ResultSet getResultSet() throws SQLException {
+ return realStatement.getResultSet();
+ }
+
+ public int getUpdateCount() throws SQLException {
+ return realStatement.getUpdateCount();
+ }
+
+ public boolean getMoreResults() throws SQLException {
+ return realStatement.getMoreResults();
+ }
+
+ public void setFetchDirection(int direction) throws SQLException {
+ realStatement.setFetchDirection(direction);
+ }
+
+ public int getFetchDirection() throws SQLException {
+ return realStatement.getFetchDirection();
+ }
+
+ public void setFetchSize(int rows) throws SQLException {
+ realStatement.setFetchSize(rows);
+ }
+
+ public int getFetchSize() throws SQLException {
+ return realStatement.getFetchSize();
+ }
+
+ public int getResultSetConcurrency() throws SQLException {
+ return realStatement.getResultSetConcurrency();
+ }
+
+ public int getResultSetType() throws SQLException {
+ return realStatement.getResultSetType();
+ }
+
+ public void addBatch(String sql) throws SQLException {
+ realStatement.addBatch(sql);
+ }
+
+ public void clearBatch() throws SQLException {
+ realStatement.clearBatch();
+ }
+
+ public int[] executeBatch() throws SQLException {
+ return PreparedStatementTracing.execute(realStatement, connectInfo, "executeBatch", "", new PreparedStatementTracing.Executable() {
+ public int[] exe(PreparedStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeBatch();
+ }
+ });
+ }
+
+ public Connection getConnection() throws SQLException {
+ return realConnection;
+ }
+
+ public boolean getMoreResults(int current) throws SQLException {
+ return realStatement.getMoreResults(current);
+ }
+
+ public ResultSet getGeneratedKeys() throws SQLException {
+ return realStatement.getGeneratedKeys();
+ }
+
+ public int executeUpdate(String sql, final int autoGeneratedKeys)
+ throws SQLException {
+ return PreparedStatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new PreparedStatementTracing.Executable() {
+ public Integer exe(PreparedStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeUpdate(sql, autoGeneratedKeys);
+ }
+ });
+ }
+
+ public int executeUpdate(String sql, final int[] columnIndexes)
+ throws SQLException {
+ return PreparedStatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new PreparedStatementTracing.Executable() {
+ public Integer exe(PreparedStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeUpdate(sql, columnIndexes);
+ }
+ });
+ }
+
+ public int executeUpdate(String sql, final String[] columnNames)
+ throws SQLException {
+ return PreparedStatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new PreparedStatementTracing.Executable() {
+ public Integer exe(PreparedStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeUpdate(sql, columnNames);
+ }
+ });
+ }
+
+ public boolean execute(String sql, final int autoGeneratedKeys)
+ throws SQLException {
+ return PreparedStatementTracing.execute(realStatement, connectInfo, "execute", sql, new PreparedStatementTracing.Executable() {
+ public Boolean exe(PreparedStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.execute(sql, autoGeneratedKeys);
+ }
+ });
+ }
+
+ public boolean execute(String sql, final int[] columnIndexes) throws SQLException {
+ return PreparedStatementTracing.execute(realStatement, connectInfo, "execute", sql, new PreparedStatementTracing.Executable() {
+ public Boolean exe(PreparedStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.execute(sql, columnIndexes);
+ }
+ });
+ }
+
+ public boolean execute(String sql, final String[] columnNames)
+ throws SQLException {
+ return PreparedStatementTracing.execute(realStatement, connectInfo, "execute", sql, new PreparedStatementTracing.Executable() {
+ public Boolean exe(PreparedStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.execute(sql, columnNames);
+ }
+ });
+ }
+
+ public int getResultSetHoldability() throws SQLException {
+ return realStatement.getResultSetHoldability();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return realStatement.isClosed();
+ }
+
+ public void setPoolable(boolean poolable) throws SQLException {
+ realStatement.setPoolable(poolable);
+ }
+
+ public boolean isPoolable() throws SQLException {
+ return realStatement.isPoolable();
+ }
+
+ public void closeOnCompletion() throws SQLException {
+ realStatement.closeOnCompletion();
+ }
+
+ public boolean isCloseOnCompletion() throws SQLException {
+ return realStatement.isCloseOnCompletion();
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return realStatement.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return realStatement.isWrapperFor(iface);
+ }
+
+ public ResultSet executeQuery() throws SQLException {
+ return PreparedStatementTracing.execute(realStatement, connectInfo, "executeQuery", sql, new PreparedStatementTracing.Executable() {
+ public ResultSet exe(PreparedStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeQuery();
+ }
+ });
+ }
+
+ public int executeUpdate() throws SQLException {
+ return PreparedStatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new PreparedStatementTracing.Executable() {
+ public Integer exe(PreparedStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeUpdate();
+ }
+ });
+ }
+
+ public void setNull(int parameterIndex, int sqlType) throws SQLException {
+ realStatement.setNull(parameterIndex, sqlType);
+ }
+
+ public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+ realStatement.setBoolean(parameterIndex, x);
+ }
+
+ public void setByte(int parameterIndex, byte x) throws SQLException {
+ realStatement.setByte(parameterIndex, x);
+ }
+
+ public void setShort(int parameterIndex, short x) throws SQLException {
+ realStatement.setShort(parameterIndex, x);
+ }
+
+ public void setInt(int parameterIndex, int x) throws SQLException {
+ realStatement.setInt(parameterIndex, x);
+ }
+
+ public void setLong(int parameterIndex, long x) throws SQLException {
+ realStatement.setLong(parameterIndex, x);
+ }
+
+ public void setFloat(int parameterIndex, float x) throws SQLException {
+ realStatement.setFloat(parameterIndex, x);
+ }
+
+ public void setDouble(int parameterIndex, double x) throws SQLException {
+ realStatement.setDouble(parameterIndex, x);
+ }
+
+ public void setBigDecimal(int parameterIndex, BigDecimal x)
+ throws SQLException {
+ realStatement.setBigDecimal(parameterIndex, x);
+ }
+
+ public void setString(int parameterIndex, String x) throws SQLException {
+ realStatement.setString(parameterIndex, x);
+ }
+
+ public void setBytes(int parameterIndex, byte[] x) throws SQLException {
+ realStatement.setBytes(parameterIndex, x);
+ }
+
+ public void setDate(int parameterIndex, Date x) throws SQLException {
+ realStatement.setDate(parameterIndex, x);
+ }
+
+ public void setTime(int parameterIndex, Time x) throws SQLException {
+ realStatement.setTime(parameterIndex, x);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x)
+ throws SQLException {
+ realStatement.setTimestamp(parameterIndex, x);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, int length)
+ throws SQLException {
+ realStatement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ @Deprecated
+ public void setUnicodeStream(int parameterIndex, InputStream x, int length)
+ throws SQLException {
+ realStatement.setUnicodeStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, int length)
+ throws SQLException {
+ realStatement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void clearParameters() throws SQLException {
+ realStatement.clearParameters();
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType)
+ throws SQLException {
+ realStatement.setObject(parameterIndex, x, targetSqlType);
+ }
+
+ public void setObject(int parameterIndex, Object x) throws SQLException {
+ realStatement.setObject(parameterIndex, x);
+ }
+
+ public boolean execute() throws SQLException {
+ return PreparedStatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new PreparedStatementTracing.Executable() {
+ public Boolean exe(PreparedStatement realStatement, String sql)
+ throws SQLException {
+ return realStatement.execute();
+ }
+ });
+ }
+
+ public void addBatch() throws SQLException {
+ realStatement.addBatch();
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader, int length)
+ throws SQLException {
+ realStatement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setRef(int parameterIndex, Ref x) throws SQLException {
+ realStatement.setRef(parameterIndex, x);
+ }
+
+ public void setBlob(int parameterIndex, Blob x) throws SQLException {
+ realStatement.setBlob(parameterIndex, x);
+ }
+
+ public void setClob(int parameterIndex, Clob x) throws SQLException {
+ realStatement.setClob(parameterIndex, x);
+ }
+
+ public void setArray(int parameterIndex, Array x) throws SQLException {
+ realStatement.setArray(parameterIndex, x);
+ }
+
+ public ResultSetMetaData getMetaData() throws SQLException {
+ return realStatement.getMetaData();
+ }
+
+ public void setDate(int parameterIndex, Date x, Calendar cal)
+ throws SQLException {
+ realStatement.setDate(parameterIndex, x, cal);
+ }
+
+ public void setTime(int parameterIndex, Time x, Calendar cal)
+ throws SQLException {
+ realStatement.setTime(parameterIndex, x, cal);
+ }
+
+ public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
+ throws SQLException {
+ realStatement.setTimestamp(parameterIndex, x, cal);
+ }
+
+ public void setNull(int parameterIndex, int sqlType, String typeName)
+ throws SQLException {
+ realStatement.setNull(parameterIndex, sqlType, typeName);
+ }
+
+ public void setURL(int parameterIndex, URL x) throws SQLException {
+ realStatement.setURL(parameterIndex, x);
+ }
+
+ public ParameterMetaData getParameterMetaData() throws SQLException {
+ return realStatement.getParameterMetaData();
+ }
+
+ public void setRowId(int parameterIndex, RowId x) throws SQLException {
+ realStatement.setRowId(parameterIndex, x);
+ }
+
+ public void setNString(int parameterIndex, String value)
+ throws SQLException {
+ realStatement.setNString(parameterIndex, value);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value,
+ long length) throws SQLException {
+ realStatement.setNCharacterStream(parameterIndex, value, length);
+ }
+
+ public void setNClob(int parameterIndex, NClob value) throws SQLException {
+ realStatement.setNClob(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader, long length)
+ throws SQLException {
+ realStatement.setClob(parameterIndex, reader, length);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream, long length)
+ throws SQLException {
+ realStatement.setBlob(parameterIndex, inputStream, length);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader, long length)
+ throws SQLException {
+ realStatement.setNClob(parameterIndex, reader, length);
+ }
+
+ public void setSQLXML(int parameterIndex, SQLXML xmlObject)
+ throws SQLException {
+ realStatement.setSQLXML(parameterIndex, xmlObject);
+ }
+
+ public void setObject(int parameterIndex, Object x, int targetSqlType,
+ int scaleOrLength) throws SQLException {
+ realStatement.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x, long length)
+ throws SQLException {
+ realStatement.setAsciiStream(parameterIndex, x, length);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x, long length)
+ throws SQLException {
+ realStatement.setBinaryStream(parameterIndex, x, length);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader,
+ long length) throws SQLException {
+ realStatement.setCharacterStream(parameterIndex, reader, length);
+ }
+
+ public void setAsciiStream(int parameterIndex, InputStream x)
+ throws SQLException {
+ realStatement.setAsciiStream(parameterIndex, x);
+ }
+
+ public void setBinaryStream(int parameterIndex, InputStream x)
+ throws SQLException {
+ realStatement.setBinaryStream(parameterIndex, x);
+ }
+
+ public void setCharacterStream(int parameterIndex, Reader reader)
+ throws SQLException {
+ realStatement.setCharacterStream(parameterIndex, reader);
+ }
+
+ public void setNCharacterStream(int parameterIndex, Reader value)
+ throws SQLException {
+ realStatement.setNCharacterStream(parameterIndex, value);
+ }
+
+ public void setClob(int parameterIndex, Reader reader) throws SQLException {
+ realStatement.setClob(parameterIndex, reader);
+ }
+
+ public void setBlob(int parameterIndex, InputStream inputStream)
+ throws SQLException {
+ realStatement.setBlob(parameterIndex, inputStream);
+ }
+
+ public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+ realStatement.setNClob(parameterIndex, reader);
+ }
+
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/SWStatement.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/SWStatement.java
new file mode 100644
index 0000000000000000000000000000000000000000..2d212b7a5e266b1e19adf36421164452a0b5ee63
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/SWStatement.java
@@ -0,0 +1,251 @@
+package com.a.eye.skywalking.plugin.jdbc;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+
+
+public class SWStatement implements java.sql.Statement {
+ private Connection realConnection;
+ private java.sql.Statement realStatement;
+ private ConnectionInfo connectInfo;
+
+ SWStatement(Connection realConnection, java.sql.Statement realStatement, ConnectionInfo connectInfo) {
+ this.realConnection = realConnection;
+ this.realStatement = realStatement;
+ this.connectInfo = connectInfo;
+ }
+
+ public T unwrap(Class iface) throws SQLException {
+ return realStatement.unwrap(iface);
+ }
+
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return realStatement.isWrapperFor(iface);
+ }
+
+ public ResultSet executeQuery(String sql) throws SQLException {
+ return StatementTracing.execute(realStatement, connectInfo, "executeQuery", sql, new StatementTracing.Executable() {
+ public ResultSet exe(java.sql.Statement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeQuery(sql);
+ }
+ });
+ }
+
+ public int executeUpdate(String sql) throws SQLException {
+ return StatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new StatementTracing.Executable() {
+ public Integer exe(java.sql.Statement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeUpdate(sql);
+ }
+ });
+ }
+
+ public void close() throws SQLException {
+ realStatement.close();
+ }
+
+ public int getMaxFieldSize() throws SQLException {
+ return realStatement.getMaxFieldSize();
+ }
+
+ public void setMaxFieldSize(int max) throws SQLException {
+ realStatement.setMaxFieldSize(max);
+ }
+
+ public int getMaxRows() throws SQLException {
+ return realStatement.getMaxRows();
+ }
+
+ public void setMaxRows(int max) throws SQLException {
+ realStatement.setMaxRows(max);
+ }
+
+ public void setEscapeProcessing(boolean enable) throws SQLException {
+ realStatement.setEscapeProcessing(enable);
+ }
+
+ public int getQueryTimeout() throws SQLException {
+ return realStatement.getQueryTimeout();
+ }
+
+ public void setQueryTimeout(int seconds) throws SQLException {
+ realStatement.setQueryTimeout(seconds);
+ }
+
+ public void cancel() throws SQLException {
+ realStatement.cancel();
+ }
+
+ public SQLWarning getWarnings() throws SQLException {
+ return realStatement.getWarnings();
+ }
+
+ public void clearWarnings() throws SQLException {
+ realStatement.clearWarnings();
+ }
+
+ public void setCursorName(String name) throws SQLException {
+ realStatement.setCursorName(name);
+ }
+
+ public boolean execute(String sql) throws SQLException {
+ return StatementTracing.execute(realStatement, connectInfo, "execute", sql, new StatementTracing.Executable() {
+ public Boolean exe(java.sql.Statement realStatement, String sql)
+ throws SQLException {
+ return realStatement.execute(sql);
+ }
+ });
+ }
+
+ public ResultSet getResultSet() throws SQLException {
+ return realStatement.getResultSet();
+ }
+
+ public int getUpdateCount() throws SQLException {
+ return realStatement.getUpdateCount();
+ }
+
+ public boolean getMoreResults() throws SQLException {
+ return realStatement.getMoreResults();
+ }
+
+ public void setFetchDirection(int direction) throws SQLException {
+ realStatement.setFetchDirection(direction);
+ }
+
+ public int getFetchDirection() throws SQLException {
+ return realStatement.getFetchDirection();
+ }
+
+ public void setFetchSize(int rows) throws SQLException {
+ realStatement.setFetchSize(rows);
+ }
+
+ public int getFetchSize() throws SQLException {
+ return realStatement.getFetchSize();
+ }
+
+ public int getResultSetConcurrency() throws SQLException {
+ return realStatement.getResultSetConcurrency();
+ }
+
+ public int getResultSetType() throws SQLException {
+ return realStatement.getResultSetType();
+ }
+
+ public void addBatch(String sql) throws SQLException {
+ realStatement.addBatch(sql);
+ }
+
+ public void clearBatch() throws SQLException {
+ realStatement.clearBatch();
+ }
+
+ public int[] executeBatch() throws SQLException {
+ return StatementTracing.execute(realStatement, connectInfo, "executeBatch", "", new StatementTracing.Executable() {
+ public int[] exe(java.sql.Statement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeBatch();
+ }
+ });
+ }
+
+ public Connection getConnection() throws SQLException {
+ return this.realConnection;
+ }
+
+ public boolean getMoreResults(int current) throws SQLException {
+ return realStatement.getMoreResults(current);
+ }
+
+ public ResultSet getGeneratedKeys() throws SQLException {
+ return realStatement.getGeneratedKeys();
+ }
+
+ public int executeUpdate(String sql, final int autoGeneratedKeys)
+ throws SQLException {
+ return StatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new StatementTracing.Executable() {
+ public Integer exe(java.sql.Statement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeUpdate(sql, autoGeneratedKeys);
+ }
+ });
+ }
+
+ public int executeUpdate(String sql, final int[] columnIndexes)
+ throws SQLException {
+ return StatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new StatementTracing.Executable() {
+ public Integer exe(java.sql.Statement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeUpdate(sql, columnIndexes);
+ }
+ });
+ }
+
+ public int executeUpdate(String sql, final String[] columnNames)
+ throws SQLException {
+ return StatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new StatementTracing.Executable() {
+ public Integer exe(java.sql.Statement realStatement, String sql)
+ throws SQLException {
+ return realStatement.executeUpdate(sql, columnNames);
+ }
+ });
+ }
+
+ public boolean execute(String sql, final int autoGeneratedKeys)
+ throws SQLException {
+ return StatementTracing.execute(realStatement, connectInfo, "execute", sql, new StatementTracing.Executable() {
+ public Boolean exe(java.sql.Statement realStatement, String sql)
+ throws SQLException {
+ return realStatement.execute(sql, autoGeneratedKeys);
+ }
+ });
+ }
+
+ public boolean execute(String sql, final int[] columnIndexes) throws SQLException {
+ return StatementTracing.execute(realStatement, connectInfo, "execute", sql, new StatementTracing.Executable() {
+ public Boolean exe(java.sql.Statement realStatement, String sql)
+ throws SQLException {
+ return realStatement.execute(sql, columnIndexes);
+ }
+ });
+ }
+
+ public boolean execute(String sql, final String[] columnNames)
+ throws SQLException {
+ return StatementTracing.execute(realStatement, connectInfo, "execute", sql, new StatementTracing.Executable() {
+ public Boolean exe(java.sql.Statement realStatement, String sql)
+ throws SQLException {
+ return realStatement.execute(sql, columnNames);
+ }
+ });
+ }
+
+ public int getResultSetHoldability() throws SQLException {
+ return realStatement.getResultSetHoldability();
+ }
+
+ public boolean isClosed() throws SQLException {
+ return realStatement.isClosed();
+ }
+
+ public void setPoolable(boolean poolable) throws SQLException {
+ realStatement.setPoolable(poolable);
+ }
+
+ public boolean isPoolable() throws SQLException {
+ return realStatement.isPoolable();
+ }
+
+ public void closeOnCompletion() throws SQLException {
+ realStatement.closeOnCompletion();
+ }
+
+ public boolean isCloseOnCompletion() throws SQLException {
+ return realStatement.isCloseOnCompletion();
+ }
+
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/StatementTracing.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/StatementTracing.java
new file mode 100644
index 0000000000000000000000000000000000000000..4e4e4f3163ec43f8e54ec4c253587487699e9620
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/StatementTracing.java
@@ -0,0 +1,50 @@
+package com.a.eye.skywalking.plugin.jdbc;
+
+
+import com.a.eye.skywalking.api.context.ContextManager;
+import com.a.eye.skywalking.api.util.StringUtil;
+import com.a.eye.skywalking.trace.Span;
+import com.a.eye.skywalking.trace.tag.Tags;
+
+import java.sql.SQLException;
+
+/**
+ * {@link StatementTracing} create span with the {@link Span#operationName} start with
+ * "JDBC/Statement/"and set {@link ConnectionInfo#dbType} to the {@link Tags#COMPONENT}.
+ *
+ * Notice: {@link Tags#PEERS} may be is null if database connection url don't contain multiple hosts.
+ *
+ * @author zhangxin
+ */
+public class StatementTracing {
+ public static R execute(java.sql.Statement realStatement,
+ ConnectionInfo connectInfo, String method, String sql, Executable exec)
+ throws SQLException {
+ try {
+ Span span = ContextManager.INSTANCE.createSpan("JDBC/Statement/" + method);
+ Tags.DB_TYPE.set(span, "sql");
+ Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName());
+ Tags.DB_STATEMENT.set(span, sql);
+ Tags.COMPONENT.set(span, connectInfo.getDBType());
+ if (!StringUtil.isEmpty(connectInfo.getHosts())) {
+ Tags.PEERS.set(span, connectInfo.getHosts());
+ } else {
+ Tags.PEER_PORT.set(span, connectInfo.getPort());
+ Tags.PEER_HOST.set(span, connectInfo.getHost());
+ }
+ return exec.exe(realStatement, sql);
+ } catch (SQLException e) {
+ Span span = ContextManager.INSTANCE.activeSpan();
+ Tags.ERROR.set(span, true);
+ span.log(e);
+ throw e;
+ } finally {
+ ContextManager.INSTANCE.stopSpan();
+ }
+ }
+
+ public interface Executable {
+ R exe(java.sql.Statement realStatement, String sql)
+ throws SQLException;
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/AbstractConnectionURLParser.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/AbstractConnectionURLParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ed4fa846ea723a1dfb57b50c3ad98f9646f5a06
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/AbstractConnectionURLParser.java
@@ -0,0 +1,65 @@
+package com.a.eye.skywalking.plugin.jdbc.connectionurl.parser;
+
+/**
+ * {@link AbstractConnectionURLParser} is abstract class that the class that parse jdbc url.
+ *
+ * @author zhangxin
+ */
+public abstract class AbstractConnectionURLParser implements ConnectionURLParser {
+
+ /**
+ * Connection url
+ */
+ protected String url;
+
+ public AbstractConnectionURLParser(String url) {
+ this.url = url;
+ }
+
+ /**
+ * Fetch the index range that database host and port from connection url.
+ *
+ * @return index range that database hosts.
+ */
+ protected abstract int[] fetchDatabaseHostsIndexRange();
+
+ /**
+ * Fetch the index range that database name from connection url.
+ *
+ * @return index range that database name.
+ */
+ protected abstract int[] fetchDatabaseNameIndexRange();
+
+ /**
+ * Fetch database host(s) from connection url.
+ *
+ * @return database host(s).
+ */
+ protected String fetchDatabaseHostsFromURL() {
+ int[] indexRange = fetchDatabaseHostsIndexRange();
+ return url.substring(indexRange[0], indexRange[1]);
+ }
+
+ /**
+ * Fetch database name from connection url.
+ *
+ * @return database name.
+ */
+ protected String fetchDatabaseNameFromURL() {
+ int[] indexRange = fetchDatabaseNameIndexRange();
+ return url.substring(indexRange[0], indexRange[1]);
+ }
+
+ /**
+ * Fetch database name from connection url.
+ *
+ * @return database name.
+ */
+ protected String fetchDatabaseNameFromURL(int[] indexRange) {
+ return url.substring(indexRange[0], indexRange[1]);
+ }
+
+ public String getConnectionURL() {
+ return this.url;
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/ConnectionURLParser.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/ConnectionURLParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..0576492eda1ad378d59fc31f7117e0a386cf5ba9
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/ConnectionURLParser.java
@@ -0,0 +1,14 @@
+package com.a.eye.skywalking.plugin.jdbc.connectionurl.parser;
+
+import com.a.eye.skywalking.plugin.jdbc.ConnectionInfo;
+
+
+public interface ConnectionURLParser {
+ /**
+ * The class that extend {@link ConnectionURLParser} spilt
+ * the database name , the database host(s) from connection url.
+ *
+ * @return connection info.
+ */
+ ConnectionInfo parse();
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/H2URLParser.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/H2URLParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..81b992501dd474ec60e3e91a1a83c7068ca637e5
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/H2URLParser.java
@@ -0,0 +1,118 @@
+package com.a.eye.skywalking.plugin.jdbc.connectionurl.parser;
+
+import com.a.eye.skywalking.plugin.jdbc.ConnectionInfo;
+
+/**
+ * {@link H2URLParser} presents that skywalking how to parse the connection url of H2 database.
+ * {@link ConnectionInfo#host} will return localhost and {@link ConnectionInfo#port} will return
+ * -1 if H2 running with memory mode or file mode, or it will return the host and the port.
+ *
+ * {@link H2URLParser} check the connection url if contains "file" or "mem". if yes. the database
+ * name substring the connection url from the index after "file" index or the "mem" index to the
+ * index of first charset ";".
+ *
+ * The {@link ConnectionInfo#host} be set the string between charset "//" and the first charset "/" after
+ * the charset "//", and {@link ConnectionInfo#databaseName} be set the string between the last index of "/" and
+ * the first charset ";".
+ *
+ * @author zhangxin
+ */
+public class H2URLParser extends AbstractConnectionURLParser {
+
+ private static final String LOCALHOST = "localhost";
+ /**
+ * Default port that H2 running with mix mode.
+ */
+ private static final int DEFAULT_PORT = 8084;
+ /**
+ * Flag that H2 running with file mode.
+ */
+ private static final String FILE_MODE_FLAG = "file";
+ /**
+ * Flag that H2 running with memory mode.
+ */
+ private static final String MEMORY_MODE_FLAG = "mem";
+ /**
+ * H2 data type.
+ */
+ private static final String H2_DB_TYPE = "H2";
+
+ public H2URLParser(String url) {
+ super(url);
+ }
+
+ @Override
+ protected int[] fetchDatabaseHostsIndexRange() {
+ int hostLabelStartIndex = url.indexOf("//");
+ int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex + 2);
+ return new int[]{hostLabelStartIndex + 2, hostLabelEndIndex};
+ }
+
+ @Override
+ protected int[] fetchDatabaseNameIndexRange() {
+ int databaseStartTag = url.lastIndexOf("/");
+ int databaseEndTag = url.indexOf(";");
+ if (databaseEndTag == -1) {
+ databaseEndTag = url.length();
+ }
+ return new int[]{databaseStartTag + 1, databaseEndTag};
+ }
+
+ @Override
+ public ConnectionInfo parse() {
+ int[] databaseNameRangeIndex = fetchDatabaseNameRangeIndexFromURLForH2FileMode();
+ if (databaseNameRangeIndex != null) {
+ return new ConnectionInfo(H2_DB_TYPE, LOCALHOST, -1, fetchDatabaseNameFromURL(databaseNameRangeIndex));
+ }
+
+ databaseNameRangeIndex = fetchDatabaseNameRangeIndexFromURLForH2MemMode();
+ if (databaseNameRangeIndex != null) {
+ return new ConnectionInfo(H2_DB_TYPE, LOCALHOST, -1, fetchDatabaseNameFromURL(databaseNameRangeIndex));
+ }
+
+ String[] hostAndPort = fetchDatabaseHostsFromURL().split(":");
+ if (hostAndPort.length == 1) {
+ return new ConnectionInfo(H2_DB_TYPE, hostAndPort[0], DEFAULT_PORT, fetchDatabaseNameFromURL());
+ } else {
+ return new ConnectionInfo(H2_DB_TYPE, hostAndPort[0], Integer.valueOf(hostAndPort[1]), fetchDatabaseNameFromURL());
+ }
+ }
+
+ /**
+ * Fetch range index that the database name from connection url if H2 database running with file mode.
+ *
+ * @return range index that the database name.
+ */
+ private int[] fetchDatabaseNameRangeIndexFromURLForH2FileMode() {
+ int fileLabelIndex = url.indexOf(FILE_MODE_FLAG);
+ int parameterLabelIndex = url.indexOf(";", fileLabelIndex);
+ if (parameterLabelIndex == -1) {
+ parameterLabelIndex = url.length();
+ }
+
+ if (fileLabelIndex != -1) {
+ return new int[]{fileLabelIndex + FILE_MODE_FLAG.length() + 1, parameterLabelIndex};
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Fetch range index that the database name from connection url if H2 database running with memory mode.
+ *
+ * @return range index that the database name.
+ */
+ private int[] fetchDatabaseNameRangeIndexFromURLForH2MemMode() {
+ int fileLabelIndex = url.indexOf(MEMORY_MODE_FLAG);
+ int parameterLabelIndex = url.indexOf(";", fileLabelIndex);
+ if (parameterLabelIndex == -1) {
+ parameterLabelIndex = url.length();
+ }
+
+ if (fileLabelIndex != -1) {
+ return new int[]{fileLabelIndex + MEMORY_MODE_FLAG.length() + 1, parameterLabelIndex};
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/MysqlURLParser.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/MysqlURLParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..604d115ef65454e2aeedcbec62a794c7e31920ef
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/MysqlURLParser.java
@@ -0,0 +1,72 @@
+package com.a.eye.skywalking.plugin.jdbc.connectionurl.parser;
+
+import com.a.eye.skywalking.plugin.jdbc.ConnectionInfo;
+
+/**
+ * {@link MysqlURLParser} presents that how to parse mysql connection url.
+ *
+ * The {@link ConnectionInfo#host} be set the string between charset "//" and the first
+ * charset "/" after the charset "//", and {@link ConnectionInfo#databaseName} be set the
+ * string between the last index of "/" and the first charset "?". but one more thing, the
+ * {@link ConnectionInfo#hosts} be set if the host container multiple host.
+ *
+ * @author zhangxin
+ */
+public class MysqlURLParser extends AbstractConnectionURLParser {
+
+ /**
+ * Mysql default port.
+ */
+ private static final int DEFAULT_PORT = 3306;
+ /**
+ * Mysql db type.
+ */
+ private static final String MYSQL_DB_TYPE = "Mysql";
+
+ public MysqlURLParser(String url) {
+ super(url);
+ }
+
+ @Override
+ protected int[] fetchDatabaseHostsIndexRange() {
+ int hostLabelStartIndex = url.indexOf("//");
+ int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex + 2);
+ return new int[]{hostLabelStartIndex + 2, hostLabelEndIndex};
+ }
+
+ @Override
+ protected int[] fetchDatabaseNameIndexRange() {
+ int databaseStartTag = url.lastIndexOf("/");
+ int databaseEndTag = url.indexOf("?", databaseStartTag);
+ if (databaseEndTag == -1) {
+ databaseEndTag = url.length();
+ }
+ return new int[]{databaseStartTag + 1, databaseEndTag};
+ }
+
+ @Override
+ public ConnectionInfo parse() {
+ int[] hostRangeIndex = fetchDatabaseHostsIndexRange();
+ String hosts = url.substring(hostRangeIndex[0], hostRangeIndex[1]);
+ String[] hostSegment = hosts.split(",");
+ if (hostSegment.length > 1) {
+ StringBuilder sb = new StringBuilder();
+ for (String host : hostSegment) {
+ if (host.split(":").length == 1) {
+ sb.append(host + ":" + DEFAULT_PORT + ",");
+ } else {
+ sb.append(host + ",");
+ }
+ }
+ return new ConnectionInfo(MYSQL_DB_TYPE, sb.toString(), fetchDatabaseNameFromURL());
+ } else {
+ String[] hostAndPort = hostSegment[0].split(":");
+ if (hostAndPort.length != 1) {
+ return new ConnectionInfo(MYSQL_DB_TYPE, hostAndPort[0], Integer.valueOf(hostAndPort[1]), fetchDatabaseNameFromURL());
+ } else {
+ return new ConnectionInfo(MYSQL_DB_TYPE, hostAndPort[0], DEFAULT_PORT, fetchDatabaseNameFromURL());
+ }
+ }
+ }
+
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/OracleURLParser.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/OracleURLParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..eecd7c2422740566935bbd6edda19d2252644e6a
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/OracleURLParser.java
@@ -0,0 +1,62 @@
+package com.a.eye.skywalking.plugin.jdbc.connectionurl.parser;
+
+import com.a.eye.skywalking.plugin.jdbc.ConnectionInfo;
+
+/**
+ * {@link OracleURLParser} presents that how to parse oracle connection url.
+ *
+ * The {@link ConnectionInfo#host} be set the string between charset "@" and the last
+ * charset ":" after the charset "@", and {@link ConnectionInfo#databaseName} be set the
+ * string that after the last index of ":".
+ *
+ * Note: {@link OracleURLParser} can parse the commons connection url. the commons
+ * connection url is of the form: jdbc:oracle::@
,the other
+ * the form of connection url cannot be parsed success.
+ *
+ * @author zhangxin
+ */
+public class OracleURLParser extends AbstractConnectionURLParser {
+
+ /**
+ * Oracle db type.
+ */
+ private static final String ORACLE_DB_TYPE = "Oracle";
+ /**
+ * Oracle default port
+ */
+ private static final int DEFAULT_PORT = 1521;
+
+ public OracleURLParser(String url) {
+ super(url);
+ }
+
+ @Override
+ protected int[] fetchDatabaseHostsIndexRange() {
+ int hostLabelStartIndex = url.indexOf("@");
+ int hostLabelEndIndex = url.lastIndexOf(":");
+ return new int[]{hostLabelStartIndex + 1, hostLabelEndIndex};
+ }
+
+ @Override
+ protected int[] fetchDatabaseNameIndexRange() {
+ return new int[0];
+ }
+
+ @Override
+ public ConnectionInfo parse() {
+ int[] hostRangeIndex = fetchDatabaseHostsIndexRange();
+ String host = fetchDatabaseHostsFromURL();
+ String[] hostSegment = splitDatabaseAddress(host);
+ String databaseName = url.substring(hostRangeIndex[1] + 1);
+ if (hostSegment.length == 1) {
+ return new ConnectionInfo(ORACLE_DB_TYPE, host, DEFAULT_PORT, databaseName);
+ } else {
+ return new ConnectionInfo(ORACLE_DB_TYPE, hostSegment[0], Integer.valueOf(hostSegment[1]), databaseName);
+ }
+ }
+
+ private String[] splitDatabaseAddress(String address) {
+ String[] hostSegment = address.split(":");
+ return hostSegment;
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/URLParser.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/URLParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..c6912a8f64d86d0a03cf115634a2e16d1a6c2233
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/connectionurl/parser/URLParser.java
@@ -0,0 +1,23 @@
+package com.a.eye.skywalking.plugin.jdbc.connectionurl.parser;
+
+import com.a.eye.skywalking.plugin.jdbc.ConnectionInfo;
+
+/**
+ * {@link URLParser#parser(String)} support parse the connection url, such as Mysql, Oracle, H2 Database.
+ * But there are some url cannot be parsed, such as Oracle connection url with multiple host.
+ *
+ * @author zhangxin
+ */
+public class URLParser {
+ public static ConnectionInfo parser(String url) {
+ ConnectionURLParser parser = null;
+ if (url.startsWith("jdbc:mysql")) {
+ parser = new MysqlURLParser(url);
+ } else if (url.startsWith("jdbc:oracle")) {
+ parser = new OracleURLParser(url);
+ } else if (url.startsWith("jdbc:h2")) {
+ parser = new H2URLParser(url);
+ }
+ return parser.parse();
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/define/AbstractDatabaseInstrumentation.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/define/AbstractDatabaseInstrumentation.java
new file mode 100644
index 0000000000000000000000000000000000000000..e9d9e4a9b52a82c3c3e3680d2df893b6ef13ebf9
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/define/AbstractDatabaseInstrumentation.java
@@ -0,0 +1,53 @@
+package com.a.eye.skywalking.plugin.jdbc.define;
+
+import com.a.eye.skywalking.api.plugin.interceptor.ConstructorInterceptPoint;
+import com.a.eye.skywalking.api.plugin.interceptor.InstanceMethodsInterceptPoint;
+import com.a.eye.skywalking.api.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import com.a.eye.skywalking.plugin.jdbc.SWConnection;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+
+import java.util.Properties;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
+/**
+ * JDBC plugin using {@link JDBCDriverInterceptor} to intercept all the class that extend {@link java.sql.Driver#connect(String, Properties)},
+ * and change the return object to {@link com.a.eye.skywalking.plugin.jdbc.SWConnection}, All the method of {@link com.a.eye.skywalking.plugin.jdbc.SWConnection}
+ * is delete to the real JDBC Driver Connection object.
+ * It will return {@link com.a.eye.skywalking.plugin.jdbc.SWStatement} when {@link java.sql.Driver} to create {@link java.sql.Statement}, return
+ * {@link com.a.eye.skywalking.plugin.jdbc.SWPreparedStatement} when {@link java.sql.Driver} to create {@link java.sql.PreparedStatement} and return
+ * {@link com.a.eye.skywalking.plugin.jdbc.SWCallableStatement} when {@link java.sql.Driver} to create {@link java.sql.CallableStatement}.
+ * of course, {@link com.a.eye.skywalking.plugin.jdbc.SWStatement}, {@link com.a.eye.skywalking.plugin.jdbc.SWPreparedStatement} and
+ * {@link com.a.eye.skywalking.plugin.jdbc.SWCallableStatement} are same as {@link SWConnection}.
+ *
+ * @author zhangxin
+ */
+public abstract class AbstractDatabaseInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+
+ /**
+ * Intercept class
+ */
+ private static final String INTERCEPT_CLASS = "com.a.eye.skywalking.plugin.jdbc.define.JDBCDriverInterceptor";
+
+ @Override
+ protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return null;
+ }
+
+ @Override
+ protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return named("connect");
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return INTERCEPT_CLASS;
+ }
+ }};
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/define/H2Instrumentation.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/define/H2Instrumentation.java
new file mode 100644
index 0000000000000000000000000000000000000000..6b44b91fd7705feddd159b8e7d7ed2a50cc515f8
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/define/H2Instrumentation.java
@@ -0,0 +1,19 @@
+package com.a.eye.skywalking.plugin.jdbc.define;
+
+/**
+ * {@link H2Instrumentation} presents that skywalking will intercept {@link org.h2.Driver}.
+ *
+ * @author zhangxin
+ */
+public class H2Instrumentation extends AbstractDatabaseInstrumentation {
+
+ /**
+ * Class of intercept H2 driver
+ */
+ private static final String CLASS_OF_INTERCEPT_H2_DRIVER = "org.h2.Driver";
+
+ @Override
+ protected String enhanceClassName() {
+ return CLASS_OF_INTERCEPT_H2_DRIVER;
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/define/JDBCDriverInterceptor.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/define/JDBCDriverInterceptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..f5439c7b409c5ee46b0b15f0868f52a9995469d8
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/define/JDBCDriverInterceptor.java
@@ -0,0 +1,38 @@
+package com.a.eye.skywalking.plugin.jdbc.define;
+
+import com.a.eye.skywalking.api.plugin.interceptor.EnhancedClassInstanceContext;
+import com.a.eye.skywalking.api.plugin.interceptor.enhance.InstanceMethodInvokeContext;
+import com.a.eye.skywalking.api.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import com.a.eye.skywalking.api.plugin.interceptor.enhance.MethodInterceptResult;
+import com.a.eye.skywalking.plugin.jdbc.SWConnection;
+
+import java.sql.Connection;
+import java.util.Properties;
+
+/**
+ * {@link JDBCDriverInterceptor} will return {@link SWConnection} when {@link java.sql.Driver#connect(String, Properties)},
+ * instead of the instance that extend {@link Connection}.
+ *
+ * @author zhangxin
+ */
+public class JDBCDriverInterceptor implements InstanceMethodsAroundInterceptor {
+ @Override
+ public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext,
+ MethodInterceptResult result) {
+ // do nothing
+ }
+
+ @Override
+ public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext,
+ Object ret) {
+ return new SWConnection((String) interceptorContext.allArguments()[0],
+ (Properties) interceptorContext.allArguments()[1], (Connection) ret);
+ }
+
+ @Override
+ public void handleMethodException(Throwable t, EnhancedClassInstanceContext context,
+ InstanceMethodInvokeContext interceptorContext) {
+ // do nothing.
+ }
+
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/define/MysqlInstrumentation.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/define/MysqlInstrumentation.java
new file mode 100644
index 0000000000000000000000000000000000000000..56808851053044d075e00daeae7a5f92142fcaf8
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/define/MysqlInstrumentation.java
@@ -0,0 +1,13 @@
+package com.a.eye.skywalking.plugin.jdbc.define;
+
+/**
+ * {@link MysqlInstrumentation} presents that skywalking will intercept {@link com.mysql.jdbc.Driver}.
+ *
+ * @author zhangxin
+ */
+public class MysqlInstrumentation extends AbstractDatabaseInstrumentation {
+ @Override
+ protected String enhanceClassName() {
+ return "com.mysql.jdbc.Driver";
+ }
+}
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/define/OracleInstrumentation.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/define/OracleInstrumentation.java
new file mode 100644
index 0000000000000000000000000000000000000000..221f114ec226e7b42512cad622f8f4962ae9e391
--- /dev/null
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/define/OracleInstrumentation.java
@@ -0,0 +1,14 @@
+package com.a.eye.skywalking.plugin.jdbc.define;
+
+/**
+ * {@link OracleInstrumentation} presents that skywalking will intercept the class oracle.jdbc.OracleDriver
+ *
.
+ *
+ * @author zhangxin
+ */
+public class OracleInstrumentation extends AbstractDatabaseInstrumentation {
+ @Override
+ protected String enhanceClassName() {
+ return "oracle.jdbc.OracleDriver";
+ }
+}