Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Release Notes.
* Support for C3P0 connection pool tracing.
* Use a daemon thread to flush logs.
* Fix typos in `URLParser`.
* Add support for `Derby`/`Sybase`/`SQLite`/`DB2`/`OceanBase` jdbc url format in `URLParser`.

All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/213?closed=1)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,15 @@ public class ComponentsDefine {

public static final OfficialComponent C3P0 = new OfficialComponent(152, "c3p0");

public static final OfficialComponent DERBY_JDBC_DRIVER = new OfficialComponent(153, "Derby-jdbc-driver");

public static final OfficialComponent SQLITE_JDBC_DRIVER = new OfficialComponent(154, "Sqlite-jdbc-driver");

public static final OfficialComponent DB2_JDBC_DRIVER = new OfficialComponent(155, "Db2-jdbc-driver");

public static final OfficialComponent SYBASE_JDBC_DRIVER = new OfficialComponent(156, "Sybase-jdbc-driver");

public static final OfficialComponent OCEANBASE_JDBC_DRIVER = new OfficialComponent(157, "OceanBase-jdbc-driver");


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.apache.skywalking.apm.plugin.jdbc.connectionurl.parser;

import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;

public class Db2URLParser extends AbstractURLParser {
private static final String DEFAULT_HOST = "localhost";
private static final int DEFAULT_PORT = 50000;
private static final String DB_TYPE = "DB2";
private static final String JDBC_PREFIX = "jdbc:db2:";

public Db2URLParser(String url) {
super(url);
}

@Override
protected URLLocation fetchDatabaseHostsIndexRange() {
int hostLabelStartIndex = url.indexOf("//");
if (hostLabelStartIndex == -1) {
return null;
}
int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex + 2);
int hostLabelEndIndexWithParameter = url.indexOf(":", hostLabelEndIndex + 1);
if (hostLabelEndIndex == -1) {
hostLabelEndIndex = hostLabelEndIndexWithParameter;
}
if (hostLabelEndIndexWithParameter < hostLabelEndIndex && hostLabelEndIndexWithParameter != -1) {
hostLabelEndIndex = hostLabelEndIndexWithParameter;
}
if (hostLabelEndIndex == -1) {
hostLabelEndIndex = url.length();
}
return new URLLocation(hostLabelStartIndex + 2, hostLabelEndIndex);
}

protected String fetchDatabaseNameFromURL(int startSize) {
URLLocation hostsLocation = fetchDatabaseNameIndexRange(startSize);
if (hostsLocation == null) {
return "";
}
return url.substring(hostsLocation.startIndex(), hostsLocation.endIndex());
}

protected URLLocation fetchDatabaseNameIndexRange(int startSize) {
int databaseStartTag = url.indexOf("/", startSize);
int parameterStartTag = url.indexOf(":", startSize);
if (parameterStartTag < databaseStartTag && parameterStartTag != -1) {
return null;
}
if (databaseStartTag == -1) {
databaseStartTag = startSize - 1;
}
int databaseEndTag = url.indexOf(":", startSize);
if (databaseEndTag == -1) {
databaseEndTag = url.length();
}
return new URLLocation(databaseStartTag + 1, databaseEndTag);
}

@Override
protected URLLocation fetchDatabaseNameIndexRange() {
int databaseStartTag = url.lastIndexOf("/");
int databaseEndTag = url.indexOf(":", databaseStartTag);
if (databaseEndTag == -1) {
databaseEndTag = url.length();
}
return new URLLocation(databaseStartTag + 1, databaseEndTag);
}

@Override
public ConnectionInfo parse() {
URLLocation location = fetchDatabaseHostsIndexRange();
if (location == null) {
return new ConnectionInfo(
ComponentsDefine.DB2_JDBC_DRIVER, DB_TYPE, DEFAULT_HOST, DEFAULT_PORT,
fetchDatabaseNameFromURL(JDBC_PREFIX.length())
);
}
String hosts = url.substring(location.startIndex(), location.endIndex());
String[] hostSegment = hosts.split(",");
if (hostSegment.length > 1) {
StringBuilder sb = new StringBuilder();
for (String host : hostSegment) {
if (host.split(":").length == 1) {
sb.append(host).append(":").append(DEFAULT_PORT).append(",");
} else {
sb.append(host).append(",");
}
}
return new ConnectionInfo(
ComponentsDefine.DB2_JDBC_DRIVER, DB_TYPE, sb.substring(0, sb.length() - 1),
fetchDatabaseNameFromURL()
);
} else {
String[] hostAndPort = hostSegment[0].split(":");
if (hostAndPort.length != 1) {
return new ConnectionInfo(
ComponentsDefine.DB2_JDBC_DRIVER, DB_TYPE, hostAndPort[0], Integer.valueOf(hostAndPort[1]),
fetchDatabaseNameFromURL(location
.endIndex())
);
} else {
return new ConnectionInfo(
ComponentsDefine.DB2_JDBC_DRIVER, DB_TYPE, hostAndPort[0], DEFAULT_PORT,
fetchDatabaseNameFromURL(location
.endIndex())
);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.apache.skywalking.apm.plugin.jdbc.connectionurl.parser;

import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;

public class DerbyURLParser extends AbstractURLParser {

private static final String DEFAULT_HOST = "localhost";
private static final int DEFAULT_PORT = 1527;
private static final String DB_TYPE = "Derby";
private static final String DERBY_JDBC_URL_PREFIX = "jdbc:derby";
/**
* Flag that running with directory mode.
*/
private static final String DIRECTORY_MODE_FLAG = "derby:directory";
/**
* Flag that running with memory mode.
*/
private static final String MEMORY_MODE_FLAG = "derby:memory";
/**
* Flag that running with classpath mode.
*/
private static final String CLASSPATH_MODE_FLAG = "derby:classpath";
/**
* Flag that running with jar mode.
*/
private static final String JAR_MODE_FLAG = "derby:jar";

public DerbyURLParser(String url) {
super(url);
}

/**
* Fetch range index that the database name from connection url if Derby database running in client/server
* environment. eg: jdbc:derby://host[:port]/[databaseName][;attribute=value]*
*
* @return range index that the database name.
*/
@Override
protected URLLocation fetchDatabaseHostsIndexRange() {
int hostLabelStartIndex = url.indexOf("//");
int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex + 2);
return new URLLocation(hostLabelStartIndex + 2, hostLabelEndIndex);
}

@Override
protected URLLocation fetchDatabaseNameIndexRange() {
int databaseEndTag = url.indexOf(";");
if (databaseEndTag == -1) {
databaseEndTag = url.length();
}
int databaseStartTag = url.lastIndexOf("\\");
if (databaseStartTag == -1) {
databaseStartTag = url.lastIndexOf("/");
}
if (url.indexOf(":", databaseStartTag) != -1) {
databaseStartTag = url.indexOf(":", databaseStartTag);
}
return new URLLocation(databaseStartTag + 1, databaseEndTag);
}

@Override
public ConnectionInfo parse() {
int[] databaseNameRangeIndex = fetchDatabaseNameRangeIndexForSubProtocol(DIRECTORY_MODE_FLAG);
if (databaseNameRangeIndex != null) {
return defaultConnection(databaseNameRangeIndex);
}
databaseNameRangeIndex = fetchDatabaseNameRangeIndexForSubProtocol(MEMORY_MODE_FLAG);
if (databaseNameRangeIndex != null) {
return defaultConnection(databaseNameRangeIndex);
}
databaseNameRangeIndex = fetchDatabaseNameRangeIndexForSubProtocol(CLASSPATH_MODE_FLAG);
if (databaseNameRangeIndex != null) {
return defaultConnection(databaseNameRangeIndex);
}
databaseNameRangeIndex = fetchDatabaseNameRangeIndexForSubProtocol(JAR_MODE_FLAG);
if (databaseNameRangeIndex != null) {
return defaultConnection(databaseNameRangeIndex);
}
databaseNameRangeIndex = fetchDatabaseNameRangeIndexWithoutHosts();
if (databaseNameRangeIndex != null) {
return defaultConnection(databaseNameRangeIndex);
}
String[] hostAndPort = fetchDatabaseHostsFromURL().split(":");
if (hostAndPort.length == 1) {
return new ConnectionInfo(
ComponentsDefine.DERBY_JDBC_DRIVER, DB_TYPE, hostAndPort[0], DEFAULT_PORT, fetchDatabaseNameFromURL());
} else {
return new ConnectionInfo(
ComponentsDefine.DERBY_JDBC_DRIVER, DB_TYPE, hostAndPort[0], Integer.valueOf(hostAndPort[1]),
fetchDatabaseNameFromURL()
);
}
}

/**
* Fetch range index that the database name from connection url if Derby database running in embedded environment.
* eg: jdbc:derby:[databaseName][;attribute=value]*
*
* @return range index that the database name.
*/
private int[] fetchDatabaseNameRangeIndexWithoutHosts() {
if (url.contains("//")) {
return null;
}
int fileLabelIndex = url.indexOf(DERBY_JDBC_URL_PREFIX);
int parameterLabelIndex = url.indexOf(";");
if (parameterLabelIndex == -1) {
parameterLabelIndex = url.length();
}

if (fileLabelIndex != -1) {
int pathLabelIndexForLinux = url.lastIndexOf("/");
if (pathLabelIndexForLinux != -1 && pathLabelIndexForLinux > fileLabelIndex) {
return new int[] {
pathLabelIndexForLinux + 1,
parameterLabelIndex
};
}
int pathLabelIndexForWin = url.lastIndexOf("\\");
if (pathLabelIndexForWin != -1 && pathLabelIndexForWin > fileLabelIndex) {
return new int[] {
pathLabelIndexForWin + 1,
parameterLabelIndex
};
}
return new int[] {
fileLabelIndex + DERBY_JDBC_URL_PREFIX.length() + 1,
parameterLabelIndex
};
} else {
return null;
}
}

/**
* Fetch range index that the database name from connection url if Derby database running with subprotocol. eg:
* jdbc:derby:subprotocol:[databaseName][;attribute=value]*
*
* @return range index that the database name.
*/
private int[] fetchDatabaseNameRangeIndexForSubProtocol(String mode) {
int fileLabelIndex = url.indexOf(mode);
int parameterLabelIndex = url.indexOf(";", fileLabelIndex);
if (parameterLabelIndex == -1) {
parameterLabelIndex = url.length();
}

if (fileLabelIndex != -1) {
int pathLabelIndexForLinux = url.lastIndexOf("/");
if (pathLabelIndexForLinux != -1 && pathLabelIndexForLinux > fileLabelIndex) {
return new int[] {
pathLabelIndexForLinux + 1,
parameterLabelIndex
};
}
int pathLabelIndexForWin = url.lastIndexOf("\\");
if (pathLabelIndexForWin != -1 && pathLabelIndexForWin > fileLabelIndex) {
return new int[] {
pathLabelIndexForWin + 1,
parameterLabelIndex
};
}
return new int[] {
fileLabelIndex + mode.length() + 1,
parameterLabelIndex
};
} else {
return null;
}
}

private ConnectionInfo defaultConnection(int[] databaseNameRangeIndex) {
return new ConnectionInfo(
ComponentsDefine.DERBY_JDBC_DRIVER, DB_TYPE, DEFAULT_HOST, -1,
fetchDatabaseNameFromURL(databaseNameRangeIndex)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.apache.skywalking.apm.plugin.jdbc.connectionurl.parser;

import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;

public class OceanBaseURLParser extends MysqlURLParser {
public OceanBaseURLParser(String url) {
super(url, "OceanBase", ComponentsDefine.OCEANBASE_JDBC_DRIVER, 2881);
}
}
Loading