Skip to content

Commit 1e96363

Browse files
committed
Support db.system.name in vertx sql instrumentation
1 parent c639fe5 commit 1e96363

14 files changed

Lines changed: 227 additions & 14 deletions

File tree

instrumentation/hibernate/hibernate-reactive-1.0/hibernate-reactive-2.0-testing/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/reactive/v2_0/AbstractHibernateReactiveTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION;
1717
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SQL_TABLE;
1818
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_STATEMENT;
19+
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM;
1920
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_USER;
21+
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DbSystemNameIncubatingValues.POSTGRESQL;
2022
import static java.util.concurrent.TimeUnit.SECONDS;
2123

2224
import io.opentelemetry.api.trace.Span;
@@ -299,6 +301,9 @@ private void assertTrace() {
299301
.hasKind(SpanKind.CLIENT)
300302
.hasParent(trace.getSpan(0))
301303
.hasAttributesSatisfyingExactly(
304+
equalTo(
305+
maybeStable(DB_SYSTEM),
306+
emitStableDatabaseSemconv() ? POSTGRESQL : null),
302307
equalTo(maybeStable(DB_NAME), DB),
303308
equalTo(DB_USER, emitStableDatabaseSemconv() ? null : USER_DB),
304309
equalTo(

instrumentation/hibernate/hibernate-reactive-1.0/javaagent/src/hibernateReactive1Test/java/io/opentelemetry/javaagent/instrumentation/hibernate/reactive/v1_0/HibernateReactiveTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION;
1717
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SQL_TABLE;
1818
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_STATEMENT;
19+
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM;
1920
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_USER;
21+
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DbSystemNameIncubatingValues.POSTGRESQL;
2022
import static java.util.concurrent.TimeUnit.SECONDS;
2123

2224
import io.opentelemetry.api.trace.Span;
@@ -310,6 +312,9 @@ private static void assertTrace() {
310312
.hasKind(SpanKind.CLIENT)
311313
.hasParent(trace.getSpan(0))
312314
.hasAttributesSatisfyingExactly(
315+
equalTo(
316+
maybeStable(DB_SYSTEM),
317+
emitStableDatabaseSemconv() ? POSTGRESQL : null),
313318
equalTo(maybeStable(DB_NAME), DB),
314319
equalTo(DB_USER, emitStableDatabaseSemconv() ? null : USER_DB),
315320
equalTo(

instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/PoolInstrumentation.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import static io.opentelemetry.javaagent.instrumentation.vertx.sql.VertxSqlClientUtil.setSqlConnectOptions;
1313
import static io.opentelemetry.javaagent.instrumentation.vertx.sql.VertxSqlClientUtil.wrapContext;
1414
import static io.opentelemetry.javaagent.instrumentation.vertx.v4_0.sql.VertxSqlClientSingletons.attachConnectOptions;
15+
import static net.bytebuddy.matcher.ElementMatchers.hasSuperType;
1516
import static net.bytebuddy.matcher.ElementMatchers.isStatic;
1617
import static net.bytebuddy.matcher.ElementMatchers.named;
1718
import static net.bytebuddy.matcher.ElementMatchers.returns;
@@ -45,12 +46,16 @@ public ElementMatcher<TypeDescription> typeMatcher() {
4546

4647
@Override
4748
public void transform(TypeTransformer transformer) {
49+
// In vertx 4.x, database-specific sub-interfaces like PgPool and MySQLPool declare their own
50+
// static pool() methods that take subtypes of SqlConnectOptions (e.g. PgConnectOptions) and
51+
// return subtypes of Pool. These are independent static methods, not overrides, and have their
52+
// own separate code paths. hasSuperType is needed to match these variant signatures.
4853
transformer.applyAdviceToMethod(
4954
named("pool")
5055
.and(isStatic())
5156
.and(takesArguments(3))
52-
.and(takesArgument(1, named("io.vertx.sqlclient.SqlConnectOptions")))
53-
.and(returns(named("io.vertx.sqlclient.Pool"))),
57+
.and(takesArgument(1, hasSuperType(named("io.vertx.sqlclient.SqlConnectOptions"))))
58+
.and(returns(hasSuperType(named("io.vertx.sqlclient.Pool")))),
5459
PoolInstrumentation.class.getName() + "$PoolAdvice");
5560

5661
transformer.applyAdviceToMethod(

instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/QueryExecutorInstrumentation.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import io.opentelemetry.javaagent.instrumentation.vertx.sql.VertxSqlClientRequest;
2020
import io.opentelemetry.javaagent.instrumentation.vertx.sql.VertxSqlClientUtil;
2121
import io.vertx.core.impl.future.PromiseInternal;
22+
import io.vertx.sqlclient.SqlConnectOptions;
2223
import io.vertx.sqlclient.impl.PreparedStatement;
2324
import io.vertx.sqlclient.impl.QueryExecutorUtil;
2425
import javax.annotation.Nullable;
@@ -102,9 +103,10 @@ public static AdviceScope start(Object queryExecutor, Object[] arguments) {
102103
return new AdviceScope(callDepth);
103104
}
104105

106+
SqlConnectOptions connectOptions = QueryExecutorUtil.getConnectOptions(queryExecutor);
107+
String dbSystem = VertxSqlClientUtil.getDbSystemFromClassName(connectOptions);
105108
VertxSqlClientRequest otelRequest =
106-
new VertxSqlClientRequest(
107-
sql, QueryExecutorUtil.getConnectOptions(queryExecutor), preparedStatement);
109+
new VertxSqlClientRequest(sql, connectOptions, preparedStatement, dbSystem);
108110
Context parentContext = Context.current();
109111
if (!instrumenter().shouldStart(parentContext, otelRequest)) {
110112
return new AdviceScope(callDepth, null, null, null);

instrumentation/vertx/vertx-sql-client/vertx-sql-client-4.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/sql/VertxSqlClientTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_OPERATION;
2222
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SQL_TABLE;
2323
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_STATEMENT;
24+
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_SYSTEM;
2425
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_USER;
26+
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DbSystemNameIncubatingValues.POSTGRESQL;
2527
import static java.util.Arrays.asList;
2628
import static java.util.concurrent.TimeUnit.SECONDS;
2729

@@ -143,6 +145,9 @@ void testSimpleSelect() throws Exception {
143145
.hasKind(SpanKind.CLIENT)
144146
.hasParent(trace.getSpan(0))
145147
.hasAttributesSatisfyingExactly(
148+
equalTo(
149+
maybeStable(DB_SYSTEM),
150+
emitStableDatabaseSemconv() ? POSTGRESQL : null),
146151
equalTo(maybeStable(DB_NAME), DB),
147152
equalTo(DB_USER, emitStableDatabaseSemconv() ? null : USER_DB),
148153
equalTo(maybeStable(DB_STATEMENT), "select * from test"),
@@ -207,6 +212,9 @@ void testInvalidQuery() throws Exception {
207212
EXCEPTION_STACKTRACE,
208213
val -> val.isInstanceOf(String.class))))
209214
.hasAttributesSatisfyingExactly(
215+
equalTo(
216+
maybeStable(DB_SYSTEM),
217+
emitStableDatabaseSemconv() ? POSTGRESQL : null),
210218
equalTo(maybeStable(DB_NAME), DB),
211219
equalTo(DB_USER, emitStableDatabaseSemconv() ? null : USER_DB),
212220
equalTo(maybeStable(DB_STATEMENT), "invalid"),
@@ -249,6 +257,9 @@ private static void assertPreparedSelect() {
249257
.hasKind(SpanKind.CLIENT)
250258
.hasParent(trace.getSpan(0))
251259
.hasAttributesSatisfyingExactly(
260+
equalTo(
261+
maybeStable(DB_SYSTEM),
262+
emitStableDatabaseSemconv() ? POSTGRESQL : null),
252263
equalTo(maybeStable(DB_NAME), DB),
253264
equalTo(DB_USER, emitStableDatabaseSemconv() ? null : USER_DB),
254265
equalTo(maybeStable(DB_STATEMENT), "select * from test where id = $1"),
@@ -287,6 +298,9 @@ void testBatch() throws Exception {
287298
.hasKind(SpanKind.CLIENT)
288299
.hasParent(trace.getSpan(0))
289300
.hasAttributesSatisfyingExactly(
301+
equalTo(
302+
maybeStable(DB_SYSTEM),
303+
emitStableDatabaseSemconv() ? POSTGRESQL : null),
290304
equalTo(maybeStable(DB_NAME), DB),
291305
equalTo(DB_USER, emitStableDatabaseSemconv() ? null : USER_DB),
292306
equalTo(
@@ -384,6 +398,9 @@ void testManyQueries() throws Exception {
384398
.hasKind(SpanKind.CLIENT)
385399
.hasParent(trace.getSpan(0))
386400
.hasAttributesSatisfyingExactly(
401+
equalTo(
402+
maybeStable(DB_SYSTEM),
403+
emitStableDatabaseSemconv() ? POSTGRESQL : null),
387404
equalTo(maybeStable(DB_NAME), DB),
388405
equalTo(DB_USER, emitStableDatabaseSemconv() ? null : USER_DB),
389406
equalTo(maybeStable(DB_STATEMENT), "select * from test"),
@@ -458,6 +475,9 @@ void testConcurrency() throws Exception {
458475
.hasKind(SpanKind.CLIENT)
459476
.hasParent(trace.getSpan(0))
460477
.hasAttributesSatisfyingExactly(
478+
equalTo(
479+
maybeStable(DB_SYSTEM),
480+
emitStableDatabaseSemconv() ? POSTGRESQL : null),
461481
equalTo(maybeStable(DB_NAME), DB),
462482
equalTo(DB_USER, emitStableDatabaseSemconv() ? null : USER_DB),
463483
equalTo(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.vertx.v5_0.sql;
7+
8+
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
9+
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface;
10+
import static io.opentelemetry.javaagent.instrumentation.vertx.sql.VertxSqlClientUtil.getDbSystemFromClassName;
11+
import static io.opentelemetry.javaagent.instrumentation.vertx.v5_0.sql.VertxSqlClientSingletons.storePoolDbSystem;
12+
import static net.bytebuddy.matcher.ElementMatchers.isStatic;
13+
import static net.bytebuddy.matcher.ElementMatchers.named;
14+
import static net.bytebuddy.matcher.ElementMatchers.not;
15+
import static net.bytebuddy.matcher.ElementMatchers.returns;
16+
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
17+
18+
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
19+
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
20+
import io.vertx.sqlclient.Pool;
21+
import net.bytebuddy.asm.Advice;
22+
import net.bytebuddy.description.type.TypeDescription;
23+
import net.bytebuddy.matcher.ElementMatcher;
24+
25+
public class DriverInstrumentation implements TypeInstrumentation {
26+
27+
@Override
28+
public ElementMatcher<ClassLoader> classLoaderOptimization() {
29+
return hasClassesNamed("io.vertx.sqlclient.spi.Driver");
30+
}
31+
32+
@Override
33+
public ElementMatcher<TypeDescription> typeMatcher() {
34+
return implementsInterface(named("io.vertx.sqlclient.spi.Driver"));
35+
}
36+
37+
@Override
38+
public void transform(TypeTransformer transformer) {
39+
transformer.applyAdviceToMethod(
40+
named("newPool")
41+
.and(not(isStatic()))
42+
.and(takesArguments(6))
43+
.and(returns(named("io.vertx.sqlclient.Pool"))),
44+
DriverInstrumentation.class.getName() + "$NewPoolAdvice");
45+
}
46+
47+
@SuppressWarnings("unused")
48+
public static class NewPoolAdvice {
49+
50+
@Advice.OnMethodExit(suppress = Throwable.class)
51+
public static void onExit(@Advice.This Object driver, @Advice.Return Pool pool) {
52+
if (pool != null) {
53+
storePoolDbSystem(pool, getDbSystemFromClassName(driver));
54+
}
55+
}
56+
}
57+
}

instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/PoolInstrumentation.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import static io.opentelemetry.javaagent.instrumentation.vertx.sql.VertxSqlClientUtil.setSqlConnectOptions;
1313
import static io.opentelemetry.javaagent.instrumentation.vertx.sql.VertxSqlClientUtil.wrapContext;
1414
import static io.opentelemetry.javaagent.instrumentation.vertx.v5_0.sql.VertxSqlClientSingletons.attachConnectOptions;
15+
import static io.opentelemetry.javaagent.instrumentation.vertx.v5_0.sql.VertxSqlClientSingletons.resolveAndStoreDbSystem;
1516
import static net.bytebuddy.matcher.ElementMatchers.isStatic;
1617
import static net.bytebuddy.matcher.ElementMatchers.named;
1718
import static net.bytebuddy.matcher.ElementMatchers.returns;
@@ -83,6 +84,7 @@ public static void onExit(
8384
}
8485

8586
setPoolConnectOptions(pool, sqlConnectOptions);
87+
resolveAndStoreDbSystem(pool, sqlConnectOptions);
8688
setSqlConnectOptions(null);
8789
}
8890
}

instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/QueryExecutorInstrumentation.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import io.opentelemetry.javaagent.instrumentation.vertx.sql.VertxSqlClientRequest;
2020
import io.opentelemetry.javaagent.instrumentation.vertx.sql.VertxSqlClientUtil;
2121
import io.vertx.core.internal.PromiseInternal;
22+
import io.vertx.sqlclient.SqlConnectOptions;
2223
import io.vertx.sqlclient.impl.QueryExecutorUtil;
2324
import io.vertx.sqlclient.internal.PreparedStatement;
2425
import javax.annotation.Nullable;
@@ -101,9 +102,10 @@ public static AdviceScope start(Object queryExecutor, Object[] arguments) {
101102
return new AdviceScope(callDepth);
102103
}
103104

105+
SqlConnectOptions connectOptions = QueryExecutorUtil.getConnectOptions(queryExecutor);
106+
String dbSystem = VertxSqlClientSingletons.getConnectOptionsDbSystem(connectOptions);
104107
VertxSqlClientRequest otelRequest =
105-
new VertxSqlClientRequest(
106-
sql, QueryExecutorUtil.getConnectOptions(queryExecutor), preparedStatement);
108+
new VertxSqlClientRequest(sql, connectOptions, preparedStatement, dbSystem);
107109
Context parentContext = Context.current();
108110
if (!instrumenter().shouldStart(parentContext, otelRequest)) {
109111
return new AdviceScope(callDepth);

instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/VertxSqlClientInstrumentationModule.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public List<String> injectedClassNames() {
4343
@Override
4444
public List<TypeInstrumentation> typeInstrumentations() {
4545
return asList(
46+
new DriverInstrumentation(),
4647
new PoolInstrumentation(),
4748
new SqlClientBaseInstrumentation(),
4849
new QueryExecutorInstrumentation(),

instrumentation/vertx/vertx-sql-client/vertx-sql-client-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v5_0/sql/VertxSqlClientSingletons.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55

66
package io.opentelemetry.javaagent.instrumentation.vertx.v5_0.sql;
77

8+
import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DbSystemNameIncubatingValues.OTHER_SQL;
9+
810
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
911
import io.opentelemetry.instrumentation.api.util.VirtualField;
1012
import io.opentelemetry.javaagent.instrumentation.vertx.sql.VertxSqlClientRequest;
1113
import io.opentelemetry.javaagent.instrumentation.vertx.sql.VertxSqlInstrumenterFactory;
1214
import io.vertx.core.Future;
15+
import io.vertx.sqlclient.Pool;
1316
import io.vertx.sqlclient.SqlConnectOptions;
1417
import io.vertx.sqlclient.SqlConnection;
1518
import io.vertx.sqlclient.internal.SqlClientBase;
@@ -23,9 +26,36 @@ public static Instrumenter<VertxSqlClientRequest, Void> instrumenter() {
2326
return INSTRUMENTER;
2427
}
2528

29+
private static final VirtualField<Pool, String> poolDbSystem =
30+
VirtualField.find(Pool.class, String.class);
31+
32+
private static final VirtualField<SqlConnectOptions, String> connectOptionsDbSystem =
33+
VirtualField.find(SqlConnectOptions.class, String.class);
34+
2635
private static final VirtualField<SqlClientBase, SqlConnectOptions> connectOptionsField =
2736
VirtualField.find(SqlClientBase.class, SqlConnectOptions.class);
2837

38+
public static void storePoolDbSystem(Pool pool, String dbSystem) {
39+
poolDbSystem.set(pool, dbSystem);
40+
}
41+
42+
public static String getConnectOptionsDbSystem(SqlConnectOptions sqlConnectOptions) {
43+
if (sqlConnectOptions != null) {
44+
String dbSystem = connectOptionsDbSystem.get(sqlConnectOptions);
45+
if (dbSystem != null) {
46+
return dbSystem;
47+
}
48+
}
49+
return OTHER_SQL;
50+
}
51+
52+
public static void resolveAndStoreDbSystem(Pool pool, SqlConnectOptions sqlConnectOptions) {
53+
String dbSystem = poolDbSystem.get(pool);
54+
if (sqlConnectOptions != null && dbSystem != null) {
55+
connectOptionsDbSystem.set(sqlConnectOptions, dbSystem);
56+
}
57+
}
58+
2959
public static SqlConnectOptions getSqlConnectOptions(SqlClientBase sqlClientBase) {
3060
return connectOptionsField.get(sqlClientBase);
3161
}

0 commit comments

Comments
 (0)