Allow JDBC autoinstrumentation to use a custom OpenTelemetry instance to be more DI (e.g. Spring Boot) friendly (#7697)
Related to issue https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/7677
This commit is contained in:
parent
c3e877032b
commit
1d3752f21b
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.jdbc;
|
package io.opentelemetry.javaagent.instrumentation.jdbc;
|
||||||
|
|
||||||
|
import static io.opentelemetry.instrumentation.jdbc.internal.DataSourceInstrumenterFactory.createDataSourceInstrumenter;
|
||||||
|
|
||||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
|
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
|
||||||
|
@ -17,17 +19,20 @@ import io.opentelemetry.instrumentation.jdbc.internal.JdbcAttributesGetter;
|
||||||
import io.opentelemetry.instrumentation.jdbc.internal.JdbcNetAttributesGetter;
|
import io.opentelemetry.instrumentation.jdbc.internal.JdbcNetAttributesGetter;
|
||||||
import io.opentelemetry.javaagent.bootstrap.internal.CommonConfig;
|
import io.opentelemetry.javaagent.bootstrap.internal.CommonConfig;
|
||||||
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
|
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
public final class JdbcSingletons {
|
public final class JdbcSingletons {
|
||||||
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.jdbc";
|
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.jdbc";
|
||||||
|
|
||||||
private static final Instrumenter<DbRequest, Void> INSTRUMENTER;
|
private static final Instrumenter<DbRequest, Void> STATEMENT_INSTRUMENTER;
|
||||||
|
public static final Instrumenter<DataSource, Void> DATASOURCE_INSTRUMENTER =
|
||||||
|
createDataSourceInstrumenter(GlobalOpenTelemetry.get());
|
||||||
|
|
||||||
static {
|
static {
|
||||||
JdbcAttributesGetter dbAttributesGetter = new JdbcAttributesGetter();
|
JdbcAttributesGetter dbAttributesGetter = new JdbcAttributesGetter();
|
||||||
JdbcNetAttributesGetter netAttributesGetter = new JdbcNetAttributesGetter();
|
JdbcNetAttributesGetter netAttributesGetter = new JdbcNetAttributesGetter();
|
||||||
|
|
||||||
INSTRUMENTER =
|
STATEMENT_INSTRUMENTER =
|
||||||
Instrumenter.<DbRequest, Void>builder(
|
Instrumenter.<DbRequest, Void>builder(
|
||||||
GlobalOpenTelemetry.get(),
|
GlobalOpenTelemetry.get(),
|
||||||
INSTRUMENTATION_NAME,
|
INSTRUMENTATION_NAME,
|
||||||
|
@ -47,8 +52,12 @@ public final class JdbcSingletons {
|
||||||
.buildInstrumenter(SpanKindExtractor.alwaysClient());
|
.buildInstrumenter(SpanKindExtractor.alwaysClient());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Instrumenter<DbRequest, Void> instrumenter() {
|
public static Instrumenter<DbRequest, Void> statementInstrumenter() {
|
||||||
return INSTRUMENTER;
|
return STATEMENT_INSTRUMENTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Instrumenter<DataSource, Void> dataSourceInstrumenter() {
|
||||||
|
return DATASOURCE_INSTRUMENTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JdbcSingletons() {}
|
private JdbcSingletons() {}
|
||||||
|
|
|
@ -8,7 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.jdbc;
|
||||||
import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext;
|
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.hasClassesNamed;
|
||||||
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface;
|
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.isPublic;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
@ -70,11 +70,11 @@ public class PreparedStatementInstrumentation implements TypeInstrumentation {
|
||||||
Context parentContext = currentContext();
|
Context parentContext = currentContext();
|
||||||
request = DbRequest.create(statement);
|
request = DbRequest.create(statement);
|
||||||
|
|
||||||
if (request == null || !instrumenter().shouldStart(parentContext, request)) {
|
if (request == null || !statementInstrumenter().shouldStart(parentContext, request)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
context = instrumenter().start(parentContext, request);
|
context = statementInstrumenter().start(parentContext, request);
|
||||||
scope = context.makeCurrent();
|
scope = context.makeCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ public class PreparedStatementInstrumentation implements TypeInstrumentation {
|
||||||
|
|
||||||
if (scope != null) {
|
if (scope != null) {
|
||||||
scope.close();
|
scope.close();
|
||||||
instrumenter().end(context, request, null, throwable);
|
statementInstrumenter().end(context, request, null, throwable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.jdbc;
|
||||||
import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext;
|
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.hasClassesNamed;
|
||||||
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface;
|
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.isPublic;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
@ -70,11 +70,11 @@ public class StatementInstrumentation implements TypeInstrumentation {
|
||||||
Context parentContext = currentContext();
|
Context parentContext = currentContext();
|
||||||
request = DbRequest.create(statement, sql);
|
request = DbRequest.create(statement, sql);
|
||||||
|
|
||||||
if (request == null || !instrumenter().shouldStart(parentContext, request)) {
|
if (request == null || !statementInstrumenter().shouldStart(parentContext, request)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
context = instrumenter().start(parentContext, request);
|
context = statementInstrumenter().start(parentContext, request);
|
||||||
scope = context.makeCurrent();
|
scope = context.makeCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ public class StatementInstrumentation implements TypeInstrumentation {
|
||||||
|
|
||||||
if (scope != null) {
|
if (scope != null) {
|
||||||
scope.close();
|
scope.close();
|
||||||
instrumenter().end(context, request, null, throwable);
|
statementInstrumenter().end(context, request, null, throwable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.jdbc.datasource;
|
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.extension.matcher.AgentElementMatchers.implementsInterface;
|
||||||
|
import static io.opentelemetry.javaagent.instrumentation.jdbc.JdbcSingletons.dataSourceInstrumenter;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
|
@ -20,6 +20,7 @@ import net.bytebuddy.description.type.TypeDescription;
|
||||||
import net.bytebuddy.matcher.ElementMatcher;
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
|
|
||||||
public class DataSourceInstrumentation implements TypeInstrumentation {
|
public class DataSourceInstrumentation implements TypeInstrumentation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ElementMatcher<TypeDescription> typeMatcher() {
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
return implementsInterface(named("javax.sql.DataSource"));
|
return implementsInterface(named("javax.sql.DataSource"));
|
||||||
|
@ -46,7 +47,7 @@ public class DataSourceInstrumentation implements TypeInstrumentation {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
context = instrumenter().start(parentContext, ds);
|
context = dataSourceInstrumenter().start(parentContext, ds);
|
||||||
scope = context.makeCurrent();
|
scope = context.makeCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ public class DataSourceInstrumentation implements TypeInstrumentation {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
scope.close();
|
scope.close();
|
||||||
instrumenter().end(context, ds, null, throwable);
|
dataSourceInstrumenter().end(context, ds, null, throwable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,8 @@
|
||||||
|
|
||||||
package io.opentelemetry.instrumentation.jdbc;
|
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.api.internal.EmbeddedInstrumentationProperties;
|
||||||
import io.opentelemetry.instrumentation.jdbc.internal.JdbcConnectionUrlParser;
|
import io.opentelemetry.instrumentation.jdbc.internal.JdbcConnectionUrlParser;
|
||||||
|
@ -211,7 +212,7 @@ public final class OpenTelemetryDriver implements Driver {
|
||||||
|
|
||||||
DbInfo dbInfo = JdbcConnectionUrlParser.parse(realUrl, info);
|
DbInfo dbInfo = JdbcConnectionUrlParser.parse(realUrl, info);
|
||||||
|
|
||||||
return new OpenTelemetryConnection(connection, dbInfo);
|
return new OpenTelemetryConnection(connection, dbInfo, statementInstrumenter());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,12 +20,17 @@
|
||||||
|
|
||||||
package io.opentelemetry.instrumentation.jdbc.datasource;
|
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 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.api.trace.Span;
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
import io.opentelemetry.context.Scope;
|
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.OpenTelemetryConnection;
|
||||||
import io.opentelemetry.instrumentation.jdbc.internal.ThrowingSupplier;
|
import io.opentelemetry.instrumentation.jdbc.internal.ThrowingSupplier;
|
||||||
import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo;
|
import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo;
|
||||||
|
@ -40,29 +45,44 @@ import javax.sql.DataSource;
|
||||||
public class OpenTelemetryDataSource implements DataSource, AutoCloseable {
|
public class OpenTelemetryDataSource implements DataSource, AutoCloseable {
|
||||||
|
|
||||||
private final DataSource delegate;
|
private final DataSource delegate;
|
||||||
|
private final Instrumenter<DataSource, Void> dataSourceInstrumenter;
|
||||||
|
private final Instrumenter<DbRequest, Void> 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
|
* Create a OpenTelemetry DataSource wrapping another DataSource. This constructor is primarily
|
||||||
* used by dependency injection frameworks.
|
* used by dependency injection frameworks.
|
||||||
*
|
*
|
||||||
* @param delegate the DataSource to wrap
|
* @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.delegate = delegate;
|
||||||
|
this.dataSourceInstrumenter = createDataSourceInstrumenter(openTelemetry);
|
||||||
|
this.statementInstrumenter = createStatementInstrumenter(openTelemetry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Connection getConnection() throws SQLException {
|
public Connection getConnection() throws SQLException {
|
||||||
Connection connection = wrapCall(delegate::getConnection);
|
Connection connection = wrapCall(delegate::getConnection);
|
||||||
DbInfo dbInfo = computeDbInfo(connection);
|
DbInfo dbInfo = computeDbInfo(connection);
|
||||||
return new OpenTelemetryConnection(connection, dbInfo);
|
return new OpenTelemetryConnection(connection, dbInfo, statementInstrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Connection getConnection(String username, String password) throws SQLException {
|
public Connection getConnection(String username, String password) throws SQLException {
|
||||||
Connection connection = wrapCall(() -> delegate.getConnection(username, password));
|
Connection connection = wrapCall(() -> delegate.getConnection(username, password));
|
||||||
DbInfo dbInfo = computeDbInfo(connection);
|
DbInfo dbInfo = computeDbInfo(connection);
|
||||||
return new OpenTelemetryConnection(connection, dbInfo);
|
return new OpenTelemetryConnection(connection, dbInfo, statementInstrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -116,15 +136,15 @@ public class OpenTelemetryDataSource implements DataSource, AutoCloseable {
|
||||||
return callable.call();
|
return callable.call();
|
||||||
}
|
}
|
||||||
|
|
||||||
Context context = instrumenter().start(parentContext, delegate);
|
Context context = this.dataSourceInstrumenter.start(parentContext, delegate);
|
||||||
T result;
|
T result;
|
||||||
try (Scope ignored = context.makeCurrent()) {
|
try (Scope ignored = context.makeCurrent()) {
|
||||||
result = callable.call();
|
result = callable.call();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
instrumenter().end(context, delegate, null, t);
|
this.dataSourceInstrumenter.end(context, delegate, null, t);
|
||||||
throw t;
|
throw t;
|
||||||
}
|
}
|
||||||
instrumenter().end(context, delegate, null, null);
|
this.dataSourceInstrumenter.end(context, delegate, null, null);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<DataSource, Void> createDataSourceInstrumenter(
|
||||||
|
OpenTelemetry openTelemetry) {
|
||||||
|
return Instrumenter.<DataSource, Void>builder(
|
||||||
|
openTelemetry, INSTRUMENTATION_NAME, CodeSpanNameExtractor.create(codeAttributesGetter))
|
||||||
|
.addAttributesExtractor(CodeAttributesExtractor.create(codeAttributesGetter))
|
||||||
|
.buildInstrumenter();
|
||||||
|
}
|
||||||
|
|
||||||
|
private DataSourceInstrumenterFactory() {}
|
||||||
|
}
|
|
@ -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<DataSource, Void> INSTRUMENTER;
|
|
||||||
|
|
||||||
static {
|
|
||||||
DataSourceCodeAttributesGetter codeAttributesGetter = new DataSourceCodeAttributesGetter();
|
|
||||||
|
|
||||||
INSTRUMENTER =
|
|
||||||
Instrumenter.<DataSource, Void>builder(
|
|
||||||
GlobalOpenTelemetry.get(),
|
|
||||||
INSTRUMENTATION_NAME,
|
|
||||||
CodeSpanNameExtractor.create(codeAttributesGetter))
|
|
||||||
.addAttributesExtractor(CodeAttributesExtractor.create(codeAttributesGetter))
|
|
||||||
.buildInstrumenter();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Instrumenter<DataSource, Void> instrumenter() {
|
|
||||||
return INSTRUMENTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DataSourceSingletons() {}
|
|
||||||
}
|
|
|
@ -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<DbRequest, Void> createStatementInstrumenter() {
|
||||||
|
return createStatementInstrumenter(GlobalOpenTelemetry.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Instrumenter<DbRequest, Void> createStatementInstrumenter(
|
||||||
|
OpenTelemetry openTelemetry) {
|
||||||
|
return Instrumenter.<DbRequest, Void>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() {}
|
||||||
|
}
|
|
@ -5,44 +5,21 @@
|
||||||
|
|
||||||
package io.opentelemetry.instrumentation.jdbc.internal;
|
package io.opentelemetry.instrumentation.jdbc.internal;
|
||||||
|
|
||||||
|
import static io.opentelemetry.instrumentation.jdbc.internal.JdbcInstrumenterFactory.createStatementInstrumenter;
|
||||||
|
|
||||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
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
|
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||||
* any time.
|
* any time.
|
||||||
*/
|
*/
|
||||||
public final class JdbcSingletons {
|
public final class JdbcSingletons {
|
||||||
public static final String INSTRUMENTATION_NAME = "io.opentelemetry.jdbc";
|
public static final Instrumenter<DbRequest, Void> STATEMENT_INSTRUMENTER =
|
||||||
|
createStatementInstrumenter(GlobalOpenTelemetry.get());
|
||||||
|
|
||||||
private static final Instrumenter<DbRequest, Void> INSTRUMENTER;
|
public static Instrumenter<DbRequest, Void> statementInstrumenter() {
|
||||||
|
return STATEMENT_INSTRUMENTER;
|
||||||
static {
|
|
||||||
JdbcAttributesGetter dbAttributesGetter = new JdbcAttributesGetter();
|
|
||||||
JdbcNetAttributesGetter netAttributesGetter = new JdbcNetAttributesGetter();
|
|
||||||
|
|
||||||
INSTRUMENTER =
|
|
||||||
Instrumenter.<DbRequest, Void>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 Instrumenter<DbRequest, Void> instrumenter() {
|
|
||||||
return INSTRUMENTER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private JdbcSingletons() {}
|
private JdbcSingletons() {}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
package io.opentelemetry.instrumentation.jdbc.internal;
|
package io.opentelemetry.instrumentation.jdbc.internal;
|
||||||
|
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||||
import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo;
|
import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
@ -47,8 +48,9 @@ import java.util.Map;
|
||||||
public class OpenTelemetryCallableStatement<S extends CallableStatement>
|
public class OpenTelemetryCallableStatement<S extends CallableStatement>
|
||||||
extends OpenTelemetryPreparedStatement<S> implements CallableStatement {
|
extends OpenTelemetryPreparedStatement<S> implements CallableStatement {
|
||||||
|
|
||||||
public OpenTelemetryCallableStatement(S delegate, DbInfo dbInfo, String query) {
|
public OpenTelemetryCallableStatement(
|
||||||
super(delegate, dbInfo, query);
|
S delegate, DbInfo dbInfo, String query, Instrumenter<DbRequest, Void> instrumenter) {
|
||||||
|
super(delegate, dbInfo, query, instrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
package io.opentelemetry.instrumentation.jdbc.internal;
|
package io.opentelemetry.instrumentation.jdbc.internal;
|
||||||
|
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||||
import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo;
|
import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo;
|
||||||
import java.sql.Array;
|
import java.sql.Array;
|
||||||
import java.sql.Blob;
|
import java.sql.Blob;
|
||||||
|
@ -48,23 +49,26 @@ public class OpenTelemetryConnection implements Connection {
|
||||||
|
|
||||||
private final Connection delegate;
|
private final Connection delegate;
|
||||||
private final DbInfo dbInfo;
|
private final DbInfo dbInfo;
|
||||||
|
protected final Instrumenter<DbRequest, Void> statementInstrumenter;
|
||||||
|
|
||||||
public OpenTelemetryConnection(Connection delegate, DbInfo dbInfo) {
|
public OpenTelemetryConnection(
|
||||||
|
Connection delegate, DbInfo dbInfo, Instrumenter<DbRequest, Void> statementInstrumenter) {
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
this.dbInfo = dbInfo;
|
this.dbInfo = dbInfo;
|
||||||
|
this.statementInstrumenter = statementInstrumenter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Statement createStatement() throws SQLException {
|
public Statement createStatement() throws SQLException {
|
||||||
Statement statement = delegate.createStatement();
|
Statement statement = delegate.createStatement();
|
||||||
return new OpenTelemetryStatement<>(statement, dbInfo);
|
return new OpenTelemetryStatement<>(statement, dbInfo, statementInstrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Statement createStatement(int resultSetType, int resultSetConcurrency)
|
public Statement createStatement(int resultSetType, int resultSetConcurrency)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
Statement statement = delegate.createStatement(resultSetType, resultSetConcurrency);
|
Statement statement = delegate.createStatement(resultSetType, resultSetConcurrency);
|
||||||
return new OpenTelemetryStatement<>(statement, dbInfo);
|
return new OpenTelemetryStatement<>(statement, dbInfo, statementInstrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -72,13 +76,13 @@ public class OpenTelemetryConnection implements Connection {
|
||||||
int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
|
||||||
Statement statement =
|
Statement statement =
|
||||||
delegate.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
|
delegate.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
|
||||||
return new OpenTelemetryStatement<>(statement, dbInfo);
|
return new OpenTelemetryStatement<>(statement, dbInfo, statementInstrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PreparedStatement prepareStatement(String sql) throws SQLException {
|
public PreparedStatement prepareStatement(String sql) throws SQLException {
|
||||||
PreparedStatement statement = delegate.prepareStatement(sql);
|
PreparedStatement statement = delegate.prepareStatement(sql);
|
||||||
return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql);
|
return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql, statementInstrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -86,7 +90,7 @@ public class OpenTelemetryConnection implements Connection {
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
PreparedStatement statement =
|
PreparedStatement statement =
|
||||||
delegate.prepareStatement(sql, resultSetType, resultSetConcurrency);
|
delegate.prepareStatement(sql, resultSetType, resultSetConcurrency);
|
||||||
return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql);
|
return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql, statementInstrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -95,38 +99,38 @@ public class OpenTelemetryConnection implements Connection {
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
PreparedStatement statement =
|
PreparedStatement statement =
|
||||||
delegate.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
|
delegate.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
|
||||||
return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql);
|
return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql, statementInstrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
|
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
|
||||||
PreparedStatement statement = delegate.prepareStatement(sql, autoGeneratedKeys);
|
PreparedStatement statement = delegate.prepareStatement(sql, autoGeneratedKeys);
|
||||||
return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql);
|
return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql, statementInstrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
|
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
|
||||||
PreparedStatement statement = delegate.prepareStatement(sql, columnIndexes);
|
PreparedStatement statement = delegate.prepareStatement(sql, columnIndexes);
|
||||||
return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql);
|
return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql, statementInstrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
|
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
|
||||||
PreparedStatement statement = delegate.prepareStatement(sql, columnNames);
|
PreparedStatement statement = delegate.prepareStatement(sql, columnNames);
|
||||||
return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql);
|
return new OpenTelemetryPreparedStatement<>(statement, dbInfo, sql, statementInstrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CallableStatement prepareCall(String sql) throws SQLException {
|
public CallableStatement prepareCall(String sql) throws SQLException {
|
||||||
CallableStatement statement = delegate.prepareCall(sql);
|
CallableStatement statement = delegate.prepareCall(sql);
|
||||||
return new OpenTelemetryCallableStatement<>(statement, dbInfo, sql);
|
return new OpenTelemetryCallableStatement<>(statement, dbInfo, sql, statementInstrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency)
|
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
CallableStatement statement = delegate.prepareCall(sql, resultSetType, resultSetConcurrency);
|
CallableStatement statement = delegate.prepareCall(sql, resultSetType, resultSetConcurrency);
|
||||||
return new OpenTelemetryCallableStatement<>(statement, dbInfo, sql);
|
return new OpenTelemetryCallableStatement<>(statement, dbInfo, sql, statementInstrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -135,7 +139,7 @@ public class OpenTelemetryConnection implements Connection {
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
CallableStatement statement =
|
CallableStatement statement =
|
||||||
delegate.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
|
delegate.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
|
||||||
return new OpenTelemetryCallableStatement<>(statement, dbInfo, sql);
|
return new OpenTelemetryCallableStatement<>(statement, dbInfo, sql, statementInstrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
package io.opentelemetry.instrumentation.jdbc.internal;
|
package io.opentelemetry.instrumentation.jdbc.internal;
|
||||||
|
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||||
import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo;
|
import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
@ -49,8 +50,9 @@ import java.util.Calendar;
|
||||||
public class OpenTelemetryPreparedStatement<S extends PreparedStatement>
|
public class OpenTelemetryPreparedStatement<S extends PreparedStatement>
|
||||||
extends OpenTelemetryStatement<S> implements PreparedStatement {
|
extends OpenTelemetryStatement<S> implements PreparedStatement {
|
||||||
|
|
||||||
public OpenTelemetryPreparedStatement(S delegate, DbInfo dbInfo, String query) {
|
public OpenTelemetryPreparedStatement(
|
||||||
super(delegate, dbInfo, query);
|
S delegate, DbInfo dbInfo, String query, Instrumenter<DbRequest, Void> instrumenter) {
|
||||||
|
super(delegate, dbInfo, query, instrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,10 +20,9 @@
|
||||||
|
|
||||||
package io.opentelemetry.instrumentation.jdbc.internal;
|
package io.opentelemetry.instrumentation.jdbc.internal;
|
||||||
|
|
||||||
import static io.opentelemetry.instrumentation.jdbc.internal.JdbcSingletons.instrumenter;
|
|
||||||
|
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
import io.opentelemetry.context.Scope;
|
import io.opentelemetry.context.Scope;
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||||
import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo;
|
import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
@ -41,17 +40,20 @@ public class OpenTelemetryStatement<S extends Statement> implements Statement {
|
||||||
protected final S delegate;
|
protected final S delegate;
|
||||||
protected final DbInfo dbInfo;
|
protected final DbInfo dbInfo;
|
||||||
protected final String query;
|
protected final String query;
|
||||||
|
protected final Instrumenter<DbRequest, Void> instrumenter;
|
||||||
|
|
||||||
private final ArrayList<String> batchCommands = new ArrayList<>();
|
private final ArrayList<String> batchCommands = new ArrayList<>();
|
||||||
|
|
||||||
OpenTelemetryStatement(S delegate, DbInfo dbInfo) {
|
OpenTelemetryStatement(S delegate, DbInfo dbInfo, Instrumenter<DbRequest, Void> instrumenter) {
|
||||||
this(delegate, dbInfo, null);
|
this(delegate, dbInfo, null, instrumenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenTelemetryStatement(S delegate, DbInfo dbInfo, String query) {
|
OpenTelemetryStatement(
|
||||||
|
S delegate, DbInfo dbInfo, String query, Instrumenter<DbRequest, Void> instrumenter) {
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
this.dbInfo = dbInfo;
|
this.dbInfo = dbInfo;
|
||||||
this.query = query;
|
this.query = query;
|
||||||
|
this.instrumenter = instrumenter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -282,19 +284,19 @@ public class OpenTelemetryStatement<S extends Statement> implements Statement {
|
||||||
Context parentContext = Context.current();
|
Context parentContext = Context.current();
|
||||||
DbRequest request = DbRequest.create(dbInfo, sql);
|
DbRequest request = DbRequest.create(dbInfo, sql);
|
||||||
|
|
||||||
if (!instrumenter().shouldStart(parentContext, request)) {
|
if (!this.instrumenter.shouldStart(parentContext, request)) {
|
||||||
return callable.call();
|
return callable.call();
|
||||||
}
|
}
|
||||||
|
|
||||||
Context context = instrumenter().start(parentContext, request);
|
Context context = this.instrumenter.start(parentContext, request);
|
||||||
T result;
|
T result;
|
||||||
try (Scope ignored = context.makeCurrent()) {
|
try (Scope ignored = context.makeCurrent()) {
|
||||||
result = callable.call();
|
result = callable.call();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
instrumenter().end(context, request, null, t);
|
this.instrumenter.end(context, request, null, t);
|
||||||
throw t;
|
throw t;
|
||||||
}
|
}
|
||||||
instrumenter().end(context, request, null, null);
|
this.instrumenter.end(context, request, null, null);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,24 +5,29 @@
|
||||||
|
|
||||||
package io.opentelemetry.instrumentation.jdbc
|
package io.opentelemetry.instrumentation.jdbc
|
||||||
|
|
||||||
|
|
||||||
|
import io.opentelemetry.api.OpenTelemetry
|
||||||
import io.opentelemetry.api.trace.SpanKind
|
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.OpenTelemetryCallableStatement
|
||||||
import io.opentelemetry.instrumentation.jdbc.internal.OpenTelemetryConnection
|
import io.opentelemetry.instrumentation.jdbc.internal.OpenTelemetryConnection
|
||||||
import io.opentelemetry.instrumentation.jdbc.internal.OpenTelemetryPreparedStatement
|
import io.opentelemetry.instrumentation.jdbc.internal.OpenTelemetryPreparedStatement
|
||||||
import io.opentelemetry.instrumentation.jdbc.internal.OpenTelemetryStatement
|
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.InstrumentationSpecification
|
||||||
import io.opentelemetry.instrumentation.test.LibraryTestTrait
|
import io.opentelemetry.instrumentation.test.LibraryTestTrait
|
||||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||||
|
|
||||||
import static io.opentelemetry.api.trace.SpanKind.CLIENT
|
import static io.opentelemetry.api.trace.SpanKind.CLIENT
|
||||||
|
import static io.opentelemetry.instrumentation.jdbc.internal.JdbcInstrumenterFactory.createStatementInstrumenter
|
||||||
|
|
||||||
class OpenTelemetryConnectionTest extends InstrumentationSpecification implements LibraryTestTrait {
|
class OpenTelemetryConnectionTest extends InstrumentationSpecification implements LibraryTestTrait {
|
||||||
|
|
||||||
def "verify create statement"() {
|
def "verify create statement"() {
|
||||||
setup:
|
setup:
|
||||||
|
def instr = createStatementInstrumenter(openTelemetry)
|
||||||
def dbInfo = getDbInfo()
|
def dbInfo = getDbInfo()
|
||||||
def connection = new OpenTelemetryConnection(new TestConnection(), dbInfo)
|
def connection = new OpenTelemetryConnection(new TestConnection(), dbInfo, instr)
|
||||||
String query = "SELECT * FROM users"
|
String query = "SELECT * FROM users"
|
||||||
def statement = connection.createStatement()
|
def statement = connection.createStatement()
|
||||||
runWithSpan("parent") {
|
runWithSpan("parent") {
|
||||||
|
@ -63,18 +68,22 @@ class OpenTelemetryConnectionTest extends InstrumentationSpecification implement
|
||||||
|
|
||||||
def "verify create statement returns otel wrapper"() {
|
def "verify create statement returns otel wrapper"() {
|
||||||
when:
|
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:
|
then:
|
||||||
connection.createStatement().class == OpenTelemetryStatement
|
connection.createStatement().class == OpenTelemetryStatement
|
||||||
connection.createStatement(0, 0).class == OpenTelemetryStatement
|
connection.createStatement(0, 0).class == OpenTelemetryStatement
|
||||||
connection.createStatement(0, 0, 0).class == OpenTelemetryStatement
|
connection.createStatement(0, 0, 0).class == OpenTelemetryStatement
|
||||||
|
connection.createStatement().instrumenter == instr
|
||||||
}
|
}
|
||||||
|
|
||||||
def "verify prepare statement"() {
|
def "verify prepare statement"() {
|
||||||
setup:
|
setup:
|
||||||
|
def instr = createStatementInstrumenter(openTelemetry)
|
||||||
def dbInfo = getDbInfo()
|
def dbInfo = getDbInfo()
|
||||||
def connection = new OpenTelemetryConnection(new TestConnection(), dbInfo)
|
def connection = new OpenTelemetryConnection(new TestConnection(), dbInfo, instr)
|
||||||
String query = "SELECT * FROM users"
|
String query = "SELECT * FROM users"
|
||||||
def statement = connection.prepareStatement(query)
|
def statement = connection.prepareStatement(query)
|
||||||
runWithSpan("parent") {
|
runWithSpan("parent") {
|
||||||
|
@ -115,21 +124,26 @@ class OpenTelemetryConnectionTest extends InstrumentationSpecification implement
|
||||||
|
|
||||||
def "verify prepare statement returns otel wrapper"() {
|
def "verify prepare statement returns otel wrapper"() {
|
||||||
when:
|
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:
|
then:
|
||||||
connection.prepareStatement("SELECT * FROM users").class == OpenTelemetryPreparedStatement
|
connection.prepareStatement(query).class == OpenTelemetryPreparedStatement
|
||||||
connection.prepareStatement("SELECT * FROM users", [0] as int[]).class == OpenTelemetryPreparedStatement
|
connection.prepareStatement(query, [0] as int[]).class == OpenTelemetryPreparedStatement
|
||||||
connection.prepareStatement("SELECT * FROM users", ["id"] as String[]).class == OpenTelemetryPreparedStatement
|
connection.prepareStatement(query, ["id"] as String[]).class == OpenTelemetryPreparedStatement
|
||||||
connection.prepareStatement("SELECT * FROM users", 0).class == OpenTelemetryPreparedStatement
|
connection.prepareStatement(query, 0).class == OpenTelemetryPreparedStatement
|
||||||
connection.prepareStatement("SELECT * FROM users", 0, 0).class == OpenTelemetryPreparedStatement
|
connection.prepareStatement(query, 0, 0).class == OpenTelemetryPreparedStatement
|
||||||
connection.prepareStatement("SELECT * FROM users", 0, 0, 0).class == OpenTelemetryPreparedStatement
|
connection.prepareStatement(query, 0, 0, 0).class == OpenTelemetryPreparedStatement
|
||||||
|
connection.prepareStatement(query).instrumenter == instr
|
||||||
}
|
}
|
||||||
|
|
||||||
def "verify prepare call"() {
|
def "verify prepare call"() {
|
||||||
setup:
|
setup:
|
||||||
|
def instr = createStatementInstrumenter(openTelemetry)
|
||||||
def dbInfo = getDbInfo()
|
def dbInfo = getDbInfo()
|
||||||
def connection = new OpenTelemetryConnection(new TestConnection(), dbInfo)
|
def connection = new OpenTelemetryConnection(new TestConnection(), dbInfo, instr)
|
||||||
String query = "SELECT * FROM users"
|
String query = "SELECT * FROM users"
|
||||||
def statement = connection.prepareCall(query)
|
def statement = connection.prepareCall(query)
|
||||||
runWithSpan("parent") {
|
runWithSpan("parent") {
|
||||||
|
@ -170,12 +184,16 @@ class OpenTelemetryConnectionTest extends InstrumentationSpecification implement
|
||||||
|
|
||||||
def "verify prepare call returns otel wrapper"() {
|
def "verify prepare call returns otel wrapper"() {
|
||||||
when:
|
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:
|
then:
|
||||||
connection.prepareCall("SELECT * FROM users").class == OpenTelemetryCallableStatement
|
connection.prepareCall(query).class == OpenTelemetryCallableStatement
|
||||||
connection.prepareCall("SELECT * FROM users", 0, 0).class == OpenTelemetryCallableStatement
|
connection.prepareCall(query, 0, 0).class == OpenTelemetryCallableStatement
|
||||||
connection.prepareCall("SELECT * FROM users", 0, 0, 0).class == OpenTelemetryCallableStatement
|
connection.prepareCall(query, 0, 0, 0).class == OpenTelemetryCallableStatement
|
||||||
|
connection.prepareCall(query).instrumenter == instr
|
||||||
}
|
}
|
||||||
|
|
||||||
private DbInfo getDbInfo() {
|
private DbInfo getDbInfo() {
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
package io.opentelemetry.instrumentation.jdbc.datasource
|
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 io.opentelemetry.instrumentation.jdbc.internal.OpenTelemetryConnection
|
||||||
import spock.lang.Specification
|
import spock.lang.Specification
|
||||||
|
|
||||||
|
@ -12,12 +14,14 @@ class OpenTelemetryDataSourceTest extends Specification {
|
||||||
|
|
||||||
def "verify get connection"() {
|
def "verify get connection"() {
|
||||||
when:
|
when:
|
||||||
def dataSource = new OpenTelemetryDataSource(new TestDataSource())
|
def ot = OpenTelemetry.propagating(ContextPropagators.noop())
|
||||||
|
def dataSource = new OpenTelemetryDataSource(new TestDataSource(), ot)
|
||||||
def connection = dataSource.getConnection()
|
def connection = dataSource.getConnection()
|
||||||
|
|
||||||
then:
|
then:
|
||||||
connection != null
|
connection != null
|
||||||
connection instanceof OpenTelemetryConnection
|
connection instanceof OpenTelemetryConnection
|
||||||
|
connection.statementInstrumenter != null
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def dbInfo = ((OpenTelemetryConnection) connection).dbInfo
|
def dbInfo = ((OpenTelemetryConnection) connection).dbInfo
|
||||||
|
@ -35,12 +39,14 @@ class OpenTelemetryDataSourceTest extends Specification {
|
||||||
|
|
||||||
def "verify get connection with username and password"() {
|
def "verify get connection with username and password"() {
|
||||||
when:
|
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)
|
def connection = dataSource.getConnection(null, null)
|
||||||
|
|
||||||
then:
|
then:
|
||||||
connection != null
|
connection != null
|
||||||
connection instanceof OpenTelemetryConnection
|
connection instanceof OpenTelemetryConnection
|
||||||
|
connection.statementInstrumenter != null
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def dbInfo = ((OpenTelemetryConnection) connection).dbInfo
|
def dbInfo = ((OpenTelemetryConnection) connection).dbInfo
|
||||||
|
@ -55,5 +61,4 @@ class OpenTelemetryDataSourceTest extends Specification {
|
||||||
dbInfo.host == "127.0.0.1"
|
dbInfo.host == "127.0.0.1"
|
||||||
dbInfo.port == 5432
|
dbInfo.port == 5432
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue