From 7558d731811c6a188906703fea888a0e79752904 Mon Sep 17 00:00:00 2001 From: saberwang Date: Mon, 9 Jun 2025 13:47:28 +0800 Subject: [PATCH 1/8] [Feature] Add URLParser for dameng(DM) --- .../trace/component/ComponentsDefine.java | 3 + .../connectionurl/parser/DMURLParser.java | 116 ++++++++++++++++++ .../jdbc/connectionurl/parser/URLParser.java | 4 + .../connectionurl/parser/URLParserTest.java | 45 +++++++ .../java-agent/Supported-list.md | 1 + 5 files changed, 169 insertions(+) create mode 100644 apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/DMURLParser.java diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java index d81ba8c136..bfebcebbaf 100755 --- a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java +++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java @@ -262,4 +262,7 @@ public class ComponentsDefine { public static final OfficialComponent CAFFEINE = new OfficialComponent(160, "Caffeine"); public static final OfficialComponent THREAD_PER_TASK_EXECUTOR = new OfficialComponent(161, "ThreadPerTask-executor"); + + public static final OfficialComponent DMDB_JDBC_DRIVER = new OfficialComponent(162, "Dmdb-jdbc-driver"); + } diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/DMURLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/DMURLParser.java new file mode 100644 index 0000000000..cc2a2d1052 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/DMURLParser.java @@ -0,0 +1,116 @@ +/* + * 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 DMURLParser extends AbstractURLParser { + private static final int DEFAULT_PORT = 5236; + private static final String DB_TYPE = "DM"; + private static final String URL_PARAMS_HOST_KEY = "host"; + private static final String URL_PARAMS_PORT_KEY = "port"; + private static final String URL_PARAMS_SCHEMA_KEY = "schema"; + + public DMURLParser(String url) { + super(url); + } + + @Override + protected URLLocation fetchDatabaseHostsIndexRange() { + int hostLabelStartIndex = url.indexOf("//"); + if (hostLabelStartIndex == -1) { + return new URLLocation(0, 0); // 格式错误 + } + int hostLabelEndIndex = url.indexOf("?", hostLabelStartIndex + 2); + if (hostLabelEndIndex == -1) { + hostLabelEndIndex = url.length(); + } + return new URLLocation(hostLabelStartIndex + 2, hostLabelEndIndex); + } + + @Override + protected URLLocation fetchDatabaseNameIndexRange() { + return new URLLocation(0, 0); + } + + @Override + public ConnectionInfo parse() { + URLLocation location = fetchDatabaseHostsIndexRange(); + String hostPortSegment = ""; + if (location.endIndex() > location.startIndex()) { + hostPortSegment = url.substring(location.startIndex(), location.endIndex()); + } + + String host = ""; + String port = ""; + + if (!hostPortSegment.isEmpty()) { + String[] parts = hostPortSegment.split(":"); + if (parts.length >= 1) { + host = parts[0]; + } + if (parts.length == 2) { + port = parts[1]; + } + } + + // 如果 host 或 port 没有从路径中获取到,则尝试从参数中获取 + if (host.isEmpty()) { + host = fetchFromUrlParams(URL_PARAMS_HOST_KEY); + } + if (port == null || port.isEmpty()) { + port = fetchFromUrlParams(URL_PARAMS_PORT_KEY); + } + + if (port == null || port.isEmpty()) { + port = String.valueOf(DEFAULT_PORT); + } + + String schema = fetchFromUrlParams(URL_PARAMS_SCHEMA_KEY); + + return new ConnectionInfo( + ComponentsDefine.DMDB_JDBC_DRIVER, + DB_TYPE, + host, + Integer.parseInt(port), + schema == null ? "" : schema + ); + } + + /** + * 从 URL 参数中提取指定 key 的值 + */ + private String fetchFromUrlParams(String key) { + int paramIndex = url.indexOf("?"); + if (paramIndex == -1) { + return null; + } + String[] params = url.substring(paramIndex + 1).split("&"); + for (String pair : params) { + if (pair.startsWith(key + "=")) { + String[] segments = pair.split("=", 2); + if (segments.length == 2) { + return segments[1]; + } + } + } + return null; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java index cb79d58b0c..83afcf9efa 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java @@ -41,6 +41,7 @@ public class URLParser { private static final String DB2_JDBC_URL_PREFIIX = "jdbc:db2:"; private static final String SYBASE_JDBC_URL_PREFIX = "jdbc:sybase:tds:"; private static final String OCEANBASE_JDBC_URL_PREFIX = "jdbc:oceanbase:"; + private static final String DM_JDBC_URL_PREFIX = "jdbc:dm:"; public static ConnectionInfo parser(String url) { ConnectionURLParser parser = null; @@ -75,7 +76,10 @@ public static ConnectionInfo parser(String url) { parser = new SybaseURLParser(url); } else if (lowerCaseUrl.startsWith(OCEANBASE_JDBC_URL_PREFIX)) { parser = new OceanBaseURLParser(url); + } else if (lowerCaseUrl.startsWith(DM_JDBC_URL_PREFIX)) { + parser = new DMURLParser(url); } + return parser.parse(); } } diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParserTest.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParserTest.java index 2a0e87e315..a9a38450e0 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParserTest.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParserTest.java @@ -415,4 +415,49 @@ public void testParseSybaseJDBCURL() { assertThat(connectionInfo.getDatabaseName(), is("mydb")); assertThat(connectionInfo.getDatabasePeer(), is("localhost:5000")); } + + @Test + public void testParseDMJDBCURLWithNamedParams() + { + ConnectionInfo connectionInfo = URLParser.parser("jdbc:dm://?host=localhost&port=5236"); + assertThat(connectionInfo.getDBType(), is("DM")); + assertThat(connectionInfo.getDatabaseName(), is("")); + assertThat(connectionInfo.getDatabasePeer(), is("localhost:5236")); + } + + @Test + public void testParseDMJDBCURLWithNamedParamsAndScheme() + { + ConnectionInfo connectionInfo = URLParser.parser("jdbc:dm://?host=localhost&port=5236&schema=dm"); + assertThat(connectionInfo.getDBType(), is("DM")); + assertThat(connectionInfo.getDatabaseName(), is("dm")); + assertThat(connectionInfo.getDatabasePeer(), is("localhost:5236")); + } + + @Test + public void testParseDMJDBCURLWithoutHost() + { + ConnectionInfo connectionInfo = URLParser.parser("jdbc:dm://localhost"); + assertThat(connectionInfo.getDBType(), is("DM")); + assertThat(connectionInfo.getDatabaseName(), is("")); + assertThat(connectionInfo.getDatabasePeer(), is("localhost:5236")); + } + + @Test + public void testParseDMJDBCURLWithoutHostAndScheme() + { + ConnectionInfo connectionInfo = URLParser.parser("jdbc:dm://localhost?schema=dm"); + assertThat(connectionInfo.getDBType(), is("DM")); + assertThat(connectionInfo.getDatabaseName(), is("dm")); + assertThat(connectionInfo.getDatabasePeer(), is("localhost:5236")); + } + + @Test + public void testParseDMJDBCURLWithoutHostPort() + { + ConnectionInfo connectionInfo = URLParser.parser("jdbc:dm://localhost:5237?schema=dm"); + assertThat(connectionInfo.getDBType(), is("DM")); + assertThat(connectionInfo.getDatabaseName(), is("dm")); + assertThat(connectionInfo.getDatabasePeer(), is("localhost:5237")); + } } diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md index cd51b8d2ce..ec607f59ce 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -185,6 +185,7 @@ The meter plugin provides the advanced metrics collections, which are not a part * [DB2](https://www.ibm.com/products/db2/database) * Sybase * [OceanBase](https://www.oceanbase.com/) + * [DaMeng](https://www.dameng.com/) * Supported Connection Pool Frameworks * [Apache Commons DBCP](https://github.com/apache/commons-dbcp) 2.x * [Alibaba Druid](https://github.com/alibaba/druid) 1.x From 99455ee9e444c55fec0c96b3288712bec827f7a6 Mon Sep 17 00:00:00 2001 From: saberwang Date: Mon, 9 Jun 2025 13:58:58 +0800 Subject: [PATCH 2/8] update CHANGES --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 8e58c3459d..b4a963dde9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ Release Notes. initialization. Delay so11y metrics#build when the services are not ready to avoid MeterService status is not initialized. * Fix retransform failure when enhancing both parent and child classes. +* Add support for `dameng(DM)` jdbc url format in `URLParser`. All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/236?closed=1) From e6e5201821ecd80b2783ae20d3849227d1fc181a Mon Sep 17 00:00:00 2001 From: saberwang Date: Mon, 9 Jun 2025 14:04:00 +0800 Subject: [PATCH 3/8] Clean up comments --- .../apm/plugin/jdbc/connectionurl/parser/DMURLParser.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/DMURLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/DMURLParser.java index cc2a2d1052..2cb4c1c4c0 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/DMURLParser.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/DMURLParser.java @@ -36,7 +36,7 @@ public DMURLParser(String url) { protected URLLocation fetchDatabaseHostsIndexRange() { int hostLabelStartIndex = url.indexOf("//"); if (hostLabelStartIndex == -1) { - return new URLLocation(0, 0); // 格式错误 + return new URLLocation(0, 0); } int hostLabelEndIndex = url.indexOf("?", hostLabelStartIndex + 2); if (hostLabelEndIndex == -1) { @@ -71,7 +71,6 @@ public ConnectionInfo parse() { } } - // 如果 host 或 port 没有从路径中获取到,则尝试从参数中获取 if (host.isEmpty()) { host = fetchFromUrlParams(URL_PARAMS_HOST_KEY); } @@ -94,9 +93,6 @@ public ConnectionInfo parse() { ); } - /** - * 从 URL 参数中提取指定 key 的值 - */ private String fetchFromUrlParams(String key) { int paramIndex = url.indexOf("?"); if (paramIndex == -1) { From 74718b0fced5d411cb6fae03d783accd9a77c2ee Mon Sep 17 00:00:00 2001 From: saberwang Date: Mon, 9 Jun 2025 17:39:39 +0800 Subject: [PATCH 4/8] update DMDB_JDBC_DRIVER Component id --- .../apm/network/trace/component/ComponentsDefine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java index bfebcebbaf..fa62c91239 100755 --- a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java +++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java @@ -263,6 +263,6 @@ public class ComponentsDefine { public static final OfficialComponent THREAD_PER_TASK_EXECUTOR = new OfficialComponent(161, "ThreadPerTask-executor"); - public static final OfficialComponent DMDB_JDBC_DRIVER = new OfficialComponent(162, "Dmdb-jdbc-driver"); + public static final OfficialComponent DMDB_JDBC_DRIVER = new OfficialComponent(163, "Dmdb-jdbc-driver"); } From 359f3737af429877a3025a26b8d1519ca833504d Mon Sep 17 00:00:00 2001 From: saberwang Date: Mon, 9 Jun 2025 17:42:56 +0800 Subject: [PATCH 5/8] Remove DM logo --- docs/en/setup/service-agent/java-agent/Supported-list.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md index ec607f59ce..c39c84a524 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -185,7 +185,7 @@ The meter plugin provides the advanced metrics collections, which are not a part * [DB2](https://www.ibm.com/products/db2/database) * Sybase * [OceanBase](https://www.oceanbase.com/) - * [DaMeng](https://www.dameng.com/) + * DM * Supported Connection Pool Frameworks * [Apache Commons DBCP](https://github.com/apache/commons-dbcp) 2.x * [Alibaba Druid](https://github.com/alibaba/druid) 1.x From 5411c3a9c6684cb1ae4c740e228ff64e563171d4 Mon Sep 17 00:00:00 2001 From: saberwang Date: Tue, 10 Jun 2025 09:00:10 +0800 Subject: [PATCH 6/8] Revert "Remove DM logo" This reverts commit 359f3737af429877a3025a26b8d1519ca833504d. --- docs/en/setup/service-agent/java-agent/Supported-list.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md index c39c84a524..ec607f59ce 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -185,7 +185,7 @@ The meter plugin provides the advanced metrics collections, which are not a part * [DB2](https://www.ibm.com/products/db2/database) * Sybase * [OceanBase](https://www.oceanbase.com/) - * DM + * [DaMeng](https://www.dameng.com/) * Supported Connection Pool Frameworks * [Apache Commons DBCP](https://github.com/apache/commons-dbcp) 2.x * [Alibaba Druid](https://github.com/alibaba/druid) 1.x From e149915a9ad34d54713611a55c8ac0d3e78021ad Mon Sep 17 00:00:00 2001 From: saberwang Date: Tue, 10 Jun 2025 09:11:42 +0800 Subject: [PATCH 7/8] Update description --- docs/en/setup/service-agent/java-agent/Supported-list.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md index ec607f59ce..caf406d960 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -185,7 +185,7 @@ The meter plugin provides the advanced metrics collections, which are not a part * [DB2](https://www.ibm.com/products/db2/database) * Sybase * [OceanBase](https://www.oceanbase.com/) - * [DaMeng](https://www.dameng.com/) + * [DaMeng(DM)](https://www.dameng.com/) * Supported Connection Pool Frameworks * [Apache Commons DBCP](https://github.com/apache/commons-dbcp) 2.x * [Alibaba Druid](https://github.com/alibaba/druid) 1.x From a2cc3140eb232399e990fd0a274ed05aaffd000d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=99=9F=20Wu=20Sheng?= Date: Tue, 10 Jun 2025 09:51:57 +0800 Subject: [PATCH 8/8] CHANGES.md --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index b4a963dde9..eea1320db7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,7 +12,7 @@ Release Notes. initialization. Delay so11y metrics#build when the services are not ready to avoid MeterService status is not initialized. * Fix retransform failure when enhancing both parent and child classes. -* Add support for `dameng(DM)` jdbc url format in `URLParser`. +* Add support for `dameng(DM)` JDBC url format in `URLParser`. All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/236?closed=1)