提交 b4902723 编写于 作者: wu-sheng's avatar wu-sheng 提交者: GitHub

Merge pull request #536 from ascrutae/feature/jdbc-plugin-refactory

change the implementation of jdbc plugins
<!--
~ Copyright 2017, OpenSkywalking Organization All rights reserved.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~
~ Project repository: https://github.com/OpenSkywalking/skywalking
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>apm-sdk-plugin</artifactId>
<groupId>org.skywalking</groupId>
<version>3.2.3-2017</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apm-h2-1.x-plugin</artifactId>
<packaging>jar</packaging>
<name>h2-1.x-plugin</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.192</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-jdbc-commons</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
</plugin>
<plugin>
<!-- 源码插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<!-- 发布时自动将源码同时发布的配置 -->
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.h2.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CLOSE_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.COMMIT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CREATE_STATEMENT_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CREATE_STATEMENT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_CALL_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_CALL_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_STATEMENT_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_STATEMENT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.RELEASE_SAVE_POINT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.ROLLBACK_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.SERVICE_METHOD_INTERCEPT_CLASS;
/**
* {@link ConnectionInstrumentation} intercept the following methods that the class which extend {@link
* org.h2.jdbc.JdbcConnection}. <br/>
*
* 1. Enhance <code>prepareStatement</code> by <code>org.skywalking.apm.plugin.jdbc.define.JDBCPrepareStatementInterceptor</code>
* 3. Enhance <code>prepareCall</code> by <code>org.skywalking.apm.plugin.jdbc.define.JDBCPrepareCallInterceptor</code>
* 4. Enhance <code>createStatement</code> by <code>org.skywalking.apm.plugin.jdbc.define.JDBCStatementInterceptor</code>
* 5. Enhance <code>commit, rollback, close, releaseSavepoint</code> by <code>org.skywalking.apm.plugin.jdbc.define.ConnectionServiceMethodInterceptor</code>
*
* @author zhangxin
*/
public class ConnectionInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
public static final String ENHANCE_CLASS = "org.h2.jdbc.JdbcConnection";
@Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(PREPARE_STATEMENT_METHOD_NAME).and(takesArguments(1));
}
@Override public String getMethodsInterceptor() {
return PREPARE_STATEMENT_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(PREPARE_STATEMENT_METHOD_NAME).and(takesArguments(3));
}
@Override public String getMethodsInterceptor() {
return PREPARE_STATEMENT_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(PREPARE_STATEMENT_METHOD_NAME).and(takesArguments(4));
}
@Override public String getMethodsInterceptor() {
return PREPARE_STATEMENT_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(PREPARE_CALL_METHOD_NAME);
}
@Override public String getMethodsInterceptor() {
return PREPARE_CALL_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(CREATE_STATEMENT_METHOD_NAME);
}
@Override public String getMethodsInterceptor() {
return CREATE_STATEMENT_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(COMMIT_METHOD_NAME).or(named(ROLLBACK_METHOD_NAME)).or(named(CLOSE_METHOD_NAME)).or(named(RELEASE_SAVE_POINT_METHOD_NAME));
}
@Override public String getMethodsInterceptor() {
return SERVICE_METHOD_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override protected ClassMatch enhanceClass() {
return byName(ENHANCE_CLASS);
}
}
......@@ -16,19 +16,19 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.define;
package org.skywalking.apm.plugin.jdbc.h2.define;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.skywalking.apm.plugin.jdbc.define.AbstractDriverInstrumentation;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
/**
* {@link H2Instrumentation} presents that skywalking intercepts {@link org.h2.Driver}.
* {@link DriverInstrumentation} presents that skywalking intercepts {@link org.h2.Driver}.
*
* @author zhangxin
*/
public class H2Instrumentation extends AbstractDatabaseInstrumentation {
public class DriverInstrumentation extends AbstractDriverInstrumentation {
private static final String CLASS_OF_INTERCEPT_H2_DRIVER = "org.h2.Driver";
@Override
......
h2-1.x=org.skywalking.apm.plugin.jdbc.h2.define.DriverInstrumentation
h2-1.x=org.skywalking.apm.plugin.jdbc.h2.define.ConnectionInstrumentation
<!--
~ Copyright 2017, OpenSkywalking Organization All rights reserved.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~
~ Project repository: https://github.com/OpenSkywalking/skywalking
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>apm-sdk-plugin</artifactId>
<groupId>org.skywalking</groupId>
<version>3.2.3-2017</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apm-jdbc-commons</artifactId>
<packaging>jar</packaging>
<name>jdbc-commons</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>[2.0.14,6.0.6]</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
</plugin>
<plugin>
<!-- 源码插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<!-- 发布时自动将源码同时发布的配置 -->
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc;
import java.lang.reflect.Method;
import org.skywalking.apm.agent.core.context.ContextManager;
import org.skywalking.apm.agent.core.context.tag.Tags;
import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import org.skywalking.apm.util.StringUtil;
/**
* {@link ConnectionServiceMethodInterceptor} create an exit span when the client call the following methods in the class
* that extend {@link java.sql.Connection}.
* 1. close
* 2. rollback
* 3. releaseSavepoint
* 4. commit
* @author zhangxin
*/
public class ConnectionServiceMethodInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public final void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
ConnectionInfo connectInfo = (ConnectionInfo)objInst.getSkyWalkingDynamicField();
String remotePeer;
if (!StringUtil.isEmpty(connectInfo.getHosts())) {
remotePeer = connectInfo.getHosts();
} else {
remotePeer = connectInfo.getHost() + ":" + connectInfo.getPort();
}
AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/Connection/" + method.getName(), remotePeer);
Tags.DB_TYPE.set(span, "sql");
Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName());
Tags.DB_STATEMENT.set(span, "");
span.setComponent(connectInfo.getComponent());
SpanLayer.asDB(span);
}
@Override
public final Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes,
Object ret) throws Throwable {
ContextManager.stopSpan();
return ret;
}
@Override public final void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
ContextManager.activeSpan().errorOccurred().log(t);
}
}
......@@ -16,19 +16,18 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.define;
package org.skywalking.apm.plugin.jdbc;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.util.Properties;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.skywalking.apm.plugin.jdbc.SWConnection;
import org.skywalking.apm.plugin.jdbc.connectionurl.parser.URLParser;
/**
* {@link JDBCDriverInterceptor} return {@link SWConnection} when {@link java.sql.Driver} to create connection,
* instead of the {@link Connection} instance.
* {@link JDBCDriverInterceptor} set <code>ConnectionInfo</code> to {@link Connection} object when {@link
* java.sql.Driver} to create connection, instead of the {@link Connection} instance.
*
* @author zhangxin
*/
......@@ -42,8 +41,7 @@ public class JDBCDriverInterceptor implements InstanceMethodsAroundInterceptor {
@Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Object ret) throws Throwable {
if (ret != null) {
return new SWConnection((String)allArguments[0],
(Properties)allArguments[1], (Connection)ret);
((EnhancedInstance)ret).setSkyWalkingDynamicField(URLParser.parser((String)allArguments[0]));
}
return ret;
......
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc;
import java.lang.reflect.Method;
import java.sql.CallableStatement;
import java.sql.Connection;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import org.skywalking.apm.plugin.jdbc.trace.SWCallableStatement;
/**
* {@link JDBCPrepareCallInterceptor} return {@link SWCallableStatement} instance that wrapper the real CallStatement
* instance when the client call <code>prepareCall</code> method.
*
* @author zhangxin
*/
public class JDBCPrepareCallInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
if (objInst.getSkyWalkingDynamicField() == null) {
return ret;
}
return new SWCallableStatement((Connection)objInst, (CallableStatement)ret, (ConnectionInfo)objInst.getSkyWalkingDynamicField(), (String)allArguments[0]);
}
@Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import org.skywalking.apm.plugin.jdbc.trace.SWPreparedStatement;
/**
* {@link JDBCPrepareStatementInterceptor} return {@link SWPreparedStatement} instance that wrapper the real
* PreparedStatement instance when the client call <code>prepareStatement</code> method.
*
* @author zhangxin
*/
public class JDBCPrepareStatementInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
if (objInst.getSkyWalkingDynamicField() == null) {
return ret;
}
return new SWPreparedStatement((Connection)objInst, (PreparedStatement)ret, (ConnectionInfo)objInst.getSkyWalkingDynamicField(), (String)allArguments[0]);
}
@Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc;
import java.lang.reflect.Method;
import java.sql.Connection;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import org.skywalking.apm.plugin.jdbc.trace.SWStatement;
/**
* {@link JDBCStatementInterceptor} return {@link SWStatement} instance that wrapper the real Statement instance when
* the client call <code>createStatement</code> method.
*
* @author zhangxin
*/
public class JDBCStatementInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
if (objInst.getSkyWalkingDynamicField() == null) {
return ret;
}
return new SWStatement((Connection)objInst, (java.sql.Statement)ret, (ConnectionInfo)objInst.getSkyWalkingDynamicField());
}
@Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
}
}
......@@ -18,7 +18,7 @@
package org.skywalking.apm.plugin.jdbc.connectionurl.parser;
import org.skywalking.apm.plugin.jdbc.ConnectionInfo;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
public interface ConnectionURLParser {
/**
......
......@@ -19,7 +19,7 @@
package org.skywalking.apm.plugin.jdbc.connectionurl.parser;
import org.skywalking.apm.network.trace.component.ComponentsDefine;
import org.skywalking.apm.plugin.jdbc.ConnectionInfo;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
/**
* {@link H2URLParser} presents that skywalking how to parse the connection url of H2 database.
......
......@@ -19,7 +19,7 @@
package org.skywalking.apm.plugin.jdbc.connectionurl.parser;
import org.skywalking.apm.network.trace.component.ComponentsDefine;
import org.skywalking.apm.plugin.jdbc.ConnectionInfo;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
/**
* {@link MysqlURLParser} parse connection url of mysql.
......
......@@ -19,7 +19,7 @@
package org.skywalking.apm.plugin.jdbc.connectionurl.parser;
import org.skywalking.apm.network.trace.component.ComponentsDefine;
import org.skywalking.apm.plugin.jdbc.ConnectionInfo;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
/**
* {@link OracleURLParser} presents that how to parse oracle connection url.
......
......@@ -19,7 +19,7 @@
package org.skywalking.apm.plugin.jdbc.connectionurl.parser;
import org.skywalking.apm.network.trace.component.ComponentsDefine;
import org.skywalking.apm.plugin.jdbc.ConnectionInfo;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
/**
* {@link PostgreSQLURLParser} parse connection url of mysql.
......
......@@ -18,7 +18,7 @@
package org.skywalking.apm.plugin.jdbc.connectionurl.parser;
import org.skywalking.apm.plugin.jdbc.ConnectionInfo;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
/**
* {@link URLParser#parser(String)} support parse the connection url, such as Mysql, Oracle, H2 Database. But there are
......
......@@ -23,29 +23,26 @@ import net.bytebuddy.matcher.ElementMatcher;
import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.skywalking.apm.plugin.jdbc.SWConnection;
import org.skywalking.apm.plugin.jdbc.JDBCDriverInterceptor;
import static net.bytebuddy.matcher.ElementMatchers.named;
/**
* JDBC plugin using {@link JDBCDriverInterceptor} to intercept all the class that it has extend {@link
* java.sql.Driver#connect(String, java.util.Properties)}, and change the return object to {@link
* SWConnection}, All the method of {@link SWConnection}
* is delegate to the real JDBC Driver Connection object.
* JDBC plugin using {@link JDBCDriverInterceptor} to intercept the <code>connect</code> method of all driver class.
*
* @author zhangxin
*/
public abstract class AbstractDatabaseInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
public abstract class AbstractDriverInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String INTERCEPT_CLASS = "org.skywalking.apm.plugin.jdbc.define.JDBCDriverInterceptor";
private static final String DRIVER_INTERCEPT_CLASS = "org.skywalking.apm.plugin.jdbc.define.JDBCDriverInterceptor";
@Override
protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return null;
protected final ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override
protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
protected final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override
......@@ -55,7 +52,7 @@ public abstract class AbstractDatabaseInstrumentation extends ClassInstanceMetho
@Override
public String getMethodsInterceptor() {
return INTERCEPT_CLASS;
return DRIVER_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
......
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.define;
public class Constants {
public static final String CREATE_STATEMENT_INTERCEPT_CLASS = "org.skywalking.apm.plugin.jdbc.define.JDBCStatementInterceptor";
public static final String PREPARE_STATEMENT_INTERCEPT_CLASS = "org.skywalking.apm.plugin.jdbc.define.JDBCPrepareStatementInterceptor";
public static final String PREPARE_CALL_INTERCEPT_CLASS = "org.skywalking.apm.plugin.jdbc.define.JDBCPrepareCallInterceptor";
public static final String SERVICE_METHOD_INTERCEPT_CLASS = "org.skywalking.apm.plugin.jdbc.define.ConnectionServiceMethodInterceptor";
public static final String PREPARE_STATEMENT_METHOD_NAME = "prepareStatement";
public static final String PREPARE_CALL_METHOD_NAME = "prepareCall";
public static final String CREATE_STATEMENT_METHOD_NAME = "createStatement";
public static final String COMMIT_METHOD_NAME = "commit";
public static final String ROLLBACK_METHOD_NAME = "rollback";
public static final String CLOSE_METHOD_NAME = "close";
public static final String RELEASE_SAVE_POINT_METHOD_NAME = "releaseSavepoint";
}
......@@ -16,7 +16,7 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc;
package org.skywalking.apm.plugin.jdbc.trace;
import java.sql.SQLException;
import org.skywalking.apm.agent.core.context.ContextManager;
......@@ -25,6 +25,12 @@ import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.skywalking.apm.util.StringUtil;
/**
* {@link CallableStatementTracing} create an exit span when the client call the method in the class that extend {@link
* java.sql.CallableStatement}.
*
* @author zhangxin
*/
public class CallableStatementTracing {
public static <R> R execute(java.sql.CallableStatement realStatement,
......
......@@ -16,7 +16,7 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc;
package org.skywalking.apm.plugin.jdbc.trace;
import org.skywalking.apm.network.trace.component.OfficialComponent;
......
......@@ -16,7 +16,7 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc;
package org.skywalking.apm.plugin.jdbc.trace;
import java.sql.SQLException;
import org.skywalking.apm.agent.core.context.ContextManager;
......@@ -25,6 +25,12 @@ import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.skywalking.apm.util.StringUtil;
/**
* {@link PreparedStatementTracing} create an exit span when the client call the method in the class that extend {@link
* java.sql.PreparedStatement}.
*
* @author zhangxin
*/
public class PreparedStatementTracing {
public static <R> R execute(java.sql.PreparedStatement realStatement,
......
......@@ -16,7 +16,7 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc;
package org.skywalking.apm.plugin.jdbc.trace;
import java.io.InputStream;
import java.io.Reader;
......@@ -42,13 +42,33 @@ import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Map;
/**
* {@link SWCallableStatement} wrapper the {@link CallableStatement} created by client. and it will interceptor the
* following methods for trace.
* 1. {@link #execute()}
* 2. {@link #execute(String)}
* 3. {@link #execute(String, int[])}
* 4. {@link #execute(String, String[])}
* 5. {@link #execute(String, int)}
* 6. {@link #executeQuery()}
* 7. {@link #executeQuery(String)}
* 8. {@link #executeUpdate()}
* 9. {@link #executeUpdate(String)}
* 10. {@link #executeUpdate(String, int[])}
* 11. {@link #executeUpdate(String, String[])}
* 12. {@link #executeUpdate(String, int)}
* 13. {@link #addBatch()}
* 14. {@link #addBatch(String)} ()}
*
* @author zhangxin
*/
public class SWCallableStatement implements CallableStatement {
private Connection realConnection;
private CallableStatement realStatement;
private ConnectionInfo connectInfo;
private String sql;
SWCallableStatement(Connection realConnection,
public SWCallableStatement(Connection realConnection,
CallableStatement realStatement, ConnectionInfo connectInfo,
String sql) {
this.realConnection = realConnection;
......
......@@ -16,7 +16,7 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc;
package org.skywalking.apm.plugin.jdbc.trace;
import java.io.InputStream;
import java.io.Reader;
......@@ -41,13 +41,33 @@ import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
/**
* {@link SWPreparedStatement} wrapper the {@link PreparedStatement} created by client. and it will interceptor the
* following methods for trace.
* 1. {@link #execute()}
* 2. {@link #execute(String)}
* 3. {@link #execute(String, int[])}
* 4. {@link #execute(String, String[])}
* 5. {@link #execute(String, int)}
* 6. {@link #executeQuery()}
* 7. {@link #executeQuery(String)}
* 8. {@link #executeUpdate()}
* 9. {@link #executeUpdate(String)}
* 10. {@link #executeUpdate(String, int[])}
* 11. {@link #executeUpdate(String, String[])}
* 12. {@link #executeUpdate(String, int)}
* 13. {@link #addBatch()}
* 14. {@link #addBatch(String)} ()}
*
* @author zhangxin
*/
public class SWPreparedStatement implements PreparedStatement {
private Connection realConnection;
private PreparedStatement realStatement;
private ConnectionInfo connectInfo;
private String sql;
SWPreparedStatement(Connection realConnection,
public SWPreparedStatement(Connection realConnection,
PreparedStatement realStatement, ConnectionInfo connectInfo,
String sql) {
this.realConnection = realConnection;
......
......@@ -16,19 +16,36 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc;
package org.skywalking.apm.plugin.jdbc.trace;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
/**
* {@link SWStatement} wrapper the {@link java.sql.Statement} created by client. and it will interceptor the
* following methods for trace.
* 1. {@link #execute(String)}
* 2. {@link #execute(String, int[])}
* 3. {@link #execute(String, String[])}
* 4. {@link #execute(String, int)}
* 5. {@link #executeQuery(String)}
* 6. {@link #executeUpdate(String)}
* 7. {@link #executeUpdate(String, int[])}
* 8. {@link #executeUpdate(String, String[])}
* 9. {@link #executeUpdate(String, int)}
* 10. {@link #addBatch(String)} ()}
*
* @author zhangxin
*/
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) {
public SWStatement(Connection realConnection, java.sql.Statement realStatement, ConnectionInfo connectInfo) {
this.realConnection = realConnection;
this.realStatement = realStatement;
this.connectInfo = connectInfo;
......
......@@ -16,7 +16,7 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc;
package org.skywalking.apm.plugin.jdbc.trace;
import java.sql.SQLException;
import org.skywalking.apm.agent.core.context.ContextManager;
......@@ -25,6 +25,12 @@ import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.skywalking.apm.util.StringUtil;
/**
* {@link PreparedStatementTracing} create an exit span when the client call the method in the class that extend {@link
* java.sql.Statement}.
*
* @author zhangxin
*/
public class StatementTracing {
public static <R> R execute(java.sql.Statement realStatement,
ConnectionInfo connectInfo, String method, String sql, Executable<R> exec)
......
......@@ -23,6 +23,7 @@ import org.skywalking.apm.agent.core.context.ContextManager;
import org.skywalking.apm.agent.core.context.tag.Tags;
import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import org.skywalking.apm.util.StringUtil;
public class ConnectionTracing {
......
......@@ -124,11 +124,11 @@ public class SWCallableStatementTest extends AbstractStatementTest {
@Test
public void testSetParam() throws SQLException, MalformedURLException {
CallableStatement callableStatement = multiHostConnection.prepareCall("SELECT * FROM test WHERE a = ? or b = ? or c=? or d = ? or e = ?" +
" or e = ? or f = ? or g = ? or h = ? or i = ? or j = ? or k = ? or l = ? or m = ? or n = ? or o = ? or p = ? " +
" or r = ? or s = ? or t = ? or u = ? or v = ? or w = ? or x = ? or y = ? or z = ? or a1 = ? or a2 = ? or a3 = ?" +
" or a4 = ? or a5 = ? or a6 = ? or a7 = ? or a8 = ? or a9 = ? or b1 = ? or b2 = ? or b3 = ? or b4 = ? or b5 = ?" +
" or b6 = ? or b7 = ? or b8 = ? or b9 = ? or c1 = ? or c2 = ? or c3 = ?");
CallableStatement callableStatement = multiHostConnection.prepareCall("SELECT * FROM test WHERE a = ? OR b = ? OR c=? OR d = ? OR e = ?" +
" OR e = ? OR f = ? OR g = ? OR h = ? OR i = ? OR j = ? OR k = ? OR l = ? OR m = ? OR n = ? OR o = ? OR p = ? " +
" OR r = ? OR s = ? OR t = ? OR u = ? OR v = ? OR w = ? OR x = ? OR y = ? OR z = ? OR a1 = ? OR a2 = ? OR a3 = ?" +
" OR a4 = ? OR a5 = ? OR a6 = ? OR a7 = ? OR a8 = ? OR a9 = ? OR b1 = ? OR b2 = ? OR b3 = ? OR b4 = ? OR b5 = ?" +
" OR b6 = ? OR b7 = ? OR b8 = ? OR b9 = ? OR c1 = ? OR c2 = ? OR c3 = ?");
callableStatement.clearParameters();
callableStatement.setAsciiStream(1, inputStream);
callableStatement.setAsciiStream(2, inputStream, 10);
......@@ -666,7 +666,7 @@ public class SWCallableStatementTest extends AbstractStatementTest {
@Test
public void testQueryWithMultiHost() throws SQLException {
CallableStatement preparedStatement = multiHostConnection.prepareCall("SELECT * FROM test WHERE a = ? or b = ? or c=? or d = ?", 1, 1);
CallableStatement preparedStatement = multiHostConnection.prepareCall("SELECT * FROM test WHERE a = ? OR b = ? OR c=? OR d = ?", 1, 1);
preparedStatement.setAsciiStream(1, inputStream);
preparedStatement.setAsciiStream(2, inputStream, 10);
preparedStatement.setAsciiStream(3, inputStream, 1000000L);
......@@ -683,7 +683,7 @@ public class SWCallableStatementTest extends AbstractStatementTest {
public void testMultiHostWithException() throws SQLException {
when(mysqlCallableStatement.executeQuery()).thenThrow(new SQLException());
try {
CallableStatement preparedStatement = multiHostConnection.prepareCall("SELECT * FROM test WHERE a = ? or b = ? or c=? or d = ? or e=?");
CallableStatement preparedStatement = multiHostConnection.prepareCall("SELECT * FROM test WHERE a = ? OR b = ? OR c=? OR d = ? OR e=?");
preparedStatement.setBigDecimal(1, new BigDecimal(10000));
preparedStatement.setBlob(2, inputStream);
preparedStatement.setBlob(3, inputStream, 1000000L);
......@@ -705,7 +705,7 @@ public class SWCallableStatementTest extends AbstractStatementTest {
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
assertThat(spans.size(), is(1));
assertDBSpan(spans.get(0), "Mysql/JDBI/CallableStatement/executeQuery", "SELECT * FROM test WHERE a = ? or b = ? or c=? or d = ? or e=?");
assertDBSpan(spans.get(0), "Mysql/JDBI/CallableStatement/executeQuery", "SELECT * FROM test WHERE a = ? OR b = ? OR c=? OR d = ? OR e=?");
List<LogDataEntity> logs = SpanHelper.getLogs(spans.get(0));
Assert.assertThat(logs.size(), is(1));
assertDBSpanLog(logs.get(0));
......
......@@ -37,6 +37,10 @@ import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
import org.skywalking.apm.plugin.jdbc.connectionurl.parser.URLParser;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import org.skywalking.apm.plugin.jdbc.trace.SWCallableStatement;
import org.skywalking.apm.plugin.jdbc.trace.SWPreparedStatement;
import org.skywalking.apm.plugin.jdbc.trace.SWStatement;
public class SWConnection implements Connection {
private ConnectionInfo connectInfo;
......
......@@ -19,7 +19,7 @@
package org.skywalking.apm.plugin.jdbc.connectionurl.parser;
import org.junit.Test;
import org.skywalking.apm.plugin.jdbc.ConnectionInfo;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
......@@ -121,4 +121,4 @@ public class URLParserTest {
assertThat(connectionInfo.getHost(), is("localhost"));
assertThat(connectionInfo.getPort(), is(8084));
}
}
\ No newline at end of file
}
jdbc=org.skywalking.apm.plugin.jdbc.define.H2Instrumentation
jdbc=org.skywalking.apm.plugin.jdbc.define.MysqlInstrumentation
jdbc=org.skywalking.apm.plugin.jdbc.define.OracleInstrumentation
jdbc=org.skywalking.apm.plugin.jdbc.define.PostgreSQLInstrumentation
......@@ -25,10 +25,10 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apm-jdbc-plugin</artifactId>
<artifactId>apm-mysql-2.x-plugin</artifactId>
<packaging>jar</packaging>
<name>jdbc-plugin</name>
<name>mysql-2.x-plugin</name>
<url>http://maven.apache.org</url>
<properties>
......@@ -42,18 +42,6 @@
<version>5.1.36</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.192</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
......@@ -61,9 +49,9 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.0.0</version>
<groupId>org.skywalking</groupId>
<artifactId>apm-jdbc-commons</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
......
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.mysql.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CLOSE_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.COMMIT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CREATE_STATEMENT_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CREATE_STATEMENT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_CALL_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_CALL_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_STATEMENT_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_STATEMENT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.RELEASE_SAVE_POINT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.ROLLBACK_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.SERVICE_METHOD_INTERCEPT_CLASS;
/**
* {@link ConnectionInstrumentation} intercept the following methods that the class which extend {@link
* com.mysql.jdbc.ConnectionImpl}. <br/>
*
* 1. Enhance <code>prepareStatement</code> by <code>org.skywalking.apm.plugin.jdbc.define.JDBCPrepareStatementInterceptor</code>
* 2. Enhance <code>prepareCall</code> by <code>org.skywalking.apm.plugin.jdbc.define.JDBCPrepareCallInterceptor</code>
* 3. Enhance <code>createStatement</code> by <code>org.skywalking.apm.plugin.jdbc.define.JDBCStatementInterceptor</code>
* 4. Enhance <code>commit, rollback, close, releaseSavepoint</code> by <code>org.skywalking.apm.plugin.jdbc.define.ConnectionServiceMethodInterceptor</code>
*
* @author zhangxin
*/
public class ConnectionInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
public static final String ENHANCE_CLASS = "com.mysql.jdbc.ConnectionImpl";
@Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(PREPARE_STATEMENT_METHOD_NAME);
}
@Override public String getMethodsInterceptor() {
return PREPARE_STATEMENT_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(PREPARE_CALL_METHOD_NAME);
}
@Override public String getMethodsInterceptor() {
return PREPARE_CALL_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(CREATE_STATEMENT_METHOD_NAME).and(takesArguments(2));
}
@Override public String getMethodsInterceptor() {
return CREATE_STATEMENT_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(COMMIT_METHOD_NAME).or(named(ROLLBACK_METHOD_NAME)).or(named(CLOSE_METHOD_NAME)).or(named(RELEASE_SAVE_POINT_METHOD_NAME));
}
@Override public String getMethodsInterceptor() {
return SERVICE_METHOD_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override protected ClassMatch enhanceClass() {
return byName(ENHANCE_CLASS);
}
}
......@@ -16,18 +16,19 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.define;
package org.skywalking.apm.plugin.jdbc.mysql.define;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.skywalking.apm.plugin.jdbc.define.AbstractDriverInstrumentation;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
/**
* {@link MysqlInstrumentation} presents that skywalking intercepts {@link com.mysql.jdbc.Driver}.
* {@link DriverInstrumentation} presents that skywalking intercepts {@link com.mysql.jdbc.Driver}.
*
* @author zhangxin
*/
public class MysqlInstrumentation extends AbstractDatabaseInstrumentation {
public class DriverInstrumentation extends AbstractDriverInstrumentation {
@Override
protected ClassMatch enhanceClass() {
return byName("com.mysql.jdbc.Driver");
......
mysql=org.skywalking.apm.plugin.jdbc.mysql.define.DriverInstrumentation
mysql=org.skywalking.apm.plugin.jdbc.mysql.define.ConnectionInstrumentation
<!--
~ Copyright 2017, OpenSkywalking Organization All rights reserved.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~
~ Project repository: https://github.com/OpenSkywalking/skywalking
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>apm-sdk-plugin</artifactId>
<groupId>org.skywalking</groupId>
<version>3.2.3-2017</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apm-oracle-10.x-plugin</artifactId>
<packaging>jar</packaging>
<name>oracle-10.x-plugin</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.4.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-jdbc-commons</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
</plugin>
<plugin>
<!-- 源码插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<!-- 发布时自动将源码同时发布的配置 -->
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package oracle.jdbc.driver;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import org.skywalking.apm.plugin.jdbc.trace.SWPreparedStatement;
/**
* {@link JDBCPrepareStatementWithArrayInterceptor} return {@link SWPreparedStatement} instance that wrapper the real
* preparedStatement instance when the client call <code>oracle.jdbc.driver.PhysicalConnection#prepareStatement(String,
* int[])</code> method or <code>oracle.jdbc.driver.PhysicalConnection#prepareStatement(String, String[])</code>
* method.
*
* @author zhangxin
*/
public class JDBCPrepareStatementWithArrayInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
/**
* To prevent the <code>org.postgresql.jdbc.prepareStatement(String sql)</code> method from repeating
* interceptor, Because PGConnection call <code>org.postgresql.jdbc.prepareStatement(String sql)</code> method when
* the second argument is empty.
*
* @see oracle.jdbc.driver.PhysicalConnection#prepareStatement(String, int[])
* @see oracle.jdbc.driver.PhysicalConnection#prepareStatement(String, String[])
**/
String sql = (String)allArguments[0];
if (!AutoKeyInfo.isInsertSqlStmt(sql)) {
return ret;
}
return new SWPreparedStatement((Connection)objInst, (PreparedStatement)ret, (ConnectionInfo)objInst.getSkyWalkingDynamicField(), (String)allArguments[0]);
}
@Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.oracle.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import static org.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CLOSE_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.COMMIT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CREATE_STATEMENT_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CREATE_STATEMENT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_CALL_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_CALL_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_STATEMENT_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_STATEMENT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.RELEASE_SAVE_POINT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.ROLLBACK_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.SERVICE_METHOD_INTERCEPT_CLASS;
/**
* {@link ConnectionInstrumentation} intercept the following methods that the class which extend {@link
* oracle.jdbc.driver.PhysicalConnection}. <br/>
*
* 1. Enhance <code>prepareStatement</code> by <code>org.skywalking.apm.plugin.jdbc.define.JDBCPrepareStatementInterceptor</code>
* 2. Enhance <code>prepareStatement</code> that the seconds argument type is <code>java.lang.String[]</code> by
* <code>oracle.jdbc.driver.JDBCPrepareStatementWithArrayInterceptor</code>
* 3. Enhance <code>prepareStatement</code> that the seconds argument type is <code>int[]</code> by
* <code>oracle.jdbc.driver.JDBCPrepareStatementWithArrayInterceptor</code>
* 4. Enhance <code>prepareCall</code> by
* <code>org.skywalking.apm.plugin.jdbc.define.JDBCPrepareCallInterceptor</code>
* 5. Enhance <code>createStatement</code>
* by <code>org.skywalking.apm.plugin.jdbc.define.JDBCStatementInterceptor</code>
* 6. Enhance <code>commit, rollback, close, releaseSavepoint</code> by <code>org.skywalking.apm.plugin.jdbc.define.ConnectionServiceMethodInterceptor</code>
*
* @author zhangxin
*/
public class ConnectionInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String PREPARE_STATEMENT_METHOD_WITH_ARRAY_INTERCEPTOR_CLASS = "oracle.jdbc.driver.JDBCPrepareStatementWithArrayInterceptor";
public static final String ENHANCE_CLASS = "oracle.jdbc.driver.PhysicalConnection";
public static final String STRING_ARRAY_ARGUMENT_TYPE = "java.lang.String[]";
public static final String INT_ARRAY_ARGUMENT_TYPE = "int[]";
@Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(PREPARE_STATEMENT_METHOD_NAME).and(takesArguments(3));
}
@Override public String getMethodsInterceptor() {
return PREPARE_STATEMENT_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(PREPARE_STATEMENT_METHOD_NAME).and(takesArgumentWithType(1, STRING_ARRAY_ARGUMENT_TYPE));
}
@Override public String getMethodsInterceptor() {
return PREPARE_STATEMENT_METHOD_WITH_ARRAY_INTERCEPTOR_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(PREPARE_STATEMENT_METHOD_NAME).and(takesArgumentWithType(1, INT_ARRAY_ARGUMENT_TYPE));
}
@Override public String getMethodsInterceptor() {
return PREPARE_STATEMENT_METHOD_WITH_ARRAY_INTERCEPTOR_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(PREPARE_CALL_METHOD_NAME).and(takesArguments(3));
}
@Override public String getMethodsInterceptor() {
return PREPARE_CALL_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(CREATE_STATEMENT_METHOD_NAME).and(takesArguments(2));
}
@Override public String getMethodsInterceptor() {
return CREATE_STATEMENT_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(COMMIT_METHOD_NAME).or(named(ROLLBACK_METHOD_NAME)).or(named(CLOSE_METHOD_NAME)).or(named(RELEASE_SAVE_POINT_METHOD_NAME));
}
@Override public String getMethodsInterceptor() {
return SERVICE_METHOD_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override protected ClassMatch enhanceClass() {
return byName(ENHANCE_CLASS);
}
}
......@@ -16,19 +16,20 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.define;
package org.skywalking.apm.plugin.jdbc.oracle.define;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.skywalking.apm.plugin.jdbc.define.AbstractDriverInstrumentation;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
/**
* {@link OracleInstrumentation} presents that skywalking intercepts the class <code>oracle.jdbc.OracleDriver
* </code>.
* {@link DriverInstrumentation} presents that skywalking intercepts {@link oracle.jdbc.driver.OracleDriver}.
*
* @author zhangxin
*/
public class OracleInstrumentation extends AbstractDatabaseInstrumentation {
public class DriverInstrumentation extends AbstractDriverInstrumentation {
@Override
protected ClassMatch enhanceClass() {
return byName("oracle.jdbc.driver.OracleDriver");
......
oracle-10.x=org.skywalking.apm.plugin.jdbc.oracle.define.DriverInstrumentation
oracle-10.x=org.skywalking.apm.plugin.jdbc.oracle.define.ConnectionInstrumentation
......@@ -30,7 +30,7 @@
<artifactId>apm-sdk-plugin</artifactId>
<modules>
<module>dubbo-plugin</module>
<module>jdbc-plugin</module>
<module>jdbc-commons</module>
<module>httpClient-4.x-plugin</module>
<module>jedis-2.x-plugin</module>
<module>tomcat-7.x-8.x-plugin</module>
......@@ -48,6 +48,10 @@
<module>sharding-jdbc-1.5.x-plugin</module>
<module>xmemcached-2.x-plugin</module>
<module>grpc-1.x-plugin</module>
<module>mysql-2.x-plugin</module>
<module>h2-1.x-plugin</module>
<module>postgresql-8.x-plugin</module>
<module>oracle-10.x-plugin</module>
</modules>
<packaging>pom</packaging>
......
<!--
~ Copyright 2017, OpenSkywalking Organization All rights reserved.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~
~ Project repository: https://github.com/OpenSkywalking/skywalking
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>apm-sdk-plugin</artifactId>
<groupId>org.skywalking</groupId>
<version>3.2.3-2017</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>apm-postgresql-8.x-plugin</artifactId>
<packaging>jar</packaging>
<name>postgresql-8.x-plugin</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.skywalking</groupId>
<artifactId>apm-jdbc-commons</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
</plugin>
<plugin>
<!-- 源码插件 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<!-- 发布时自动将源码同时发布的配置 -->
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.postgresql;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import org.skywalking.apm.plugin.jdbc.trace.SWPreparedStatement;
/**
* {@link JDBCPrepareStatementWithStringArrayInterceptor} return {@link SWPreparedStatement} instance that wrapper the
* real preparedStatement instance when the client call <code>org.postgresql.jdbc.PgConnection#prepareStatement(String,
* String[]) </code> method. method.
*
* @author zhangxin
*/
public class JDBCPrepareStatementWithStringArrayInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
/**
* To prevent the <code>org.postgresql.jdbc.prepareStatement(String sql)</code> method from repeating
* interceptor, Because PGConnection call <code>org.postgresql.jdbc.prepareStatement(String sql)</code> method when
* the second argument is empty.
*
* @see org.postgresql.jdbc.PgConnection#prepareStatement(String, String[])
**/
String[] columnNames = (String[])allArguments[1];
if (columnNames != null && columnNames.length == 0) {
return ret;
}
return new SWPreparedStatement((Connection)objInst, (PreparedStatement)ret, (ConnectionInfo)objInst.getSkyWalkingDynamicField(), (String)allArguments[0]);
}
@Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.postgresql.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import static org.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CLOSE_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.COMMIT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CREATE_STATEMENT_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CREATE_STATEMENT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_CALL_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_CALL_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_STATEMENT_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_STATEMENT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.RELEASE_SAVE_POINT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.ROLLBACK_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.SERVICE_METHOD_INTERCEPT_CLASS;
/**
* {@link ConnectionInstrumentation} intercept the following methods that the class which extend {@link
* org.postgresql.jdbc.PgConnection}. <br/>
*
* 1. Enhance <code>prepareStatement</code> by <code>org.skywalking.apm.plugin.jdbc.define.JDBCPrepareStatementInterceptor</code>
* 2. Enhance <code>prepareStatement</code> that the seconds argument type is <code>java.lang.String[]</code> by
* <code>org.skywalking.apm.plugin.jdbc.postgresql.JDBCPrepareStatementWithStringArrayInterceptor</code>
* 3. Enhance <code>prepareCall</code> by
* <code>org.skywalking.apm.plugin.jdbc.define.JDBCPrepareCallInterceptor</code>
* 4. Enhance <code>createStatement</code>
* by <code>org.skywalking.apm.plugin.jdbc.define.JDBCStatementInterceptor</code>
* 5. Enhance <code>commit, rollback, close, releaseSavepoint</code> by <code>org.skywalking.apm.plugin.jdbc.define.ConnectionServiceMethodInterceptor</code>
*
* @author zhangxin
*/
public class ConnectionInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String PREPARE_STATEMENT_METHOD_WITH_STRING_ARRAY_INTERCEPTOR_CLASS = "org.skywalking.apm.plugin.jdbc.postgresql.JDBCPrepareStatementWithStringArrayInterceptor";
public static final String ENHANCE_CLASS = "org.postgresql.jdbc.PgConnection";
public static final String STRING_ARRAY_ARGUMENT_TYPE = "java.lang.String[]";
@Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(PREPARE_STATEMENT_METHOD_NAME).and(takesArguments(4));
}
@Override public String getMethodsInterceptor() {
return PREPARE_STATEMENT_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(PREPARE_STATEMENT_METHOD_NAME).and(takesArgumentWithType(1, STRING_ARRAY_ARGUMENT_TYPE));
}
@Override public String getMethodsInterceptor() {
return PREPARE_STATEMENT_METHOD_WITH_STRING_ARRAY_INTERCEPTOR_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(PREPARE_CALL_METHOD_NAME).and(takesArguments(4));
}
@Override public String getMethodsInterceptor() {
return PREPARE_CALL_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(CREATE_STATEMENT_METHOD_NAME).and(takesArguments(3));
}
@Override public String getMethodsInterceptor() {
return CREATE_STATEMENT_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(COMMIT_METHOD_NAME).or(named(ROLLBACK_METHOD_NAME)).or(named(CLOSE_METHOD_NAME)).or(named(RELEASE_SAVE_POINT_METHOD_NAME));
}
@Override public String getMethodsInterceptor() {
return SERVICE_METHOD_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override protected ClassMatch enhanceClass() {
return byName(ENHANCE_CLASS);
}
}
......@@ -16,18 +16,20 @@
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.define;
package org.skywalking.apm.plugin.jdbc.postgresql.define;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.skywalking.apm.plugin.jdbc.define.AbstractDriverInstrumentation;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
/**
* {@link PostgreSQLInstrumentation} presents that skywalking intercepts {@link org.postgresql.Driver}.
* {@link DriverInstrumentation} presents that skywalking intercepts {@link org.postgresql.Driver}.
*
* @author zhangxin
*/
public class PostgreSQLInstrumentation extends AbstractDatabaseInstrumentation {
public class DriverInstrumentation extends AbstractDriverInstrumentation {
@Override
protected ClassMatch enhanceClass() {
return byName("org.postgresql.Driver");
......
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.postgresql.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CLOSE_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.COMMIT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CREATE_STATEMENT_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CREATE_STATEMENT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_CALL_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_CALL_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_STATEMENT_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_STATEMENT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.RELEASE_SAVE_POINT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.ROLLBACK_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.SERVICE_METHOD_INTERCEPT_CLASS;
/**
* {@link ConnectionInstrumentation} intercept the following methods that the class which extend {@link
* org.postgresql.jdbc.PgConnection}. <br/>
*
* 1. Enhance <code>prepareStatement</code> by <code>org.skywalking.apm.plugin.jdbc.define.JDBCPrepareStatementInterceptor</code>
* 2. Enhance <code>prepareCall</code> by
* <code>org.skywalking.apm.plugin.jdbc.define.JDBCPrepareCallInterceptor</code>
* 3. Enhance <code>createStatement</code>
* by <code>org.skywalking.apm.plugin.jdbc.define.JDBCStatementInterceptor</code>
* 4. Enhance <code>commit, rollback, close, releaseSavepoint</code> by <code>org.skywalking.apm.plugin.jdbc.define.ConnectionServiceMethodInterceptor</code>
*
* @author zhangxin
*/
public class Jdbc3ConnectionInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
public static final String ENHANCE_CLASS = "org.postgresql.jdbc3.Jdbc3Connection";
@Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(PREPARE_STATEMENT_METHOD_NAME).and(takesArguments(4));
}
@Override public String getMethodsInterceptor() {
return PREPARE_STATEMENT_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(PREPARE_CALL_METHOD_NAME).and(takesArguments(4));
}
@Override public String getMethodsInterceptor() {
return PREPARE_CALL_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(CREATE_STATEMENT_METHOD_NAME).and(takesArguments(3));
}
@Override public String getMethodsInterceptor() {
return CREATE_STATEMENT_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named(COMMIT_METHOD_NAME).or(named(ROLLBACK_METHOD_NAME)).or(named(CLOSE_METHOD_NAME)).or(named(RELEASE_SAVE_POINT_METHOD_NAME));
}
@Override public String getMethodsInterceptor() {
return SERVICE_METHOD_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override protected ClassMatch enhanceClass() {
return byName(ENHANCE_CLASS);
}
}
postgresql-8.x=org.skywalking.apm.plugin.jdbc.postgresql.define.DriverInstrumentation
postgresql-8.x=org.skywalking.apm.plugin.jdbc.postgresql.define.Jdbc3ConnectionInstrumentation
postgresql-8.x=org.skywalking.apm.plugin.jdbc.postgresql.define.ConnectionInstrumentation
......@@ -38,12 +38,6 @@
</properties>
<dependencies>
<dependency>
<groupId>${groupId}</groupId>
<artifactId>apm-jdbc-plugin</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
......@@ -89,4 +83,4 @@
</plugins>
</build>
</project>
\ No newline at end of file
</project>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册