diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParser.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParser.java index 87d075e84bd2..3db94c6d6d08 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParser.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParser.java @@ -911,6 +911,84 @@ DbInfo.Builder doParse(String jdbcUrl, DbInfo.Builder builder) { } return GENERIC_URL_LIKE.doParse(clickhouseUrl, builder); } + }, + /** + * Sample urls: + * + * + */ + OCEANBASE("oceanbase") { + @Override + DbInfo.Builder doParse(String jdbcUrl, DbInfo.Builder builder) { + int protoLoc = jdbcUrl.indexOf("://"); + int typeEndLoc = jdbcUrl.indexOf(':'); + if (protoLoc > typeEndLoc) { + String subtype = jdbcUrl.substring(typeEndLoc + 1, protoLoc); + builder.subtype(subtype); + if (subtype.equals(DbSystemValues.ORACLE)) { + builder.system(DbSystemValues.ORACLE); + } + return MODIFIED_URL_LIKE.doParse(jdbcUrl, builder); + } else { + return GENERIC_URL_LIKE.doParse(jdbcUrl, builder); + } + } + }, + /** + * Driver + * configuration doc + * + *

Sample urls: + * + *

+ */ + LINDORM("lindorm") { + private static final String DEFAULT_HOST = "localhost"; + private static final int DEFAULT_PORT = 30060; + + @Override + DbInfo.Builder doParse(String jdbcUrl, DbInfo.Builder builder) { + String lindormUrl = jdbcUrl.substring("lindorm:".length()); + DbInfo dbInfo = builder.build(); + if (dbInfo.getHost() == null) { + builder.host(DEFAULT_HOST); + } + if (dbInfo.getPort() == null) { + builder.port(DEFAULT_PORT); + } + + int urlIndex = lindormUrl.indexOf(":url="); + if (urlIndex < 0) { + return builder; + } + builder.subtype(lindormUrl.substring(0, urlIndex)); + String realUrl = lindormUrl.substring(urlIndex + 5); + return GENERIC_URL_LIKE.doParse(realUrl, builder); + } + }, + /** Sample url: jdbc:polardb://server_name:1901/dbname */ + POLARDB("polardb") { + private static final int DEFAULT_PORT = 1521; + private static final String DEFAULT_HOST = "localhost"; + + @Override + DbInfo.Builder doParse(String jdbcUrl, DbInfo.Builder builder) { + DbInfo dbInfo = builder.build(); + if (dbInfo.getHost() == null) { + builder.host(DEFAULT_HOST); + } + if (dbInfo.getPort() == null) { + builder.port(DEFAULT_PORT); + } + return GENERIC_URL_LIKE.doParse(jdbcUrl, builder); + } }; private static final Logger logger = Logger.getLogger(JdbcConnectionUrlParser.class.getName()); @@ -943,8 +1021,13 @@ public static DbInfo parse(String connectionUrl, Properties props) { connectionUrl = connectionUrl.toLowerCase(Locale.ROOT); String jdbcUrl; - if (connectionUrl.startsWith("jdbc:")) { + if (connectionUrl.startsWith("jdbc:tracing:")) { + // see https://github.com/opentracing-contrib/java-jdbc + jdbcUrl = connectionUrl.substring("jdbc:tracing:".length()); + } else if (connectionUrl.startsWith("jdbc:")) { jdbcUrl = connectionUrl.substring("jdbc:".length()); + } else if (connectionUrl.startsWith("jdbc-secretsmanager:tracing:")) { + jdbcUrl = connectionUrl.substring("jdbc-secretsmanager:tracing:".length()); } else if (connectionUrl.startsWith("jdbc-secretsmanager:")) { jdbcUrl = connectionUrl.substring("jdbc-secretsmanager:".length()); } else { @@ -1100,6 +1183,12 @@ private static String toDbSystem(String type) { return DbSystemValues.HANADB; case "clickhouse": // ClickHouse return DbSystemValues.CLICKHOUSE; + case "oceanbase": // Oceanbase + return DbSystemValues.OCEANBASE; + case "polardb": // PolarDB + return DbSystemValues.POLARDB; + case "lindorm": // Lindorm + return DbSystemValues.LINDORM; default: return DbSystemValues.OTHER_SQL; // Unknown DBMS } @@ -1120,6 +1209,9 @@ private static final class DbSystemValues { static final String MARIADB = "mariadb"; static final String H2 = "h2"; static final String CLICKHOUSE = "clickhouse"; + static final String OCEANBASE = "oceanbase"; + static final String POLARDB = "polardb"; + static final String LINDORM = "lindorm"; private DbSystemValues() {} } diff --git a/instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParserTest.java b/instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParserTest.java index 165a91d2d3c0..a0a0fe30573e 100644 --- a/instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParserTest.java +++ b/instrumentation/jdbc/library/src/test/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcConnectionUrlParserTest.java @@ -1300,6 +1300,127 @@ void testSecretsManagerParsing(ParseTestArgument argument) { testVerifySystemSubtypeParsingOfUrl(argument); } + private static Stream openTracingArguments() { + return args( + // https://github.com/opentracing-contrib/java-jdbc + arg("jdbc:tracing:mysql://example.com:50000") + .setShortUrl("mysql://example.com:50000") + .setSystem("mysql") + .setHost("example.com") + .setPort(50000) + .build(), + arg("jdbc:tracing:postgresql://example.com:50000/dbname") + .setShortUrl("postgresql://example.com:50000") + .setSystem("postgresql") + .setHost("example.com") + .setPort(50000) + .setDb("dbname") + .build(), + arg("jdbc:tracing:oracle:thin:@example.com:50000/ORCL") + .setShortUrl("oracle:thin://example.com:50000") + .setSystem("oracle") + .setSubtype("thin") + .setHost("example.com") + .setPort(50000) + .setName("orcl") + .build(), + arg("jdbc:tracing:sqlserver://example.com:50000") + .setShortUrl("sqlserver://example.com:50000") + .setSystem("mssql") + .setHost("example.com") + .setPort(50000) + .build()); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("openTracingArguments") + void testOpenTracingParsing(ParseTestArgument argument) { + testVerifySystemSubtypeParsingOfUrl(argument); + } + + private static Stream oceanbaseArguments() { + return args( + // https://en.oceanbase.com/ + arg("jdbc:oceanbase://host:3306/test") + .setShortUrl("oceanbase://host:3306") + .setSystem("oceanbase") + .setHost("host") + .setPort(3306) + .setDb("test") + .build(), + arg("jdbc:oceanbase:oracle://host:1521") + .setShortUrl("oceanbase:oracle://host:1521") + .setSystem("oracle") + .setSubtype("oracle") + .setHost("host") + .setPort(1521) + .build()); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("oceanbaseArguments") + void testOceasbaseParsing(ParseTestArgument argument) { + testVerifySystemSubtypeParsingOfUrl(argument); + } + + private static Stream lindormArguments() { + return args( + // https://www.alibabacloud.com/help/en/lindorm/user-guide/view-endpoints + arg("jdbc:lindorm:table:url=http://host:30060/test") + .setShortUrl("lindorm:table://host:30060") + .setSystem("lindorm") + .setSubtype("table") + .setHost("host") + .setDb("test") + .setPort(30060) + .build(), + arg("jdbc:lindorm:tsdb:url=http://host:8242/test") + .setShortUrl("lindorm:tsdb://host:8242") + .setSystem("lindorm") + .setSubtype("tsdb") + .setHost("host") + .setDb("test") + .setPort(8242) + .setDb("test") + .build(), + arg("jdbc:lindorm:search:url=http://host:30070/test") + .setShortUrl("lindorm:search://host:30070") + .setSystem("lindorm") + .setSubtype("search") + .setHost("host") + .setDb("test") + .setPort(30070) + .build()); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("lindormArguments") + void testLindormManagerParsing(ParseTestArgument argument) { + testVerifySystemSubtypeParsingOfUrl(argument); + } + + private static Stream polardbArguments() { + return args( + arg("jdbc:polardb://example.com:1901") + .setShortUrl("polardb://example.com:1901") + .setSystem("polardb") + .setHost("example.com") + .setPort(1901) + .build(), + arg("jdbc:polardb://example.com") + .setShortUrl("polardb://example.com:1521") + .setSystem("polardb") + .setHost("example.com") + .setPort(1521) + .build()); + } + + @ParameterizedTest(name = "{index}: {0}") + @MethodSource("polardbArguments") + void testPolardbParsing(ParseTestArgument argument) { + testVerifySystemSubtypeParsingOfUrl(argument); + } + private static void testVerifySystemSubtypeParsingOfUrl(ParseTestArgument argument) { DbInfo info = parse(argument.url, argument.properties); DbInfo expected = argument.dbInfo;