提交 d655c23c 编写于 作者: A ascrutae

处理JDBC插件

上级 61d79760
package com.ai.cloud.skywalking.plugin.jdbc;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.sql.DriverManager;
import java.util.concurrent.CopyOnWriteArrayList;
import com.ai.cloud.skywalking.logging.LogManager;
import com.ai.cloud.skywalking.logging.Logger;
import com.ai.cloud.skywalking.plugin.boot.BootException;
import com.ai.cloud.skywalking.plugin.boot.IBootPluginDefine;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.sql.DriverManager;
import java.util.concurrent.CopyOnWriteArrayList;
public class JDBCPluginDefine implements IBootPluginDefine {
private static Logger logger = LogManager.getLogger(JDBCPluginDefine.class);
......@@ -20,24 +20,26 @@ public class JDBCPluginDefine implements IBootPluginDefine {
Object traceDriverInfo = newDriverInfoInstance(classes);
Field field = DriverManager.class.getDeclaredField("registeredDrivers");
field.setAccessible(true);
@SuppressWarnings("unchecked")
CopyOnWriteArrayList<Object> copyOnWriteArrayList = (CopyOnWriteArrayList<Object>) field.get(DriverManager.class);
@SuppressWarnings("unchecked") CopyOnWriteArrayList<Object> copyOnWriteArrayList =
(CopyOnWriteArrayList<Object>) field.get(DriverManager.class);
copyOnWriteArrayList.add(0, traceDriverInfo);
} catch (Throwable e) {
// 开启补偿机制
logger.error(
"Failed to inject TracingDriver to the top of registered Drivers. Need to alter jdbc url to trace.",
e);
TracingDriver.registerDriver();
}
}
// 开启补偿机制
logger.error(
"Failed to inject TracingDriver to the top of registered Drivers. Need to alter jdbc url to trace.",
e);
TracingDriver.registerDriver();
}
}
private Object newDriverInfoInstance(Class<?> classes) throws NoSuchMethodException, InstantiationException, IllegalAccessException, java.lang.reflect.InvocationTargetException {
private Object newDriverInfoInstance(Class<?> classes)
throws NoSuchMethodException, InstantiationException, IllegalAccessException,
java.lang.reflect.InvocationTargetException {
//DriverInfo 只有一个构造函数
Constructor constructor = classes.getDeclaredConstructors()[0];
constructor.setAccessible(true);
// JDK 1.7 DriverInfo 只有一个Driver入参构造函数
if (constructor.getParameterTypes().length == 1){
if (constructor.getParameterTypes().length == 1) {
return constructor.newInstance(new TracingDriver());
}
// JDK1.8 DriverInfo 有两个入参的构造函数(Driver, DriverAction)
......
......@@ -4,13 +4,8 @@ import com.ai.cloud.skywalking.conf.AuthDesc;
import com.ai.cloud.skywalking.logging.LogManager;
import com.ai.cloud.skywalking.logging.Logger;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Enumeration;
import java.util.Properties;
public class TracingDriver implements Driver {
......@@ -35,9 +30,9 @@ public class TracingDriver implements Driver {
}
public java.sql.Connection connect(String url, Properties info) throws SQLException {
Driver driver = DriverChooser.choose(convertConnectURLIfNecessary(url));
Driver driver = chooseActualDriver(convertConnectURLIfNecessary(url));
if (driver == null) {
throw new SQLException("Failed to choose driver by url[{}].", convertConnectURLIfNecessary(url));
throw new SQLException("Failed to chooseActualDriver driver by url[{}].", convertConnectURLIfNecessary(url));
}
java.sql.Connection conn = driver.
......@@ -51,7 +46,7 @@ public class TracingDriver implements Driver {
}
public boolean acceptsURL(String url) throws SQLException {
Driver driver = DriverChooser.choose(convertConnectURLIfNecessary(url));
Driver driver = chooseActualDriver(convertConnectURLIfNecessary(url));
if (driver == null) {
return false;
}
......@@ -60,7 +55,7 @@ public class TracingDriver implements Driver {
}
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
return DriverChooser.choose(convertConnectURLIfNecessary(url)).
return chooseActualDriver(convertConnectURLIfNecessary(url)).
getPropertyInfo(convertConnectURLIfNecessary(url), info);
}
......@@ -80,70 +75,26 @@ public class TracingDriver implements Driver {
return null;
}
static class DriverChooser {
private static Logger logger = LogManager.getLogger(DriverChooser.class);
private static Map<String, String> urlDriverMapping = new HashMap<String, String>();
static {
fetchUrlDriverMapping();
}
public static Driver choose(String url) {
String driverClassStr = chooseDriverClass(url);
Driver driver = null;
try {
Class<?> driverClass = Class.forName(driverClassStr);
driver = (Driver) driverClass.newInstance();
} catch (Exception e) {
logger.error("Failed to initial Driver class {}.", new Object[] {driverClassStr}, e);
}
return driver;
}
private static String chooseDriverClass(String url) {
Iterator<String> mapping = urlDriverMapping.keySet().iterator();
while (mapping.hasNext()) {
String urlPrefix = mapping.next();
if (url.startsWith(urlPrefix)) {
String driverClassStr = urlDriverMapping.get(urlPrefix);
logger.debug("Success choose the driver class [{}] by connection url[{}]", driverClassStr, url);
return driverClassStr;
private static Driver chooseActualDriver(String url) throws SQLException {
try {
Driver result = null;
for (Enumeration<Driver> drivers = DriverManager.getDrivers(); drivers.hasMoreElements(); ) {
Driver driver = drivers.nextElement();
if (driver instanceof TracingDriver) {
continue;
}
}
logger.warn("Cannot match the driver class by connection url [{}].", url);
return null;
}
private static void fetchUrlDriverMapping() {
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new InputStreamReader(DriverChooser.class.
getResourceAsStream("/driver-mapping-url.def")));
String mappingString = null;
while ((mappingString = bufferedReader.readLine()) != null) {
fillMapping(mappingString);
}
} catch (Exception e) {
logger.error("Failed to load driver-mapping-url.def.");
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
logger.error("Failed to close driver-mapping-url.def.", e);
}
if (driver.acceptsURL(url)) {
result = driver;
}
}
}
private static void fillMapping(String mappingString) {
String[] tmpMapping = mappingString.split("=");
if (tmpMapping.length == 2) {
urlDriverMapping.put(tmpMapping[0], tmpMapping[1]);
}
return result;
} catch (Exception e) {
logger.error("Failed to chooseActualDriver sql driver with url[" + url + "]", e);
throw new SQLException("Failed to chooseActualDriver sql driver with url[" + url + "]", e);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册