diff --git a/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/JdbcSingletons.java b/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/JdbcSingletons.java index 7da1e4f50cbc..f86ead0fa9a5 100644 --- a/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/JdbcSingletons.java +++ b/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/JdbcSingletons.java @@ -5,6 +5,8 @@ package io.opentelemetry.javaagent.instrumentation.jdbc; +import static io.opentelemetry.instrumentation.jdbc.internal.DataSourceInstrumenterFactory.createDataSourceInstrumenter; + import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; @@ -17,17 +19,20 @@ import io.opentelemetry.instrumentation.jdbc.internal.JdbcNetAttributesGetter; import io.opentelemetry.javaagent.bootstrap.internal.CommonConfig; import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig; +import javax.sql.DataSource; public final class JdbcSingletons { private static final String INSTRUMENTATION_NAME = "io.opentelemetry.jdbc"; - private static final Instrumenter INSTRUMENTER; + private static final Instrumenter STATEMENT_INSTRUMENTER; + public static final Instrumenter DATASOURCE_INSTRUMENTER = + createDataSourceInstrumenter(GlobalOpenTelemetry.get()); static { JdbcAttributesGetter dbAttributesGetter = new JdbcAttributesGetter(); JdbcNetAttributesGetter netAttributesGetter = new JdbcNetAttributesGetter(); - INSTRUMENTER = + STATEMENT_INSTRUMENTER = Instrumenter.builder( GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, @@ -47,8 +52,12 @@ public final class JdbcSingletons { .buildInstrumenter(SpanKindExtractor.alwaysClient()); } - public static Instrumenter instrumenter() { - return INSTRUMENTER; + public static Instrumenter statementInstrumenter() { + return STATEMENT_INSTRUMENTER; + } + + public static Instrumenter dataSourceInstrumenter() { + return DATASOURCE_INSTRUMENTER; } private JdbcSingletons() {} diff --git a/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/PreparedStatementInstrumentation.java b/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/PreparedStatementInstrumentation.java index 9acd6dac23a9..799e85df6431 100644 --- a/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/PreparedStatementInstrumentation.java +++ b/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/PreparedStatementInstrumentation.java @@ -8,7 +8,7 @@ import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext; import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface; -import static io.opentelemetry.javaagent.instrumentation.jdbc.JdbcSingletons.instrumenter; +import static io.opentelemetry.javaagent.instrumentation.jdbc.JdbcSingletons.statementInstrumenter; import static net.bytebuddy.matcher.ElementMatchers.isPublic; import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith; import static net.bytebuddy.matcher.ElementMatchers.named; @@ -70,11 +70,11 @@ public static void onEnter( Context parentContext = currentContext(); request = DbRequest.create(statement); - if (request == null || !instrumenter().shouldStart(parentContext, request)) { + if (request == null || !statementInstrumenter().shouldStart(parentContext, request)) { return; } - context = instrumenter().start(parentContext, request); + context = statementInstrumenter().start(parentContext, request); scope = context.makeCurrent(); } @@ -91,7 +91,7 @@ public static void stopSpan( if (scope != null) { scope.close(); - instrumenter().end(context, request, null, throwable); + statementInstrumenter().end(context, request, null, throwable); } } } diff --git a/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/StatementInstrumentation.java b/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/StatementInstrumentation.java index 147a86bba708..4eeb0ef82bf9 100644 --- a/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/StatementInstrumentation.java +++ b/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/StatementInstrumentation.java @@ -8,7 +8,7 @@ import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext; import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface; -import static io.opentelemetry.javaagent.instrumentation.jdbc.JdbcSingletons.instrumenter; +import static io.opentelemetry.javaagent.instrumentation.jdbc.JdbcSingletons.statementInstrumenter; import static net.bytebuddy.matcher.ElementMatchers.isPublic; import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith; import static net.bytebuddy.matcher.ElementMatchers.named; @@ -70,11 +70,11 @@ public static void onEnter( Context parentContext = currentContext(); request = DbRequest.create(statement, sql); - if (request == null || !instrumenter().shouldStart(parentContext, request)) { + if (request == null || !statementInstrumenter().shouldStart(parentContext, request)) { return; } - context = instrumenter().start(parentContext, request); + context = statementInstrumenter().start(parentContext, request); scope = context.makeCurrent(); } @@ -91,7 +91,7 @@ public static void stopSpan( if (scope != null) { scope.close(); - instrumenter().end(context, request, null, throwable); + statementInstrumenter().end(context, request, null, throwable); } } } diff --git a/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/datasource/DataSourceInstrumentation.java b/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/datasource/DataSourceInstrumentation.java index 9399bfdd0a31..809e84c6a00a 100644 --- a/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/datasource/DataSourceInstrumentation.java +++ b/instrumentation/jdbc/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jdbc/datasource/DataSourceInstrumentation.java @@ -5,8 +5,8 @@ package io.opentelemetry.javaagent.instrumentation.jdbc.datasource; -import static io.opentelemetry.instrumentation.jdbc.internal.DataSourceSingletons.instrumenter; import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface; +import static io.opentelemetry.javaagent.instrumentation.jdbc.JdbcSingletons.dataSourceInstrumenter; import static net.bytebuddy.matcher.ElementMatchers.named; import io.opentelemetry.context.Context; @@ -20,6 +20,7 @@ import net.bytebuddy.matcher.ElementMatcher; public class DataSourceInstrumentation implements TypeInstrumentation { + @Override public ElementMatcher typeMatcher() { return implementsInterface(named("javax.sql.DataSource")); @@ -46,7 +47,7 @@ public static void start( return; } - context = instrumenter().start(parentContext, ds); + context = dataSourceInstrumenter().start(parentContext, ds); scope = context.makeCurrent(); } @@ -60,7 +61,7 @@ public static void stopSpan( return; } scope.close(); - instrumenter().end(context, ds, null, throwable); + dataSourceInstrumenter().end(context, ds, null, throwable); } } } diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java index b874a5ceced8..5b6646ced2c6 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java @@ -20,7 +20,8 @@ package io.opentelemetry.instrumentation.jdbc; -import static io.opentelemetry.instrumentation.jdbc.internal.JdbcSingletons.INSTRUMENTATION_NAME; +import static io.opentelemetry.instrumentation.jdbc.internal.JdbcInstrumenterFactory.INSTRUMENTATION_NAME; +import static io.opentelemetry.instrumentation.jdbc.internal.JdbcSingletons.statementInstrumenter; import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties; import io.opentelemetry.instrumentation.jdbc.internal.JdbcConnectionUrlParser; @@ -211,7 +212,7 @@ public Connection connect(String url, Properties info) throws SQLException { DbInfo dbInfo = JdbcConnectionUrlParser.parse(realUrl, info); - return new OpenTelemetryConnection(connection, dbInfo); + return new OpenTelemetryConnection(connection, dbInfo, statementInstrumenter()); } @Override diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/datasource/OpenTelemetryDataSource.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/datasource/OpenTelemetryDataSource.java index be2148c0f1d2..8fc427ce2a80 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/datasource/OpenTelemetryDataSource.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/datasource/OpenTelemetryDataSource.java @@ -20,12 +20,17 @@ package io.opentelemetry.instrumentation.jdbc.datasource; -import static io.opentelemetry.instrumentation.jdbc.internal.DataSourceSingletons.instrumenter; +import static io.opentelemetry.instrumentation.jdbc.internal.DataSourceInstrumenterFactory.createDataSourceInstrumenter; +import static io.opentelemetry.instrumentation.jdbc.internal.JdbcInstrumenterFactory.createStatementInstrumenter; import static io.opentelemetry.instrumentation.jdbc.internal.JdbcUtils.computeDbInfo; +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.instrumentation.jdbc.internal.DbRequest; import io.opentelemetry.instrumentation.jdbc.internal.OpenTelemetryConnection; import io.opentelemetry.instrumentation.jdbc.internal.ThrowingSupplier; import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo; @@ -40,29 +45,44 @@ public class OpenTelemetryDataSource implements DataSource, AutoCloseable { private final DataSource delegate; + private final Instrumenter dataSourceInstrumenter; + private final Instrumenter statementInstrumenter; + + /** + * Create a OpenTelemetry DataSource wrapping another DataSource. + * + * @param delegate the DataSource to wrap + */ + @Deprecated + public OpenTelemetryDataSource(DataSource delegate) { + this(delegate, GlobalOpenTelemetry.get()); + } /** * Create a OpenTelemetry DataSource wrapping another DataSource. This constructor is primarily * used by dependency injection frameworks. * * @param delegate the DataSource to wrap + * @param openTelemetry the OpenTelemetry instance to setup for */ - public OpenTelemetryDataSource(DataSource delegate) { + public OpenTelemetryDataSource(DataSource delegate, OpenTelemetry openTelemetry) { this.delegate = delegate; + this.dataSourceInstrumenter = createDataSourceInstrumenter(openTelemetry); + this.statementInstrumenter = createStatementInstrumenter(openTelemetry); } @Override public Connection getConnection() throws SQLException { Connection connection = wrapCall(delegate::getConnection); DbInfo dbInfo = computeDbInfo(connection); - return new OpenTelemetryConnection(connection, dbInfo); + return new OpenTelemetryConnection(connection, dbInfo, statementInstrumenter); } @Override public Connection getConnection(String username, String password) throws SQLException { Connection connection = wrapCall(() -> delegate.getConnection(username, password)); DbInfo dbInfo = computeDbInfo(connection); - return new OpenTelemetryConnection(connection, dbInfo); + return new OpenTelemetryConnection(connection, dbInfo, statementInstrumenter); } @Override @@ -116,15 +136,15 @@ private T wrapCall(ThrowingSupplier callable) return callable.call(); } - Context context = instrumenter().start(parentContext, delegate); + Context context = this.dataSourceInstrumenter.start(parentContext, delegate); T result; try (Scope ignored = context.makeCurrent()) { result = callable.call(); } catch (Throwable t) { - instrumenter().end(context, delegate, null, t); + this.dataSourceInstrumenter.end(context, delegate, null, t); throw t; } - instrumenter().end(context, delegate, null, null); + this.dataSourceInstrumenter.end(context, delegate, null, null); return result; } } diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/DataSourceInstrumenterFactory.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/DataSourceInstrumenterFactory.java new file mode 100644 index 000000000000..d259a0fd7845 --- /dev/null +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/DataSourceInstrumenterFactory.java @@ -0,0 +1,32 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.jdbc.internal; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.instrumentation.api.instrumenter.code.CodeAttributesExtractor; +import io.opentelemetry.instrumentation.api.instrumenter.code.CodeSpanNameExtractor; +import javax.sql.DataSource; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public final class DataSourceInstrumenterFactory { + private static final String INSTRUMENTATION_NAME = "io.opentelemetry.jdbc"; + private static final DataSourceCodeAttributesGetter codeAttributesGetter = + new DataSourceCodeAttributesGetter(); + + public static Instrumenter createDataSourceInstrumenter( + OpenTelemetry openTelemetry) { + return Instrumenter.builder( + openTelemetry, INSTRUMENTATION_NAME, CodeSpanNameExtractor.create(codeAttributesGetter)) + .addAttributesExtractor(CodeAttributesExtractor.create(codeAttributesGetter)) + .buildInstrumenter(); + } + + private DataSourceInstrumenterFactory() {} +} diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/DataSourceSingletons.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/DataSourceSingletons.java deleted file mode 100644 index b28987af038e..000000000000 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/DataSourceSingletons.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.jdbc.internal; - -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.instrumentation.api.instrumenter.code.CodeAttributesExtractor; -import io.opentelemetry.instrumentation.api.instrumenter.code.CodeSpanNameExtractor; -import javax.sql.DataSource; - -/** - * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. - */ -public final class DataSourceSingletons { - private static final String INSTRUMENTATION_NAME = "io.opentelemetry.jdbc"; - - private static final Instrumenter INSTRUMENTER; - - static { - DataSourceCodeAttributesGetter codeAttributesGetter = new DataSourceCodeAttributesGetter(); - - INSTRUMENTER = - Instrumenter.builder( - GlobalOpenTelemetry.get(), - INSTRUMENTATION_NAME, - CodeSpanNameExtractor.create(codeAttributesGetter)) - .addAttributesExtractor(CodeAttributesExtractor.create(codeAttributesGetter)) - .buildInstrumenter(); - } - - public static Instrumenter instrumenter() { - return INSTRUMENTER; - } - - private DataSourceSingletons() {} -} diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java new file mode 100644 index 000000000000..6399476743fd --- /dev/null +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java @@ -0,0 +1,47 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.jdbc.internal; + +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; +import io.opentelemetry.instrumentation.api.instrumenter.db.DbClientSpanNameExtractor; +import io.opentelemetry.instrumentation.api.instrumenter.db.SqlClientAttributesExtractor; +import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesExtractor; +import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public final class JdbcInstrumenterFactory { + public static final String INSTRUMENTATION_NAME = "io.opentelemetry.jdbc"; + private static final JdbcAttributesGetter dbAttributesGetter = new JdbcAttributesGetter(); + private static final JdbcNetAttributesGetter netAttributesGetter = new JdbcNetAttributesGetter(); + + public static Instrumenter createStatementInstrumenter() { + return createStatementInstrumenter(GlobalOpenTelemetry.get()); + } + + public static Instrumenter createStatementInstrumenter( + OpenTelemetry openTelemetry) { + return Instrumenter.builder( + openTelemetry, + INSTRUMENTATION_NAME, + DbClientSpanNameExtractor.create(dbAttributesGetter)) + .addAttributesExtractor( + SqlClientAttributesExtractor.builder(dbAttributesGetter) + .setStatementSanitizationEnabled( + ConfigPropertiesUtil.getBoolean( + "otel.instrumentation.common.db-statement-sanitizer.enabled", true)) + .build()) + .addAttributesExtractor(NetClientAttributesExtractor.create(netAttributesGetter)) + .buildInstrumenter(SpanKindExtractor.alwaysClient()); + } + + private JdbcInstrumenterFactory() {} +} diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcSingletons.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcSingletons.java index a14214ed35d7..0ab6892401f6 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcSingletons.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcSingletons.java @@ -5,44 +5,21 @@ package io.opentelemetry.instrumentation.jdbc.internal; +import static io.opentelemetry.instrumentation.jdbc.internal.JdbcInstrumenterFactory.createStatementInstrumenter; + import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; -import io.opentelemetry.instrumentation.api.instrumenter.db.DbClientSpanNameExtractor; -import io.opentelemetry.instrumentation.api.instrumenter.db.SqlClientAttributesExtractor; -import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesExtractor; -import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at * any time. */ public final class JdbcSingletons { - public static final String INSTRUMENTATION_NAME = "io.opentelemetry.jdbc"; - - private static final Instrumenter INSTRUMENTER; - - static { - JdbcAttributesGetter dbAttributesGetter = new JdbcAttributesGetter(); - JdbcNetAttributesGetter netAttributesGetter = new JdbcNetAttributesGetter(); - - INSTRUMENTER = - Instrumenter.builder( - GlobalOpenTelemetry.get(), - INSTRUMENTATION_NAME, - DbClientSpanNameExtractor.create(dbAttributesGetter)) - .addAttributesExtractor( - SqlClientAttributesExtractor.builder(dbAttributesGetter) - .setStatementSanitizationEnabled( - ConfigPropertiesUtil.getBoolean( - "otel.instrumentation.common.db-statement-sanitizer.enabled", true)) - .build()) - .addAttributesExtractor(NetClientAttributesExtractor.create(netAttributesGetter)) - .buildInstrumenter(SpanKindExtractor.alwaysClient()); - } + public static final Instrumenter STATEMENT_INSTRUMENTER = + createStatementInstrumenter(GlobalOpenTelemetry.get()); - public static Instrumenter instrumenter() { - return INSTRUMENTER; + public static Instrumenter statementInstrumenter() { + return STATEMENT_INSTRUMENTER; } private JdbcSingletons() {} diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/OpenTelemetryCallableStatement.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/OpenTelemetryCallableStatement.java index 5f2e7bb0475a..267786751225 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/OpenTelemetryCallableStatement.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/OpenTelemetryCallableStatement.java @@ -20,6 +20,7 @@ package io.opentelemetry.instrumentation.jdbc.internal; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo; import java.io.InputStream; import java.io.Reader; @@ -47,8 +48,9 @@ public class OpenTelemetryCallableStatement extends OpenTelemetryPreparedStatement implements CallableStatement { - public OpenTelemetryCallableStatement(S delegate, DbInfo dbInfo, String query) { - super(delegate, dbInfo, query); + public OpenTelemetryCallableStatement( + S delegate, DbInfo dbInfo, String query, Instrumenter instrumenter) { + super(delegate, dbInfo, query, instrumenter); } @Override diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/OpenTelemetryConnection.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/OpenTelemetryConnection.java index b4e60f40e319..8b394eb9dabd 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/OpenTelemetryConnection.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/OpenTelemetryConnection.java @@ -20,6 +20,7 @@ package io.opentelemetry.instrumentation.jdbc.internal; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo; import java.sql.Array; import java.sql.Blob; @@ -48,23 +49,26 @@ public class OpenTelemetryConnection implements Connection { private final Connection delegate; private final DbInfo dbInfo; + protected final Instrumenter statementInstrumenter; - public OpenTelemetryConnection(Connection delegate, DbInfo dbInfo) { + public OpenTelemetryConnection( + Connection delegate, DbInfo dbInfo, Instrumenter statementInstrumenter) { this.delegate = delegate; this.dbInfo = dbInfo; + this.statementInstrumenter = statementInstrumenter; } @Override public Statement createStatement() throws SQLException { Statement statement = delegate.createStatement(); - return new OpenTelemetryStatement<>(statement, dbInfo); + return new OpenTelemetryStatement<>(statement, dbInfo, statementInstrumenter); } @Override public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { Statement statement = delegate.createStatement(resultSetType, resultSetConcurrency); - return new OpenTelemetryStatement<>(statement, dbInfo); + return new OpenTelemetryStatement<>(statement, dbInfo, statementInstrumenter); } @Override @@ -72,13 +76,13 @@ public Statement createStatement( int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { Statement statement = delegate.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability); - return new OpenTelemetryStatement<>(statement, dbInfo); + return new OpenTelemetryStatement<>(statement, dbInfo, statementInstrumenter); } @Override public PreparedStatement prepareStatement(String sql) throws SQLException { PreparedStatement statement = delegate.prepareStatement(sql); - return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql); + return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql, statementInstrumenter); } @Override @@ -86,7 +90,7 @@ public PreparedStatement prepareStatement(String sql, int resultSetType, int res throws SQLException { PreparedStatement statement = delegate.prepareStatement(sql, resultSetType, resultSetConcurrency); - return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql); + return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql, statementInstrumenter); } @Override @@ -95,38 +99,38 @@ public PreparedStatement prepareStatement( throws SQLException { PreparedStatement statement = delegate.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); - return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql); + return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql, statementInstrumenter); } @Override public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { PreparedStatement statement = delegate.prepareStatement(sql, autoGeneratedKeys); - return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql); + return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql, statementInstrumenter); } @Override public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { PreparedStatement statement = delegate.prepareStatement(sql, columnIndexes); - return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql); + return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql, statementInstrumenter); } @Override public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { PreparedStatement statement = delegate.prepareStatement(sql, columnNames); - return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql); + return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql, statementInstrumenter); } @Override public CallableStatement prepareCall(String sql) throws SQLException { CallableStatement statement = delegate.prepareCall(sql); - return new OpenTelemetryCallableStatement<>(statement, dbInfo, sql); + return new OpenTelemetryCallableStatement<>(statement, dbInfo, sql, statementInstrumenter); } @Override public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { CallableStatement statement = delegate.prepareCall(sql, resultSetType, resultSetConcurrency); - return new OpenTelemetryCallableStatement<>(statement, dbInfo, sql); + return new OpenTelemetryCallableStatement<>(statement, dbInfo, sql, statementInstrumenter); } @Override @@ -135,7 +139,7 @@ public CallableStatement prepareCall( throws SQLException { CallableStatement statement = delegate.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability); - return new OpenTelemetryCallableStatement<>(statement, dbInfo, sql); + return new OpenTelemetryCallableStatement<>(statement, dbInfo, sql, statementInstrumenter); } @Override diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/OpenTelemetryPreparedStatement.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/OpenTelemetryPreparedStatement.java index b100a14ad3ee..74e9b306b62d 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/OpenTelemetryPreparedStatement.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/OpenTelemetryPreparedStatement.java @@ -20,6 +20,7 @@ package io.opentelemetry.instrumentation.jdbc.internal; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo; import java.io.InputStream; import java.io.Reader; @@ -49,8 +50,9 @@ public class OpenTelemetryPreparedStatement extends OpenTelemetryStatement implements PreparedStatement { - public OpenTelemetryPreparedStatement(S delegate, DbInfo dbInfo, String query) { - super(delegate, dbInfo, query); + public OpenTelemetryPreparedStatement( + S delegate, DbInfo dbInfo, String query, Instrumenter instrumenter) { + super(delegate, dbInfo, query, instrumenter); } @Override diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/OpenTelemetryStatement.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/OpenTelemetryStatement.java index a034067937dc..ddaccb057eac 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/OpenTelemetryStatement.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/OpenTelemetryStatement.java @@ -20,10 +20,9 @@ package io.opentelemetry.instrumentation.jdbc.internal; -import static io.opentelemetry.instrumentation.jdbc.internal.JdbcSingletons.instrumenter; - import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo; import java.sql.Connection; import java.sql.ResultSet; @@ -41,17 +40,20 @@ public class OpenTelemetryStatement implements Statement { protected final S delegate; protected final DbInfo dbInfo; protected final String query; + protected final Instrumenter instrumenter; private final ArrayList batchCommands = new ArrayList<>(); - OpenTelemetryStatement(S delegate, DbInfo dbInfo) { - this(delegate, dbInfo, null); + OpenTelemetryStatement(S delegate, DbInfo dbInfo, Instrumenter instrumenter) { + this(delegate, dbInfo, null, instrumenter); } - OpenTelemetryStatement(S delegate, DbInfo dbInfo, String query) { + OpenTelemetryStatement( + S delegate, DbInfo dbInfo, String query, Instrumenter instrumenter) { this.delegate = delegate; this.dbInfo = dbInfo; this.query = query; + this.instrumenter = instrumenter; } @Override @@ -282,19 +284,19 @@ protected T wrapCall(String sql, ThrowingSupplier Context parentContext = Context.current(); DbRequest request = DbRequest.create(dbInfo, sql); - if (!instrumenter().shouldStart(parentContext, request)) { + if (!this.instrumenter.shouldStart(parentContext, request)) { return callable.call(); } - Context context = instrumenter().start(parentContext, request); + Context context = this.instrumenter.start(parentContext, request); T result; try (Scope ignored = context.makeCurrent()) { result = callable.call(); } catch (Throwable t) { - instrumenter().end(context, request, null, t); + this.instrumenter.end(context, request, null, t); throw t; } - instrumenter().end(context, request, null, null); + this.instrumenter.end(context, request, null, null); return result; } diff --git a/instrumentation/jdbc/library/src/test/groovy/io/opentelemetry/instrumentation/jdbc/OpenTelemetryConnectionTest.groovy b/instrumentation/jdbc/library/src/test/groovy/io/opentelemetry/instrumentation/jdbc/OpenTelemetryConnectionTest.groovy index f474c69d14fb..1b106b74ef6a 100644 --- a/instrumentation/jdbc/library/src/test/groovy/io/opentelemetry/instrumentation/jdbc/OpenTelemetryConnectionTest.groovy +++ b/instrumentation/jdbc/library/src/test/groovy/io/opentelemetry/instrumentation/jdbc/OpenTelemetryConnectionTest.groovy @@ -5,24 +5,29 @@ package io.opentelemetry.instrumentation.jdbc + +import io.opentelemetry.api.OpenTelemetry import io.opentelemetry.api.trace.SpanKind -import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo +import io.opentelemetry.context.propagation.ContextPropagators import io.opentelemetry.instrumentation.jdbc.internal.OpenTelemetryCallableStatement import io.opentelemetry.instrumentation.jdbc.internal.OpenTelemetryConnection import io.opentelemetry.instrumentation.jdbc.internal.OpenTelemetryPreparedStatement import io.opentelemetry.instrumentation.jdbc.internal.OpenTelemetryStatement +import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo import io.opentelemetry.instrumentation.test.InstrumentationSpecification import io.opentelemetry.instrumentation.test.LibraryTestTrait import io.opentelemetry.semconv.trace.attributes.SemanticAttributes import static io.opentelemetry.api.trace.SpanKind.CLIENT +import static io.opentelemetry.instrumentation.jdbc.internal.JdbcInstrumenterFactory.createStatementInstrumenter class OpenTelemetryConnectionTest extends InstrumentationSpecification implements LibraryTestTrait { def "verify create statement"() { setup: + def instr = createStatementInstrumenter(openTelemetry) def dbInfo = getDbInfo() - def connection = new OpenTelemetryConnection(new TestConnection(), dbInfo) + def connection = new OpenTelemetryConnection(new TestConnection(), dbInfo, instr) String query = "SELECT * FROM users" def statement = connection.createStatement() runWithSpan("parent") { @@ -63,18 +68,22 @@ class OpenTelemetryConnectionTest extends InstrumentationSpecification implement def "verify create statement returns otel wrapper"() { when: - def connection = new OpenTelemetryConnection(new TestConnection(), DbInfo.DEFAULT) + def ot = OpenTelemetry.propagating(ContextPropagators.noop()) + def instr = createStatementInstrumenter(ot) + def connection = new OpenTelemetryConnection(new TestConnection(), DbInfo.DEFAULT, instr) then: connection.createStatement().class == OpenTelemetryStatement connection.createStatement(0, 0).class == OpenTelemetryStatement connection.createStatement(0, 0, 0).class == OpenTelemetryStatement + connection.createStatement().instrumenter == instr } def "verify prepare statement"() { setup: + def instr = createStatementInstrumenter(openTelemetry) def dbInfo = getDbInfo() - def connection = new OpenTelemetryConnection(new TestConnection(), dbInfo) + def connection = new OpenTelemetryConnection(new TestConnection(), dbInfo, instr) String query = "SELECT * FROM users" def statement = connection.prepareStatement(query) runWithSpan("parent") { @@ -115,21 +124,26 @@ class OpenTelemetryConnectionTest extends InstrumentationSpecification implement def "verify prepare statement returns otel wrapper"() { when: - def connection = new OpenTelemetryConnection(new TestConnection(), DbInfo.DEFAULT) + def ot = OpenTelemetry.propagating(ContextPropagators.noop()) + def instr = createStatementInstrumenter(ot) + def connection = new OpenTelemetryConnection(new TestConnection(), DbInfo.DEFAULT, instr) + String query = "SELECT * FROM users" then: - connection.prepareStatement("SELECT * FROM users").class == OpenTelemetryPreparedStatement - connection.prepareStatement("SELECT * FROM users", [0] as int[]).class == OpenTelemetryPreparedStatement - connection.prepareStatement("SELECT * FROM users", ["id"] as String[]).class == OpenTelemetryPreparedStatement - connection.prepareStatement("SELECT * FROM users", 0).class == OpenTelemetryPreparedStatement - connection.prepareStatement("SELECT * FROM users", 0, 0).class == OpenTelemetryPreparedStatement - connection.prepareStatement("SELECT * FROM users", 0, 0, 0).class == OpenTelemetryPreparedStatement + connection.prepareStatement(query).class == OpenTelemetryPreparedStatement + connection.prepareStatement(query, [0] as int[]).class == OpenTelemetryPreparedStatement + connection.prepareStatement(query, ["id"] as String[]).class == OpenTelemetryPreparedStatement + connection.prepareStatement(query, 0).class == OpenTelemetryPreparedStatement + connection.prepareStatement(query, 0, 0).class == OpenTelemetryPreparedStatement + connection.prepareStatement(query, 0, 0, 0).class == OpenTelemetryPreparedStatement + connection.prepareStatement(query).instrumenter == instr } def "verify prepare call"() { setup: + def instr = createStatementInstrumenter(openTelemetry) def dbInfo = getDbInfo() - def connection = new OpenTelemetryConnection(new TestConnection(), dbInfo) + def connection = new OpenTelemetryConnection(new TestConnection(), dbInfo, instr) String query = "SELECT * FROM users" def statement = connection.prepareCall(query) runWithSpan("parent") { @@ -170,12 +184,16 @@ class OpenTelemetryConnectionTest extends InstrumentationSpecification implement def "verify prepare call returns otel wrapper"() { when: - def connection = new OpenTelemetryConnection(new TestConnection(), DbInfo.DEFAULT) + def ot = OpenTelemetry.propagating(ContextPropagators.noop()) + def instr = createStatementInstrumenter(ot) + def connection = new OpenTelemetryConnection(new TestConnection(), DbInfo.DEFAULT, instr) + String query = "SELECT * FROM users" then: - connection.prepareCall("SELECT * FROM users").class == OpenTelemetryCallableStatement - connection.prepareCall("SELECT * FROM users", 0, 0).class == OpenTelemetryCallableStatement - connection.prepareCall("SELECT * FROM users", 0, 0, 0).class == OpenTelemetryCallableStatement + connection.prepareCall(query).class == OpenTelemetryCallableStatement + connection.prepareCall(query, 0, 0).class == OpenTelemetryCallableStatement + connection.prepareCall(query, 0, 0, 0).class == OpenTelemetryCallableStatement + connection.prepareCall(query).instrumenter == instr } private DbInfo getDbInfo() { diff --git a/instrumentation/jdbc/library/src/test/groovy/io/opentelemetry/instrumentation/jdbc/datasource/OpenTelemetryDataSourceTest.groovy b/instrumentation/jdbc/library/src/test/groovy/io/opentelemetry/instrumentation/jdbc/datasource/OpenTelemetryDataSourceTest.groovy index 7e8e92fdaa74..22403261e665 100644 --- a/instrumentation/jdbc/library/src/test/groovy/io/opentelemetry/instrumentation/jdbc/datasource/OpenTelemetryDataSourceTest.groovy +++ b/instrumentation/jdbc/library/src/test/groovy/io/opentelemetry/instrumentation/jdbc/datasource/OpenTelemetryDataSourceTest.groovy @@ -5,6 +5,8 @@ package io.opentelemetry.instrumentation.jdbc.datasource +import io.opentelemetry.api.OpenTelemetry +import io.opentelemetry.context.propagation.ContextPropagators import io.opentelemetry.instrumentation.jdbc.internal.OpenTelemetryConnection import spock.lang.Specification @@ -12,12 +14,14 @@ class OpenTelemetryDataSourceTest extends Specification { def "verify get connection"() { when: - def dataSource = new OpenTelemetryDataSource(new TestDataSource()) + def ot = OpenTelemetry.propagating(ContextPropagators.noop()) + def dataSource = new OpenTelemetryDataSource(new TestDataSource(), ot) def connection = dataSource.getConnection() then: connection != null connection instanceof OpenTelemetryConnection + connection.statementInstrumenter != null when: def dbInfo = ((OpenTelemetryConnection) connection).dbInfo @@ -35,12 +39,14 @@ class OpenTelemetryDataSourceTest extends Specification { def "verify get connection with username and password"() { when: - def dataSource = new OpenTelemetryDataSource(new TestDataSource()) + def ot = OpenTelemetry.propagating(ContextPropagators.noop()) + def dataSource = new OpenTelemetryDataSource(new TestDataSource(), ot) def connection = dataSource.getConnection(null, null) then: connection != null connection instanceof OpenTelemetryConnection + connection.statementInstrumenter != null when: def dbInfo = ((OpenTelemetryConnection) connection).dbInfo @@ -55,5 +61,4 @@ class OpenTelemetryDataSourceTest extends Specification { dbInfo.host == "127.0.0.1" dbInfo.port == 5432 } - }