From 44444b4e75420809923050f6dcf76da07969cbf2 Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Tue, 12 Nov 2024 17:44:03 +0100 Subject: [PATCH 01/18] trace injection for prepared statements --- ...tractPreparedStatementInstrumentation.java | 5 +++ .../instrumentation/jdbc/JDBCDecorator.java | 39 +++++++++++++++++++ .../jdbc/StatementInstrumentation.java | 1 + 3 files changed, 45 insertions(+) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractPreparedStatementInstrumentation.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractPreparedStatementInstrumentation.java index 733d40c8793..e430b712364 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractPreparedStatementInstrumentation.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractPreparedStatementInstrumentation.java @@ -88,6 +88,11 @@ public static AgentScope onEnter(@Advice.This final Statement statement) { span.setTag(DBM_TRACE_INJECTED, true); } else { span = startSpan(DATABASE_QUERY); + // TODO: call setApplicationName only if postgres && inject comment && inject trace + // context && trace_prepared_statements + // if (DECORATE.isPostgres(dbInfo)) { + DECORATE.setApplicationName(span, connection); + // } } DECORATE.afterStart(span); DECORATE.onConnection(span, dbInfo); diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index d3dea36abe8..8108f650830 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -1,6 +1,7 @@ package datadog.trace.instrumentation.jdbc; import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; +import static datadog.trace.bootstrap.instrumentation.api.InstrumentationTags.DBM_TRACE_INJECTED; import static datadog.trace.bootstrap.instrumentation.api.Tags.*; import datadog.trace.api.Config; @@ -248,6 +249,10 @@ public String traceParent(AgentSpan span, int samplingPriority) { return sb.toString(); } + public boolean isPostgres(final DBInfo dbInfo) { + return "postgres".equals(dbInfo.getType()); + } + public boolean isSqlServer(final DBInfo dbInfo) { return "sqlserver".equals(dbInfo.getType()); } @@ -312,6 +317,40 @@ public long setContextInfo(Connection connection, DBInfo dbInfo) { return spanID; } + // TODO: add description + public void setApplicationName(AgentSpan span, Connection connection) { + // TODO: measure time spent in instrumentation and add it as a tag in span + try { + Integer priority = span.forceSamplingDecision(); + if (priority == null) { + return; + } + final String traceParent = DECORATE.traceParent(span, priority); + final String traceContext = "_DD_" + traceParent; + + // SET doesn't work with parameters + StringBuilder sql = new StringBuilder(); + sql.append("SET application_name = '"); + sql.append(traceContext); + sql.append("';"); + + try (Statement statement = connection.createStatement()) { + statement.execute(sql.toString()); + } catch (SQLException e) { + throw e; + } + } catch (Exception e) { + log.debug( + "Failed to set extra DBM data in application_name for trace {}. " + + "To disable this behavior, set trace_prepared_statements to 'false'. " + + "See https://docs.datadoghq.com/database_monitoring/connect_dbm_and_apm/ for more info.{}", + span.getTraceId().toHexString(), + e); + DECORATE.onError(span, e); + } + span.setTag(DBM_TRACE_INJECTED, true); + } + @Override protected void postProcessServiceAndOperationName( AgentSpan span, DatabaseClientDecorator.NamingEntry namingEntry) { diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java index 75f433f255c..832913af9df 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java @@ -103,6 +103,7 @@ public static AgentScope onEnter( if (span != null && INJECT_COMMENT) { String traceParent = null; + // TODO: don't propagate trace info in the comments for postgres if full+ mode is defined if (injectTraceContext) { Integer priority = span.forceSamplingDecision(); if (priority != null) { From 11adebc69580dabe0b99addcd7b322c7c7f257fd Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Thu, 14 Nov 2024 13:38:12 +0100 Subject: [PATCH 02/18] parmeter --- ...tractPreparedStatementInstrumentation.java | 25 +++++++++++-------- .../instrumentation/jdbc/JDBCDecorator.java | 4 ++- .../datadog/trace/api/ConfigDefaults.java | 1 + .../config/TraceInstrumentationConfig.java | 2 ++ .../main/java/datadog/trace/api/Config.java | 9 +++++++ 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractPreparedStatementInstrumentation.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractPreparedStatementInstrumentation.java index e430b712364..681b0800590 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractPreparedStatementInstrumentation.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/AbstractPreparedStatementInstrumentation.java @@ -5,6 +5,7 @@ import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.startSpan; import static datadog.trace.bootstrap.instrumentation.api.InstrumentationTags.DBM_TRACE_INJECTED; import static datadog.trace.instrumentation.jdbc.JDBCDecorator.DATABASE_QUERY; +import static datadog.trace.instrumentation.jdbc.JDBCDecorator.DBM_TRACE_PREPARED_STATEMENTS; import static datadog.trace.instrumentation.jdbc.JDBCDecorator.DECORATE; import static datadog.trace.instrumentation.jdbc.JDBCDecorator.INJECT_COMMENT; import static datadog.trace.instrumentation.jdbc.JDBCDecorator.logMissingQueryInfo; @@ -80,19 +81,21 @@ public static AgentScope onEnter(@Advice.This final Statement statement) { connection, InstrumentationContext.get(Connection.class, DBInfo.class)); final boolean injectTraceContext = DECORATE.shouldInjectTraceContext(dbInfo); - if (INJECT_COMMENT && injectTraceContext && DECORATE.isSqlServer(dbInfo)) { - // The span ID is pre-determined so that we can reference it when setting the context - final long spanID = DECORATE.setContextInfo(connection, dbInfo); - // we then force that pre-determined span ID for the span covering the actual query - span = AgentTracer.get().buildSpan(DATABASE_QUERY).withSpanId(spanID).start(); - span.setTag(DBM_TRACE_INJECTED, true); + if (INJECT_COMMENT && injectTraceContext) { + if (DECORATE.isSqlServer(dbInfo)) { + // The span ID is pre-determined so that we can reference it when setting the context + final long spanID = DECORATE.setContextInfo(connection, dbInfo); + // we then force that pre-determined span ID for the span covering the actual query + span = AgentTracer.get().buildSpan(DATABASE_QUERY).withSpanId(spanID).start(); + span.setTag(DBM_TRACE_INJECTED, true); + } else if (DECORATE.isPostgres(dbInfo) && DBM_TRACE_PREPARED_STATEMENTS) { + span = startSpan(DATABASE_QUERY); + DECORATE.setApplicationName(span, connection); + } else { + span = startSpan(DATABASE_QUERY); + } } else { span = startSpan(DATABASE_QUERY); - // TODO: call setApplicationName only if postgres && inject comment && inject trace - // context && trace_prepared_statements - // if (DECORATE.isPostgres(dbInfo)) { - DECORATE.setApplicationName(span, connection); - // } } DECORATE.afterStart(span); DECORATE.onConnection(span, dbInfo); diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index 8108f650830..1263e67bee3 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -54,6 +54,8 @@ public class JDBCDecorator extends DatabaseClientDecorator { || DBM_PROPAGATION_MODE.equals(DBM_PROPAGATION_MODE_STATIC); private static final boolean INJECT_TRACE_CONTEXT = DBM_PROPAGATION_MODE.equals(DBM_PROPAGATION_MODE_FULL); + public static final boolean DBM_TRACE_PREPARED_STATEMENTS = + Config.get().isDBMTracePreparedStatements(); private volatile boolean warnedAboutDBMPropagationMode = false; // to log a warning only once @@ -250,7 +252,7 @@ public String traceParent(AgentSpan span, int samplingPriority) { } public boolean isPostgres(final DBInfo dbInfo) { - return "postgres".equals(dbInfo.getType()); + return dbInfo.getType().startsWith("postgres"); } public boolean isSqlServer(final DBInfo dbInfo) { diff --git a/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java b/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java index 5319aa9a18f..0af701d2b61 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java @@ -69,6 +69,7 @@ public final class ConfigDefaults { static final boolean DEFAULT_DB_CLIENT_HOST_SPLIT_BY_INSTANCE_TYPE_SUFFIX = false; static final boolean DEFAULT_DB_CLIENT_HOST_SPLIT_BY_HOST = false; static final String DEFAULT_DB_DBM_PROPAGATION_MODE_MODE = "disabled"; + static final boolean DEFAULT_DB_DBM_TRACE_PREPARED_STATEMENTS = false; static final int DEFAULT_SCOPE_DEPTH_LIMIT = 100; static final int DEFAULT_SCOPE_ITERATION_KEEP_ALIVE = 30; // in seconds static final int DEFAULT_PARTIAL_FLUSH_MIN_SPANS = 1000; diff --git a/dd-trace-api/src/main/java/datadog/trace/api/config/TraceInstrumentationConfig.java b/dd-trace-api/src/main/java/datadog/trace/api/config/TraceInstrumentationConfig.java index 1936ab4fccd..0eae2793ea6 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/config/TraceInstrumentationConfig.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/config/TraceInstrumentationConfig.java @@ -68,6 +68,8 @@ public final class TraceInstrumentationConfig { public static final String DB_DBM_PROPAGATION_MODE_MODE = "dbm.propagation.mode"; + public static final String DB_DBM_TRACE_PREPARED_STATEMENTS = "dbm.trace_prepared_statements"; + public static final String JDBC_CONNECTION_CLASS_NAME = "trace.jdbc.connection.class.name"; public static final String HTTP_URL_CONNECTION_CLASS_NAME = diff --git a/internal-api/src/main/java/datadog/trace/api/Config.java b/internal-api/src/main/java/datadog/trace/api/Config.java index 6618a798569..058e21addad 100644 --- a/internal-api/src/main/java/datadog/trace/api/Config.java +++ b/internal-api/src/main/java/datadog/trace/api/Config.java @@ -372,6 +372,7 @@ public static String getHostName() { private final int remoteConfigMaxExtraServices; private final String DBMPropagationMode; + private final boolean DBMTracePreparedStatements; private final boolean debuggerEnabled; private final int debuggerUploadTimeout; @@ -844,6 +845,10 @@ private Config(final ConfigProvider configProvider, final InstrumenterConfig ins configProvider.getString( DB_DBM_PROPAGATION_MODE_MODE, DEFAULT_DB_DBM_PROPAGATION_MODE_MODE); + DBMTracePreparedStatements = + configProvider.getBoolean( + DB_DBM_TRACE_PREPARED_STATEMENTS, DEFAULT_DB_DBM_TRACE_PREPARED_STATEMENTS); + splitByTags = tryMakeImmutableSet(configProvider.getList(SPLIT_BY_TAGS)); springDataRepositoryInterfaceResourceName = @@ -3665,6 +3670,10 @@ public boolean isEnabled( Collections.singletonList(settingName), "", settingSuffix, defaultEnabled); } + public boolean isDBMTracePreparedStatements() { + return DBMTracePreparedStatements; + } + public String getDBMPropagationMode() { return DBMPropagationMode; } From 4b6f95308f895b58808d08e7f68bdd27bc84dde2 Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Thu, 14 Nov 2024 14:59:49 +0100 Subject: [PATCH 03/18] measure instrumentation time --- .../datadog/trace/instrumentation/jdbc/JDBCDecorator.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index 1263e67bee3..c2c27b6f140 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -321,8 +321,9 @@ public long setContextInfo(Connection connection, DBInfo dbInfo) { // TODO: add description public void setApplicationName(AgentSpan span, Connection connection) { - // TODO: measure time spent in instrumentation and add it as a tag in span + final long startTime = System.currentTimeMillis(); try { + Integer priority = span.forceSamplingDecision(); if (priority == null) { return; @@ -349,8 +350,11 @@ public void setApplicationName(AgentSpan span, Connection connection) { span.getTraceId().toHexString(), e); DECORATE.onError(span, e); + } finally { + span.setTag(DBM_TRACE_INJECTED, true); + final long elapsed = System.currentTimeMillis() - startTime; + span.setTag("dd.instrumentation.time_ms", elapsed); } - span.setTag(DBM_TRACE_INJECTED, true); } @Override From 7b88bcaa68c9eaf5ede476e836f988bd145a5753 Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Mon, 18 Nov 2024 14:30:40 +0100 Subject: [PATCH 04/18] test cases --- .../instrumentation/jdbc/JDBCDecorator.java | 10 +- .../jdbc/StatementInstrumentation.java | 1 - .../RemoteJDBCInstrumentationTest.groovy | 272 ++++++++++++------ 3 files changed, 191 insertions(+), 92 deletions(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index c2c27b6f140..d7ef8015b36 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -319,7 +319,15 @@ public long setContextInfo(Connection connection, DBInfo dbInfo) { return spanID; } - // TODO: add description + /** + * Executes `SET application_name` statement on the Postgres DB to set the trace parent in + * `pg_stat_activity.application_name`. This is used for prepared statements where it isn't + * possible to propagate trace parent with the comment. Downside: makes an additional round trip + * to the database. + * + * @param span The span of the instrumented statement + * @param connection The same connection as the one that will be used for the actual statement + */ public void setApplicationName(AgentSpan span, Connection connection) { final long startTime = System.currentTimeMillis(); try { diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java index 832913af9df..75f433f255c 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java @@ -103,7 +103,6 @@ public static AgentScope onEnter( if (span != null && INJECT_COMMENT) { String traceParent = null; - // TODO: don't propagate trace info in the comments for postgres if full+ mode is defined if (injectTraceContext) { Integer priority = span.forceSamplingDecision(); if (priority != null) { diff --git a/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy b/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy index a896ab2f33f..774785b9612 100644 --- a/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy @@ -28,6 +28,9 @@ import java.util.concurrent.TimeUnit import static datadog.trace.agent.test.utils.TraceUtils.basicSpan import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace import static datadog.trace.api.config.TraceInstrumentationConfig.DB_CLIENT_HOST_SPLIT_BY_INSTANCE +import static datadog.trace.api.config.TraceInstrumentationConfig.DB_DBM_PROPAGATION_MODE_MODE +import static datadog.trace.api.config.TraceInstrumentationConfig.DB_DBM_TRACE_PREPARED_STATEMENTS + // workaround for SSLHandShakeException on J9 only with Hikari/MySQL @Requires({ !System.getProperty("java.vendor").contains("IBM") }) @@ -207,6 +210,7 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { def "basic statement with #connection.getClass().getCanonicalName() on #driver generates spans"() { setup: injectSysConfig(DB_CLIENT_HOST_SPLIT_BY_INSTANCE, "$renameService") + injectSysConfig(DB_DBM_TRACE_PREPARED_STATEMENTS , "$tracePreparedStatements") when: Statement statement = connection.createStatement() @@ -317,23 +321,36 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { connection.close() where: - driver | connection | renameService | query | operation | obfuscatedQuery | usingHikari - MYSQL | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3" | "SELECT" | "SELECT ?" | false - POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false - SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3" | "SELECT" | "SELECT ?" | false - MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false - POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false - SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false - MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | true - POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | true - SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | true - MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false - POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false - SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false + driver | connection | renameService | query | operation | obfuscatedQuery | usingHikari | tracePreparedStatements + MYSQL | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | false + POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false | false + SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | false + MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | false + POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false | false + SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | false + MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | true | false + POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | true | false + SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | true | false + MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | false + POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false | false + SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | false + MYSQL | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | true + POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false | true + SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | true + MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | true + POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false | true + SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | true + MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | true | true + POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | true | true + SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | true | true + MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | true + POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false | true + SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | true } def "prepared statement execute on #driver with #connection.getClass().getCanonicalName() generates a span"() { setup: + injectSysConfig(DB_DBM_TRACE_PREPARED_STATEMENTS , "$tracePreparedStatements") PreparedStatement statement = connection.prepareStatement(query) when: @@ -443,23 +460,37 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { connection.close() where: - driver | connection | query | operation | obfuscatedQuery | usingHikari - MYSQL | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false - POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false - SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false - MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false - POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false - SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false - MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true - POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true - SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true - MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false - POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false - SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false + driver | connection | query | operation | obfuscatedQuery | usingHikari | tracePreparedStatements + MYSQL | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false | false + POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false | false + SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false | false + MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false | false + POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false | false + SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false | false + MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true | false + POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true | false + SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true | false + MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false | false + POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false | false + SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false | false + MYSQL | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false | true + POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false | true + SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false | true + MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false | true + POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false | true + SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false | true + MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true | true + POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true | true + SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true | true + MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false | true + POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false | true + SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false | true + } def "prepared statement query on #driver with #connection.getClass().getCanonicalName() generates a span"() { setup: + injectSysConfig(DB_DBM_TRACE_PREPARED_STATEMENTS , "$tracePreparedStatements") PreparedStatement statement = connection.prepareStatement(query) when: ResultSet resultSet = runUnderTrace("parent") { @@ -568,23 +599,36 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { connection.close() where: - driver | conPoolType | connection | query | operation | obfuscatedQuery - MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" - POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" - SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" - MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" - POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" - SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" - MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" - POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" - SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" - MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" - POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" - SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" + driver | conPoolType | connection | query | operation | obfuscatedQuery | tracePreparedStatements + MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false + POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false + SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false + MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false + POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false + SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false + MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false + POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false + SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false + MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false + POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false + SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false + MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | true + POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true + SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | true + MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true + POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true + SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true + MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true + POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true + SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true + MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true + POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true + SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true } def "prepared call on #driver with #connection.getClass().getCanonicalName() generates a span"() { setup: + injectSysConfig(DB_DBM_TRACE_PREPARED_STATEMENTS , "$tracePreparedStatements") CallableStatement statement = connection.prepareCall(query) when: ResultSet resultSet = runUnderTrace("parent") { @@ -687,23 +731,37 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { connection.close() where: - driver | conPoolType | connection | query | operation | obfuscatedQuery - MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" - POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" - SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" - MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" - POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" - SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" - MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" - POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" - SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" - MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" - POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" - SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" + driver | conPoolType | connection | query | operation | obfuscatedQuery | tracePreparedStatements + MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false + POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false + SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false + MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false + POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false + SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false + MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false + POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false + SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false + MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false + POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false + SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false + MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | true + POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true + SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | true + MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true + POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true + SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true + MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true + POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true + SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true + MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true + POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true + SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true + } def "statement update on #driver with #connection.getClass().getCanonicalName() generates a span"() { setup: + injectSysConfig(DB_DBM_TRACE_PREPARED_STATEMENTS , "$tracePreparedStatements") Statement statement = connection.createStatement() def sql = connection.nativeSQL(query) @@ -819,25 +877,39 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { connection.close() where: - driver | conPoolType | connection | query | operation - MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TEMPORARY TABLE s_test_ (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" - POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TEMPORARY TABLE s_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" - SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TABLE #s_test_ (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" - MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" - POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" - SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" - MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" - POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" - SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" - MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" - POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" - SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" + driver | conPoolType | connection | query | operation | tracePreparedStatements + MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TEMPORARY TABLE s_test_ (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false + POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TEMPORARY TABLE s_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false + SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TABLE #s_test_ (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false + MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false + POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false + SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false + MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false + POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false + SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false + MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false + POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false + SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false + MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TEMPORARY TABLE s_test_ (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true + POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TEMPORARY TABLE s_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true + SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TABLE #s_test_ (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true + MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true + POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true + SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true + MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true + POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true + SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true + MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true + POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true + SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true + } def "prepared procedure call with return value on #driver with #connection.getClass().getCanonicalName() does not hang"() { setup: - injectSysConfig("dd.dbm.propagation.mode", "full") + injectSysConfig(DB_DBM_PROPAGATION_MODE_MODE, "full") + injectSysConfig(DB_DBM_TRACE_PREPARED_STATEMENTS, "$tracePreparedStatements") CallableStatement upperProc = connection.prepareCall(query) upperProc.registerOutParameter(1, Types.VARCHAR) @@ -855,15 +927,23 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { connection.close() where: - driver | connection | query - POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "{ ? = call upper( ? ) }" - MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "{ ? = call upper( ? ) }" - POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{ ? = call upper( ? ) }" - MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{ ? = call upper( ? ) }" - POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "{ ? = call upper( ? ) }" - MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "{ ? = call upper( ? ) }" - POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "{ ? = call upper( ? ) }" - MYSQL | connectTo(driver, peerConnectionProps(driver)) | "{ ? = call upper( ? ) }" + driver | connection | query | tracePreparedStatements + POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "{ ? = call upper( ? ) }" | false + MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "{ ? = call upper( ? ) }" | false + POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{ ? = call upper( ? ) }" | false + MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{ ? = call upper( ? ) }" | false + POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "{ ? = call upper( ? ) }" | false + MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "{ ? = call upper( ? ) }" | false + POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "{ ? = call upper( ? ) }" | false + MYSQL | connectTo(driver, peerConnectionProps(driver)) | "{ ? = call upper( ? ) }" | false + POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "{ ? = call upper( ? ) }" | true + MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "{ ? = call upper( ? ) }" | true + POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{ ? = call upper( ? ) }" | true + MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{ ? = call upper( ? ) }" | true + POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "{ ? = call upper( ? ) }" | true + MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "{ ? = call upper( ? ) }" | true + POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "{ ? = call upper( ? ) }" | true + MYSQL | connectTo(driver, peerConnectionProps(driver)) | "{ ? = call upper( ? ) }" | true } def "prepared procedure call on #driver with #connection.getClass().getCanonicalName() does not hang"() { @@ -910,7 +990,7 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { connection.prepareCall(createSql).execute() } catch (SQLServerException ex) {} - injectSysConfig("dd.dbm.propagation.mode", "full") + injectSysConfig(DB_DBM_PROPAGATION_MODE_MODE, "full") CallableStatement proc = connection.prepareCall(query) proc.setInt(1,1) proc.registerOutParameter(1, Types.INTEGER) @@ -930,19 +1010,31 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { connection.close() where: - driver | connection | query - POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "CALL dummy(?)" - MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "CALL dummy(?)" - SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | "{CALL dummy(?)}" - POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "CALL dummy(?)" - MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{CALL dummy(?)}" - SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | "{CALL dummy(?)}" - POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "CALL dummy(?)" - MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "CALL dummy(?)" - SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | "{CALL dummy(?)}" - POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "CALL dummy(?)" - MYSQL | connectTo(driver, peerConnectionProps(driver)) | "CALL dummy(?)" - SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | "{CALL dummy(?)}" + driver | connection | query | tracePreparedStatements + POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "CALL dummy(?)" | false + MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "CALL dummy(?)" | false + SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | "{CALL dummy(?)}" | false + POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "CALL dummy(?)" | false + MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{CALL dummy(?)}" | false + SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | "{CALL dummy(?)}" | false + POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "CALL dummy(?)" | false + MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "CALL dummy(?)" | false + SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | "{CALL dummy(?)}" | false + POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "CALL dummy(?)" | false + MYSQL | connectTo(driver, peerConnectionProps(driver)) | "CALL dummy(?)" | false + SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | "{CALL dummy(?)}" | false + POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "CALL dummy(?)" | true + MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "CALL dummy(?)" | true + SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | "{CALL dummy(?)}" | true + POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "CALL dummy(?)" | true + MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{CALL dummy(?)}" | true + SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | "{CALL dummy(?)}" | true + POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "CALL dummy(?)" | true + MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "CALL dummy(?)" | true + SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | "{CALL dummy(?)}" | true + POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "CALL dummy(?)" | true + MYSQL | connectTo(driver, peerConnectionProps(driver)) | "CALL dummy(?)" | true + SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | "{CALL dummy(?)}" | true } @@ -1038,7 +1130,7 @@ class RemoteDBMTraceInjectedForkedTest extends RemoteJDBCInstrumentationTest { @Override void configurePreAgent() { super.configurePreAgent() - injectSysConfig("dd.dbm.propagation.mode", "full") + injectSysConfig(DB_DBM_PROPAGATION_MODE_MODE, "full") } @Override From 320d497379bf471464199367fb633da37cee740d Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Tue, 19 Nov 2024 18:14:51 +0100 Subject: [PATCH 05/18] test cases --- .../RemoteJDBCInstrumentationTest.groovy | 63 ------------------- 1 file changed, 63 deletions(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy b/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy index 774785b9612..5aedda6434f 100644 --- a/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy @@ -337,15 +337,6 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { MYSQL | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | true POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false | true SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | true - MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | true - POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false | true - SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | true - MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | true | true - POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | true | true - SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | true | true - MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | true - POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false | true - SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | true } def "prepared statement execute on #driver with #connection.getClass().getCanonicalName() generates a span"() { @@ -476,16 +467,6 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { MYSQL | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false | true POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false | true SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false | true - MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false | true - POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false | true - SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false | true - MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true | true - POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true | true - SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true | true - MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false | true - POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false | true - SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false | true - } def "prepared statement query on #driver with #connection.getClass().getCanonicalName() generates a span"() { @@ -615,15 +596,6 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | true POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | true - MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true - POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true - SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true - MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true - POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true - SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true - MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true - POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true - SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true } def "prepared call on #driver with #connection.getClass().getCanonicalName() generates a span"() { @@ -747,16 +719,6 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | true POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | true - MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true - POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true - SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true - MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true - POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true - SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true - MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true - POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true - SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true - } def "statement update on #driver with #connection.getClass().getCanonicalName() generates a span"() { @@ -893,16 +855,6 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TEMPORARY TABLE s_test_ (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TEMPORARY TABLE s_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TABLE #s_test_ (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true - MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true - POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true - SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true - MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true - POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true - SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true - MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true - POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true - SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true - } @@ -936,12 +888,6 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "{ ? = call upper( ? ) }" | false POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "{ ? = call upper( ? ) }" | false MYSQL | connectTo(driver, peerConnectionProps(driver)) | "{ ? = call upper( ? ) }" | false - POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "{ ? = call upper( ? ) }" | true - MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "{ ? = call upper( ? ) }" | true - POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{ ? = call upper( ? ) }" | true - MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{ ? = call upper( ? ) }" | true - POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "{ ? = call upper( ? ) }" | true - MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "{ ? = call upper( ? ) }" | true POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "{ ? = call upper( ? ) }" | true MYSQL | connectTo(driver, peerConnectionProps(driver)) | "{ ? = call upper( ? ) }" | true } @@ -1023,15 +969,6 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "CALL dummy(?)" | false MYSQL | connectTo(driver, peerConnectionProps(driver)) | "CALL dummy(?)" | false SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | "{CALL dummy(?)}" | false - POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "CALL dummy(?)" | true - MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "CALL dummy(?)" | true - SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | "{CALL dummy(?)}" | true - POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "CALL dummy(?)" | true - MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{CALL dummy(?)}" | true - SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | "{CALL dummy(?)}" | true - POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "CALL dummy(?)" | true - MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "CALL dummy(?)" | true - SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | "{CALL dummy(?)}" | true POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "CALL dummy(?)" | true MYSQL | connectTo(driver, peerConnectionProps(driver)) | "CALL dummy(?)" | true SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | "{CALL dummy(?)}" | true From 75cdbd72e7d675bc935788a702c7019c4e4b17eb Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Tue, 19 Nov 2024 18:25:15 +0100 Subject: [PATCH 06/18] restored remote tests --- .../RemoteJDBCInstrumentationTest.groovy | 209 ++++++++---------- 1 file changed, 90 insertions(+), 119 deletions(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy b/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy index 5aedda6434f..a896ab2f33f 100644 --- a/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy @@ -28,9 +28,6 @@ import java.util.concurrent.TimeUnit import static datadog.trace.agent.test.utils.TraceUtils.basicSpan import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace import static datadog.trace.api.config.TraceInstrumentationConfig.DB_CLIENT_HOST_SPLIT_BY_INSTANCE -import static datadog.trace.api.config.TraceInstrumentationConfig.DB_DBM_PROPAGATION_MODE_MODE -import static datadog.trace.api.config.TraceInstrumentationConfig.DB_DBM_TRACE_PREPARED_STATEMENTS - // workaround for SSLHandShakeException on J9 only with Hikari/MySQL @Requires({ !System.getProperty("java.vendor").contains("IBM") }) @@ -210,7 +207,6 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { def "basic statement with #connection.getClass().getCanonicalName() on #driver generates spans"() { setup: injectSysConfig(DB_CLIENT_HOST_SPLIT_BY_INSTANCE, "$renameService") - injectSysConfig(DB_DBM_TRACE_PREPARED_STATEMENTS , "$tracePreparedStatements") when: Statement statement = connection.createStatement() @@ -321,27 +317,23 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { connection.close() where: - driver | connection | renameService | query | operation | obfuscatedQuery | usingHikari | tracePreparedStatements - MYSQL | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | false - POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false | false - SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | false - MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | false - POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false | false - SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | false - MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | true | false - POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | true | false - SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | true | false - MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | false - POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false | false - SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | false - MYSQL | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | true - POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false | true - SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3" | "SELECT" | "SELECT ?" | false | true + driver | connection | renameService | query | operation | obfuscatedQuery | usingHikari + MYSQL | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3" | "SELECT" | "SELECT ?" | false + POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false + SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | false | "SELECT 3" | "SELECT" | "SELECT ?" | false + MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false + POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false + SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false + MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | true + POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | true + SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | true + MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false + POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3 FROM pg_user" | "SELECT" | "SELECT ? FROM pg_user" | false + SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | false | "SELECT 3" | "SELECT" | "SELECT ?" | false } def "prepared statement execute on #driver with #connection.getClass().getCanonicalName() generates a span"() { setup: - injectSysConfig(DB_DBM_TRACE_PREPARED_STATEMENTS , "$tracePreparedStatements") PreparedStatement statement = connection.prepareStatement(query) when: @@ -451,27 +443,23 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { connection.close() where: - driver | connection | query | operation | obfuscatedQuery | usingHikari | tracePreparedStatements - MYSQL | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false | false - POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false | false - SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false | false - MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false | false - POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false | false - SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false | false - MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true | false - POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true | false - SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true | false - MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false | false - POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false | false - SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false | false - MYSQL | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false | true - POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false | true - SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false | true + driver | connection | query | operation | obfuscatedQuery | usingHikari + MYSQL | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false + POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false + SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false + MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false + POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false + SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false + MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true + POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true + SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | true + MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false + POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false + SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false } def "prepared statement query on #driver with #connection.getClass().getCanonicalName() generates a span"() { setup: - injectSysConfig(DB_DBM_TRACE_PREPARED_STATEMENTS , "$tracePreparedStatements") PreparedStatement statement = connection.prepareStatement(query) when: ResultSet resultSet = runUnderTrace("parent") { @@ -580,27 +568,23 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { connection.close() where: - driver | conPoolType | connection | query | operation | obfuscatedQuery | tracePreparedStatements - MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false - POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false - SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false - MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false - POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false - SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false - MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false - POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false - SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false - MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false - POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false - SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false - MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | true - POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true - SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | true + driver | conPoolType | connection | query | operation | obfuscatedQuery + MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" + POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" + SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" + MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" + POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" + SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" + MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" + POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" + SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" + MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" + POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" + SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" } def "prepared call on #driver with #connection.getClass().getCanonicalName() generates a span"() { setup: - injectSysConfig(DB_DBM_TRACE_PREPARED_STATEMENTS , "$tracePreparedStatements") CallableStatement statement = connection.prepareCall(query) when: ResultSet resultSet = runUnderTrace("parent") { @@ -703,27 +687,23 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { connection.close() where: - driver | conPoolType | connection | query | operation | obfuscatedQuery | tracePreparedStatements - MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false - POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false - SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | false - MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false - POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false - SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false - MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false - POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false - SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false - MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false - POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | false - SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" | false - MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | true - POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" | true - SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" | true + driver | conPoolType | connection | query | operation | obfuscatedQuery + MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" + POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" + SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "SELECT 3" | "SELECT" | "SELECT ?" + MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" + POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" + SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" + MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" + POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" + SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" + MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" + POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3 from pg_user" | "SELECT" | "SELECT ? from pg_user" + SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "SELECT 3" | "SELECT" | "SELECT ?" } def "statement update on #driver with #connection.getClass().getCanonicalName() generates a span"() { setup: - injectSysConfig(DB_DBM_TRACE_PREPARED_STATEMENTS , "$tracePreparedStatements") Statement statement = connection.createStatement() def sql = connection.nativeSQL(query) @@ -839,29 +819,25 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { connection.close() where: - driver | conPoolType | connection | query | operation | tracePreparedStatements - MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TEMPORARY TABLE s_test_ (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false - POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TEMPORARY TABLE s_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false - SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TABLE #s_test_ (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false - MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false - POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false - SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false - MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false - POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false - SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false - MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false - POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false - SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | false - MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TEMPORARY TABLE s_test_ (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true - POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TEMPORARY TABLE s_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true - SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TABLE #s_test_ (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" | true + driver | conPoolType | connection | query | operation + MYSQL | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TEMPORARY TABLE s_test_ (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" + POSTGRESQL | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TEMPORARY TABLE s_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" + SQLSERVER | "" | connectTo(driver, peerConnectionProps(driver)) | "CREATE TABLE #s_test_ (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" + MYSQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" + POSTGRESQL | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" + SQLSERVER | "tomcat" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_tomcat_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" + MYSQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" + POSTGRESQL | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" + SQLSERVER | "hikari" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_hikari_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" + MYSQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" + POSTGRESQL | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TEMPORARY TABLE s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" + SQLSERVER | "c3p0" | cpDatasources.get(conPoolType).get(driver).getConnection() | "CREATE TABLE #s_c3p0_test (id INTEGER not NULL, PRIMARY KEY ( id ))" | "CREATE" } def "prepared procedure call with return value on #driver with #connection.getClass().getCanonicalName() does not hang"() { setup: - injectSysConfig(DB_DBM_PROPAGATION_MODE_MODE, "full") - injectSysConfig(DB_DBM_TRACE_PREPARED_STATEMENTS, "$tracePreparedStatements") + injectSysConfig("dd.dbm.propagation.mode", "full") CallableStatement upperProc = connection.prepareCall(query) upperProc.registerOutParameter(1, Types.VARCHAR) @@ -879,17 +855,15 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { connection.close() where: - driver | connection | query | tracePreparedStatements - POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "{ ? = call upper( ? ) }" | false - MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "{ ? = call upper( ? ) }" | false - POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{ ? = call upper( ? ) }" | false - MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{ ? = call upper( ? ) }" | false - POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "{ ? = call upper( ? ) }" | false - MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "{ ? = call upper( ? ) }" | false - POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "{ ? = call upper( ? ) }" | false - MYSQL | connectTo(driver, peerConnectionProps(driver)) | "{ ? = call upper( ? ) }" | false - POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "{ ? = call upper( ? ) }" | true - MYSQL | connectTo(driver, peerConnectionProps(driver)) | "{ ? = call upper( ? ) }" | true + driver | connection | query + POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "{ ? = call upper( ? ) }" + MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "{ ? = call upper( ? ) }" + POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{ ? = call upper( ? ) }" + MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{ ? = call upper( ? ) }" + POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "{ ? = call upper( ? ) }" + MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "{ ? = call upper( ? ) }" + POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "{ ? = call upper( ? ) }" + MYSQL | connectTo(driver, peerConnectionProps(driver)) | "{ ? = call upper( ? ) }" } def "prepared procedure call on #driver with #connection.getClass().getCanonicalName() does not hang"() { @@ -936,7 +910,7 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { connection.prepareCall(createSql).execute() } catch (SQLServerException ex) {} - injectSysConfig(DB_DBM_PROPAGATION_MODE_MODE, "full") + injectSysConfig("dd.dbm.propagation.mode", "full") CallableStatement proc = connection.prepareCall(query) proc.setInt(1,1) proc.registerOutParameter(1, Types.INTEGER) @@ -956,22 +930,19 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { connection.close() where: - driver | connection | query | tracePreparedStatements - POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "CALL dummy(?)" | false - MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "CALL dummy(?)" | false - SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | "{CALL dummy(?)}" | false - POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "CALL dummy(?)" | false - MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{CALL dummy(?)}" | false - SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | "{CALL dummy(?)}" | false - POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "CALL dummy(?)" | false - MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "CALL dummy(?)" | false - SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | "{CALL dummy(?)}" | false - POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "CALL dummy(?)" | false - MYSQL | connectTo(driver, peerConnectionProps(driver)) | "CALL dummy(?)" | false - SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | "{CALL dummy(?)}" | false - POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "CALL dummy(?)" | true - MYSQL | connectTo(driver, peerConnectionProps(driver)) | "CALL dummy(?)" | true - SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | "{CALL dummy(?)}" | true + driver | connection | query + POSTGRESQL | cpDatasources.get("hikari").get(driver).getConnection() | "CALL dummy(?)" + MYSQL | cpDatasources.get("hikari").get(driver).getConnection() | "CALL dummy(?)" + SQLSERVER | cpDatasources.get("hikari").get(driver).getConnection() | "{CALL dummy(?)}" + POSTGRESQL | cpDatasources.get("tomcat").get(driver).getConnection() | "CALL dummy(?)" + MYSQL | cpDatasources.get("tomcat").get(driver).getConnection() | "{CALL dummy(?)}" + SQLSERVER | cpDatasources.get("tomcat").get(driver).getConnection() | "{CALL dummy(?)}" + POSTGRESQL | cpDatasources.get("c3p0").get(driver).getConnection() | "CALL dummy(?)" + MYSQL | cpDatasources.get("c3p0").get(driver).getConnection() | "CALL dummy(?)" + SQLSERVER | cpDatasources.get("c3p0").get(driver).getConnection() | "{CALL dummy(?)}" + POSTGRESQL | connectTo(driver, peerConnectionProps(driver)) | "CALL dummy(?)" + MYSQL | connectTo(driver, peerConnectionProps(driver)) | "CALL dummy(?)" + SQLSERVER | connectTo(driver, peerConnectionProps(driver)) | "{CALL dummy(?)}" } @@ -1067,7 +1038,7 @@ class RemoteDBMTraceInjectedForkedTest extends RemoteJDBCInstrumentationTest { @Override void configurePreAgent() { super.configurePreAgent() - injectSysConfig(DB_DBM_PROPAGATION_MODE_MODE, "full") + injectSysConfig("dd.dbm.propagation.mode", "full") } @Override From 049ce78212329efdf42fd8ac4b7ed6eca809de4d Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Tue, 19 Nov 2024 19:15:01 +0100 Subject: [PATCH 07/18] check concatenated string --- .../datadog/trace/instrumentation/jdbc/JDBCDecorator.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index d7ef8015b36..cde56cb060a 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -337,6 +337,10 @@ public void setApplicationName(AgentSpan span, Connection connection) { return; } final String traceParent = DECORATE.traceParent(span, priority); + if (traceParent == null + || !traceParent.matches("^00-[a-f0-9]{32}-[a-f0-9]{16}-[a-f0-9]{2}$")) { + throw new IllegalArgumentException("Invalid trace parent: " + traceParent); + } final String traceContext = "_DD_" + traceParent; // SET doesn't work with parameters From 2a4532840a497641263e46dda7c5e58e0ee67f0c Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Tue, 19 Nov 2024 19:23:06 +0100 Subject: [PATCH 08/18] SpotBugs annotation --- .../datadog/trace/instrumentation/jdbc/JDBCDecorator.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index cde56cb060a..31bd9ce9ac4 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -19,6 +19,7 @@ import datadog.trace.bootstrap.instrumentation.jdbc.DBInfo; import datadog.trace.bootstrap.instrumentation.jdbc.DBQueryInfo; import datadog.trace.bootstrap.instrumentation.jdbc.JDBCConnectionUrlParser; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.sql.Connection; @@ -328,6 +329,9 @@ public long setContextInfo(Connection connection, DBInfo dbInfo) { * @param span The span of the instrumented statement * @param connection The same connection as the one that will be used for the actual statement */ + @SuppressFBWarnings( + value = "SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE", + justification = "Prepared statement not possible with SET") public void setApplicationName(AgentSpan span, Connection connection) { final long startTime = System.currentTimeMillis(); try { From f2f7b8f01c0e713c36425a7ea45f71d916490e9b Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Wed, 20 Nov 2024 15:14:38 +0100 Subject: [PATCH 09/18] new test cases --- .../RemoteJDBCInstrumentationTest.groovy | 199 ++++++++++++------ .../api/InstrumentationTags.java | 1 + 2 files changed, 131 insertions(+), 69 deletions(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy b/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy index a896ab2f33f..16d7930341f 100644 --- a/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy @@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit import static datadog.trace.agent.test.utils.TraceUtils.basicSpan import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace import static datadog.trace.api.config.TraceInstrumentationConfig.DB_CLIENT_HOST_SPLIT_BY_INSTANCE +import static datadog.trace.api.config.TraceInstrumentationConfig.DB_DBM_TRACE_PREPARED_STATEMENTS // workaround for SSLHandShakeException on J9 only with Hikari/MySQL @Requires({ !System.getProperty("java.vendor").contains("IBM") }) @@ -347,9 +348,9 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { resultSet.next() resultSet.getInt(1) == 3 def addDbmTag = dbmTraceInjected() - if (driver == POSTGRESQL || driver == MYSQL || !addDbmTag) { + if (driver == SQLSERVER && addDbmTag){ assertTraces(1) { - trace(2) { + trace(3) { basicSpan(it, "parent") span { operationName this.operation(this.getDbType(driver)) @@ -364,72 +365,76 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { "$Tags.SPAN_KIND" Tags.SPAN_KIND_CLIENT "$Tags.DB_TYPE" this.getDbType(driver) "$Tags.DB_INSTANCE" dbName.get(driver).toLowerCase() - // only set when there is an out of proc instance (postgresql, mysql) "$Tags.PEER_HOSTNAME" String - // currently there is a bug in the instrumentation with - // postgresql and mysql if the connection event is missed - // since Connection.getClientInfo will not provide the username "$Tags.DB_USER" { it == null || it == jdbcUserNames.get(driver) } "$Tags.DB_OPERATION" operation if (usingHikari) { "$Tags.DB_POOL_NAME" String } + if (addDbmTag) { + "$InstrumentationTags.DBM_TRACE_INJECTED" true + } peerServiceFrom(Tags.DB_INSTANCE) defaultTags() } } - } - } - } else { - assertTraces(1) { - trace(3) { - basicSpan(it, "parent") span { - operationName this.operation(this.getDbType(driver)) serviceName service(driver) - resourceName obfuscatedQuery + operationName this.operation(this.getDbType(driver)) + resourceName "set context_info ?" spanType DDSpanTypes.SQL childOf span(0) errored false measured true tags { - "$Tags.COMPONENT" "java-jdbc-prepared_statement" + "$Tags.COMPONENT" "java-jdbc-statement" "$Tags.SPAN_KIND" Tags.SPAN_KIND_CLIENT "$Tags.DB_TYPE" this.getDbType(driver) "$Tags.DB_INSTANCE" dbName.get(driver).toLowerCase() "$Tags.PEER_HOSTNAME" String "$Tags.DB_USER" { it == null || it == jdbcUserNames.get(driver) } - "$Tags.DB_OPERATION" operation + "$Tags.DB_OPERATION" "set" if (usingHikari) { "$Tags.DB_POOL_NAME" String } - if (addDbmTag) { - "$InstrumentationTags.DBM_TRACE_INJECTED" true - } + "dd.instrumentation" true peerServiceFrom(Tags.DB_INSTANCE) defaultTags() } } + } + } + } else { + assertTraces(1) { + trace(2) { + basicSpan(it, "parent") span { - serviceName service(driver) operationName this.operation(this.getDbType(driver)) - resourceName "set context_info ?" + serviceName service(driver) + resourceName obfuscatedQuery spanType DDSpanTypes.SQL childOf span(0) errored false measured true tags { - "$Tags.COMPONENT" "java-jdbc-statement" + "$Tags.COMPONENT" "java-jdbc-prepared_statement" "$Tags.SPAN_KIND" Tags.SPAN_KIND_CLIENT "$Tags.DB_TYPE" this.getDbType(driver) "$Tags.DB_INSTANCE" dbName.get(driver).toLowerCase() + // only set when there is an out of proc instance (postgresql, mysql) "$Tags.PEER_HOSTNAME" String + // currently there is a bug in the instrumentation with + // postgresql and mysql if the connection event is missed + // since Connection.getClientInfo will not provide the username "$Tags.DB_USER" { it == null || it == jdbcUserNames.get(driver) } - "$Tags.DB_OPERATION" "set" + "$Tags.DB_OPERATION" operation if (usingHikari) { "$Tags.DB_POOL_NAME" String } - "dd.instrumentation" true + if (this.dbmTracePreparedStatements(driver)){ + "$InstrumentationTags.DBM_TRACE_INJECTED" true + "$InstrumentationTags.TIME_MS" Long + } peerServiceFrom(Tags.DB_INSTANCE) defaultTags() } @@ -470,9 +475,11 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { then: resultSet.next() resultSet.getInt(1) == 3 - if (driver == POSTGRESQL || driver == MYSQL || !dbmTraceInjected()) { + + def addDbmTag = dbmTraceInjected() + if (driver == SQLSERVER && addDbmTag){ assertTraces(1) { - trace(2) { + trace(3) { basicSpan(it, "parent") span { operationName this.operation(this.getDbType(driver)) @@ -497,64 +504,68 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { if (conPoolType == "hikari") { "$Tags.DB_POOL_NAME" String } + "$InstrumentationTags.DBM_TRACE_INJECTED" true peerServiceFrom(Tags.DB_INSTANCE) defaultTags() } } - } - } - } else { - assertTraces(1) { - trace(3) { - basicSpan(it, "parent") span { - operationName this.operation(this.getDbType(driver)) serviceName service(driver) - resourceName obfuscatedQuery + operationName this.operation(this.getDbType(driver)) + resourceName "set context_info ?" spanType DDSpanTypes.SQL childOf span(0) errored false measured true tags { - "$Tags.COMPONENT" "java-jdbc-prepared_statement" + "$Tags.COMPONENT" "java-jdbc-statement" "$Tags.SPAN_KIND" Tags.SPAN_KIND_CLIENT "$Tags.DB_TYPE" this.getDbType(driver) "$Tags.DB_INSTANCE" dbName.get(driver).toLowerCase() - // only set when there is an out of proc instance (postgresql, mysql) "$Tags.PEER_HOSTNAME" String - // currently there is a bug in the instrumentation with - // postgresql and mysql if the connection event is missed - // since Connection.getClientInfo will not provide the username "$Tags.DB_USER" { it == null || it == jdbcUserNames.get(driver) } - "$Tags.DB_OPERATION" operation + "$Tags.DB_OPERATION" "set" if (conPoolType == "hikari") { "$Tags.DB_POOL_NAME" String } - "$InstrumentationTags.DBM_TRACE_INJECTED" true + "dd.instrumentation" true peerServiceFrom(Tags.DB_INSTANCE) defaultTags() } } + } + } + } else { + assertTraces(1) { + trace(2) { + basicSpan(it, "parent") span { - serviceName service(driver) operationName this.operation(this.getDbType(driver)) - resourceName "set context_info ?" + serviceName service(driver) + resourceName obfuscatedQuery spanType DDSpanTypes.SQL childOf span(0) errored false measured true tags { - "$Tags.COMPONENT" "java-jdbc-statement" + "$Tags.COMPONENT" "java-jdbc-prepared_statement" "$Tags.SPAN_KIND" Tags.SPAN_KIND_CLIENT "$Tags.DB_TYPE" this.getDbType(driver) "$Tags.DB_INSTANCE" dbName.get(driver).toLowerCase() + // only set when there is an out of proc instance (postgresql, mysql) "$Tags.PEER_HOSTNAME" String + // currently there is a bug in the instrumentation with + // postgresql and mysql if the connection event is missed + // since Connection.getClientInfo will not provide the username "$Tags.DB_USER" { it == null || it == jdbcUserNames.get(driver) } - "$Tags.DB_OPERATION" "set" + "$Tags.DB_OPERATION" operation if (conPoolType == "hikari") { "$Tags.DB_POOL_NAME" String } - "dd.instrumentation" true + if (this.dbmTracePreparedStatements(driver)){ + "$InstrumentationTags.DBM_TRACE_INJECTED" true + "$InstrumentationTags.TIME_MS" Long + } peerServiceFrom(Tags.DB_INSTANCE) defaultTags() } @@ -595,9 +606,10 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { then: resultSet.next() resultSet.getInt(1) == 3 - if (driver == POSTGRESQL || driver == MYSQL || !dbmTraceInjected()) { + def addDbmTag = dbmTraceInjected() + if (driver == SQLSERVER && addDbmTag){ assertTraces(1) { - trace(2) { + trace(3) { basicSpan(it, "parent") span { operationName this.operation(this.getDbType(driver)) @@ -612,69 +624,73 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { "$Tags.SPAN_KIND" Tags.SPAN_KIND_CLIENT "$Tags.DB_TYPE" this.getDbType(driver) "$Tags.DB_INSTANCE" dbName.get(driver).toLowerCase() - // only set when there is an out of proc instance (postgresql, mysql) "$Tags.PEER_HOSTNAME" String - // currently there is a bug in the instrumentation with - // postgresql and mysql if the connection event is missed - // since Connection.getClientInfo will not provide the username "$Tags.DB_USER" { it == null || it == jdbcUserNames.get(driver) } "${Tags.DB_OPERATION}" operation if (conPoolType == "hikari") { "$Tags.DB_POOL_NAME" String } + "$InstrumentationTags.DBM_TRACE_INJECTED" true defaultTags() } } - } - } - } else { - assertTraces(1) { - trace(3) { - basicSpan(it, "parent") span { - operationName this.operation(this.getDbType(driver)) serviceName service(driver) - resourceName obfuscatedQuery + operationName this.operation(this.getDbType(driver)) + resourceName "set context_info ?" spanType DDSpanTypes.SQL childOf span(0) errored false measured true tags { - "$Tags.COMPONENT" "java-jdbc-prepared_statement" + "$Tags.COMPONENT" "java-jdbc-statement" "$Tags.SPAN_KIND" Tags.SPAN_KIND_CLIENT "$Tags.DB_TYPE" this.getDbType(driver) "$Tags.DB_INSTANCE" dbName.get(driver).toLowerCase() "$Tags.PEER_HOSTNAME" String "$Tags.DB_USER" { it == null || it == jdbcUserNames.get(driver) } - "${Tags.DB_OPERATION}" operation + "$Tags.DB_OPERATION" "set" + "dd.instrumentation" true if (conPoolType == "hikari") { "$Tags.DB_POOL_NAME" String } - "$InstrumentationTags.DBM_TRACE_INJECTED" true + peerServiceFrom(Tags.DB_INSTANCE) defaultTags() } } + } + } + } else { + assertTraces(1) { + trace(2) { + basicSpan(it, "parent") span { - serviceName service(driver) operationName this.operation(this.getDbType(driver)) - resourceName "set context_info ?" + serviceName service(driver) + resourceName obfuscatedQuery spanType DDSpanTypes.SQL childOf span(0) errored false measured true tags { - "$Tags.COMPONENT" "java-jdbc-statement" + "$Tags.COMPONENT" "java-jdbc-prepared_statement" "$Tags.SPAN_KIND" Tags.SPAN_KIND_CLIENT "$Tags.DB_TYPE" this.getDbType(driver) "$Tags.DB_INSTANCE" dbName.get(driver).toLowerCase() + // only set when there is an out of proc instance (postgresql, mysql) "$Tags.PEER_HOSTNAME" String + // currently there is a bug in the instrumentation with + // postgresql and mysql if the connection event is missed + // since Connection.getClientInfo will not provide the username "$Tags.DB_USER" { it == null || it == jdbcUserNames.get(driver) } - "$Tags.DB_OPERATION" "set" - "dd.instrumentation" true + "${Tags.DB_OPERATION}" operation if (conPoolType == "hikari") { "$Tags.DB_POOL_NAME" String } - peerServiceFrom(Tags.DB_INSTANCE) + if (this.dbmTracePreparedStatements(driver)){ + "$InstrumentationTags.DBM_TRACE_INJECTED" true + "$InstrumentationTags.TIME_MS" Long + } defaultTags() } } @@ -979,6 +995,10 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { protected abstract String operation(String dbType) protected abstract boolean dbmTraceInjected() + + protected boolean dbmTracePreparedStatements(String dbType){ + return false + } } class RemoteJDBCInstrumentationV0Test extends RemoteJDBCInstrumentationTest { @@ -1067,3 +1087,44 @@ class RemoteDBMTraceInjectedForkedTest extends RemoteJDBCInstrumentationTest { return databaseNaming.normalizedName(dbType) } } + +class RemoteDBMTraceInjectedForkedTestTracePreparedStatements extends RemoteJDBCInstrumentationTest { + + @Override + void configurePreAgent() { + super.configurePreAgent() + injectSysConfig("dd.dbm.propagation.mode", "full") + injectSysConfig(DB_DBM_TRACE_PREPARED_STATEMENTS, "true") + } + + @Override + protected boolean dbmTraceInjected() { + return true + } + + @Override + int version() { + return 1 + } + + @Override + protected String service(String dbType) { + return Config.get().getServiceName() + } + + @Override + protected String operation(String dbType) { + return "${dbType}.query" + } + + @Override + protected String getDbType(String dbType) { + final databaseNaming = new DatabaseNamingV1() + return databaseNaming.normalizedName(dbType) + } + + @Override + protected boolean dbmTracePreparedStatements(String dbType){ + return dbType == POSTGRESQL + } +} diff --git a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/InstrumentationTags.java b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/InstrumentationTags.java index 430f74924da..f9de6c088e2 100644 --- a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/InstrumentationTags.java +++ b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/InstrumentationTags.java @@ -107,6 +107,7 @@ public class InstrumentationTags { public static final String TWILIO_STATUS = "twilio.status"; public static final String TWILIO_PARENT_SID = "twilio.parentSid"; public static final String DBM_TRACE_INJECTED = "_dd.dbm_trace_injected"; + public static final String TIME_MS = "dd.instrumentation.time_ms"; public static final UTF8BytesString DD_MEASURED = UTF8BytesString.create("_dd.measured"); public static final UTF8BytesString DD_TOP_LEVEL = UTF8BytesString.create("_dd.top_level"); public static final UTF8BytesString DD_PARTIAL_VERSION = From 5d235a030060e76aad50432302f8c0a5d7a86be8 Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Tue, 3 Dec 2024 07:18:27 +0100 Subject: [PATCH 10/18] renamed TIME_MS to INSTRUMENTATION_TIME_MS --- .../src/test/groovy/RemoteJDBCInstrumentationTest.groovy | 6 +++--- .../bootstrap/instrumentation/api/InstrumentationTags.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy b/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy index 16d7930341f..3f6c4ac2ecc 100644 --- a/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy +++ b/dd-java-agent/instrumentation/jdbc/src/test/groovy/RemoteJDBCInstrumentationTest.groovy @@ -433,7 +433,7 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { } if (this.dbmTracePreparedStatements(driver)){ "$InstrumentationTags.DBM_TRACE_INJECTED" true - "$InstrumentationTags.TIME_MS" Long + "$InstrumentationTags.INSTRUMENTATION_TIME_MS" Long } peerServiceFrom(Tags.DB_INSTANCE) defaultTags() @@ -564,7 +564,7 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { } if (this.dbmTracePreparedStatements(driver)){ "$InstrumentationTags.DBM_TRACE_INJECTED" true - "$InstrumentationTags.TIME_MS" Long + "$InstrumentationTags.INSTRUMENTATION_TIME_MS" Long } peerServiceFrom(Tags.DB_INSTANCE) defaultTags() @@ -689,7 +689,7 @@ abstract class RemoteJDBCInstrumentationTest extends VersionedNamingTestBase { } if (this.dbmTracePreparedStatements(driver)){ "$InstrumentationTags.DBM_TRACE_INJECTED" true - "$InstrumentationTags.TIME_MS" Long + "$InstrumentationTags.INSTRUMENTATION_TIME_MS" Long } defaultTags() } diff --git a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/InstrumentationTags.java b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/InstrumentationTags.java index f9de6c088e2..35a64b112f3 100644 --- a/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/InstrumentationTags.java +++ b/internal-api/src/main/java/datadog/trace/bootstrap/instrumentation/api/InstrumentationTags.java @@ -107,7 +107,7 @@ public class InstrumentationTags { public static final String TWILIO_STATUS = "twilio.status"; public static final String TWILIO_PARENT_SID = "twilio.parentSid"; public static final String DBM_TRACE_INJECTED = "_dd.dbm_trace_injected"; - public static final String TIME_MS = "dd.instrumentation.time_ms"; + public static final String INSTRUMENTATION_TIME_MS = "_dd.instrumentation.time_ms"; public static final UTF8BytesString DD_MEASURED = UTF8BytesString.create("_dd.measured"); public static final UTF8BytesString DD_TOP_LEVEL = UTF8BytesString.create("_dd.top_level"); public static final UTF8BytesString DD_PARTIAL_VERSION = From cd9550f263964b9105f33b36712cc43eee787eb1 Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Tue, 3 Dec 2024 07:32:35 +0100 Subject: [PATCH 11/18] compile regex --- .../datadog/trace/instrumentation/jdbc/JDBCDecorator.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index 31bd9ce9ac4..df2749a5e3a 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -2,6 +2,7 @@ import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan; import static datadog.trace.bootstrap.instrumentation.api.InstrumentationTags.DBM_TRACE_INJECTED; +import static datadog.trace.bootstrap.instrumentation.api.InstrumentationTags.INSTRUMENTATION_TIME_MS; import static datadog.trace.bootstrap.instrumentation.api.Tags.*; import datadog.trace.api.Config; @@ -29,6 +30,7 @@ import java.sql.Statement; import java.util.HashSet; import java.util.Set; +import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -341,8 +343,8 @@ public void setApplicationName(AgentSpan span, Connection connection) { return; } final String traceParent = DECORATE.traceParent(span, priority); - if (traceParent == null - || !traceParent.matches("^00-[a-f0-9]{32}-[a-f0-9]{16}-[a-f0-9]{2}$")) { + final Pattern pattern = Pattern.compile("^00-[a-f0-9]{32}-[a-f0-9]{16}-[a-f0-9]{2}$"); + if (traceParent == null || !pattern.matcher(traceParent).matches()) { throw new IllegalArgumentException("Invalid trace parent: " + traceParent); } final String traceContext = "_DD_" + traceParent; @@ -369,7 +371,7 @@ public void setApplicationName(AgentSpan span, Connection connection) { } finally { span.setTag(DBM_TRACE_INJECTED, true); final long elapsed = System.currentTimeMillis() - startTime; - span.setTag("dd.instrumentation.time_ms", elapsed); + span.setTag(INSTRUMENTATION_TIME_MS, elapsed); } } From 94fa6731b208c512b11348335d2311ff075d3cc6 Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Tue, 3 Dec 2024 07:34:53 +0100 Subject: [PATCH 12/18] catch Throwable --- .../java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index df2749a5e3a..16efbad0df9 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -360,7 +360,7 @@ public void setApplicationName(AgentSpan span, Connection connection) { } catch (SQLException e) { throw e; } - } catch (Exception e) { + } catch (Throwable e) { log.debug( "Failed to set extra DBM data in application_name for trace {}. " + "To disable this behavior, set trace_prepared_statements to 'false'. " From faa95415474c2aa71a6fc02845e5359b4fd53f60 Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Tue, 3 Dec 2024 09:56:23 +0100 Subject: [PATCH 13/18] fix sized StringBuilder --- .../trace/instrumentation/jdbc/JDBCDecorator.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index 16efbad0df9..a9c27c029d9 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -350,10 +350,14 @@ public void setApplicationName(AgentSpan span, Connection connection) { final String traceContext = "_DD_" + traceParent; // SET doesn't work with parameters - StringBuilder sql = new StringBuilder(); - sql.append("SET application_name = '"); + final String setCommandBegin = "SET application_name = '"; + final String setCommandEnd = "';"; + StringBuilder sql = + new StringBuilder( + setCommandBegin.length() + traceContext.length() + setCommandEnd.length()); + sql.append(setCommandBegin); sql.append(traceContext); - sql.append("';"); + sql.append(setCommandEnd); try (Statement statement = connection.createStatement()) { statement.execute(sql.toString()); From f552f64d440be0252d7ca24e7a35a6ebea29a24c Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:29:14 +0100 Subject: [PATCH 14/18] removed inner catch --- .../java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index a9c27c029d9..534114b20a6 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -361,8 +361,6 @@ public void setApplicationName(AgentSpan span, Connection connection) { try (Statement statement = connection.createStatement()) { statement.execute(sql.toString()); - } catch (SQLException e) { - throw e; } } catch (Throwable e) { log.debug( From 75cf7e53b7ef4a635f31e5940d016b8e264aba74 Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Tue, 3 Dec 2024 15:24:39 +0100 Subject: [PATCH 15/18] pattern as class variable --- .../datadog/trace/instrumentation/jdbc/JDBCDecorator.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index 534114b20a6..bef29e9cf1b 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -50,6 +50,8 @@ public class JDBCDecorator extends DatabaseClientDecorator { SpanNaming.instance().namingSchema().database().service("jdbc"); public static final String DBM_PROPAGATION_MODE_STATIC = "service"; public static final String DBM_PROPAGATION_MODE_FULL = "full"; + private static final Pattern traceParentPattern = + Pattern.compile("^00-[a-f0-9]{32}-[a-f0-9]{16}-[a-f0-9]{2}$"); public static final String DBM_PROPAGATION_MODE = Config.get().getDBMPropagationMode(); public static final boolean INJECT_COMMENT = @@ -343,8 +345,7 @@ public void setApplicationName(AgentSpan span, Connection connection) { return; } final String traceParent = DECORATE.traceParent(span, priority); - final Pattern pattern = Pattern.compile("^00-[a-f0-9]{32}-[a-f0-9]{16}-[a-f0-9]{2}$"); - if (traceParent == null || !pattern.matcher(traceParent).matches()) { + if (traceParent == null || !traceParentPattern.matcher(traceParent).matches()) { throw new IllegalArgumentException("Invalid trace parent: " + traceParent); } final String traceContext = "_DD_" + traceParent; From ba6fa89762573814c1bee7ddf99939644f707829 Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Tue, 3 Dec 2024 15:49:50 +0100 Subject: [PATCH 16/18] Update dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Raphaƫl Vandon --- .../trace/instrumentation/jdbc/JDBCDecorator.java | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index bef29e9cf1b..81355e79460 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -351,17 +351,8 @@ public void setApplicationName(AgentSpan span, Connection connection) { final String traceContext = "_DD_" + traceParent; // SET doesn't work with parameters - final String setCommandBegin = "SET application_name = '"; - final String setCommandEnd = "';"; - StringBuilder sql = - new StringBuilder( - setCommandBegin.length() + traceContext.length() + setCommandEnd.length()); - sql.append(setCommandBegin); - sql.append(traceContext); - sql.append(setCommandEnd); - try (Statement statement = connection.createStatement()) { - statement.execute(sql.toString()); + statement.execute("SET application_name = '" + traceContext + "';"); } } catch (Throwable e) { log.debug( From f159cd93cb9f54c91f8c08af20cca57a72fe48e2 Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Thu, 12 Dec 2024 11:39:49 +0100 Subject: [PATCH 17/18] log only if isDebugEnabled --- .../trace/instrumentation/jdbc/JDBCDecorator.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index ed4857cebdb..0cfe5e7f87f 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -355,12 +355,14 @@ public void setApplicationName(AgentSpan span, Connection connection) { statement.execute("SET application_name = '" + traceContext + "';"); } } catch (Throwable e) { - log.debug( - "Failed to set extra DBM data in application_name for trace {}. " - + "To disable this behavior, set trace_prepared_statements to 'false'. " - + "See https://docs.datadoghq.com/database_monitoring/connect_dbm_and_apm/ for more info.{}", - span.getTraceId().toHexString(), - e); + if (log.isDebugEnabled()) { + log.debug( + "Failed to set extra DBM data in application_name for trace {}. " + + "To disable this behavior, set trace_prepared_statements to 'false'. " + + "See https://docs.datadoghq.com/database_monitoring/connect_dbm_and_apm/ for more info.{}", + span.getTraceId().toHexString(), + e); + } DECORATE.onError(span, e); } finally { span.setTag(DBM_TRACE_INJECTED, true); From 98f01640f3d3bba144befa3bd2d00aa29fe59620 Mon Sep 17 00:00:00 2001 From: Nenad Noveljic <18366081+nenadnoveljic@users.noreply.github.com> Date: Thu, 12 Dec 2024 14:07:13 +0100 Subject: [PATCH 18/18] switched to setClientInfo --- .../trace/instrumentation/jdbc/JDBCDecorator.java | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java index 0cfe5e7f87f..ea2b18e48f3 100644 --- a/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java +++ b/dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java @@ -20,7 +20,6 @@ import datadog.trace.bootstrap.instrumentation.jdbc.DBInfo; import datadog.trace.bootstrap.instrumentation.jdbc.DBQueryInfo; import datadog.trace.bootstrap.instrumentation.jdbc.JDBCConnectionUrlParser; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.sql.Connection; @@ -30,7 +29,6 @@ import java.sql.Statement; import java.util.HashSet; import java.util.Set; -import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,8 +48,6 @@ public class JDBCDecorator extends DatabaseClientDecorator { SpanNaming.instance().namingSchema().database().service("jdbc"); public static final String DBM_PROPAGATION_MODE_STATIC = "service"; public static final String DBM_PROPAGATION_MODE_FULL = "full"; - private static final Pattern traceParentPattern = - Pattern.compile("^00-[a-f0-9]{32}-[a-f0-9]{16}-[a-f0-9]{2}$"); public static final String DBM_PROPAGATION_MODE = Config.get().getDBMPropagationMode(); public static final boolean INJECT_COMMENT = @@ -333,9 +329,6 @@ public long setContextInfo(Connection connection, DBInfo dbInfo) { * @param span The span of the instrumented statement * @param connection The same connection as the one that will be used for the actual statement */ - @SuppressFBWarnings( - value = "SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE", - justification = "Prepared statement not possible with SET") public void setApplicationName(AgentSpan span, Connection connection) { final long startTime = System.currentTimeMillis(); try { @@ -345,15 +338,9 @@ public void setApplicationName(AgentSpan span, Connection connection) { return; } final String traceParent = DECORATE.traceParent(span, priority); - if (traceParent == null || !traceParentPattern.matcher(traceParent).matches()) { - throw new IllegalArgumentException("Invalid trace parent: " + traceParent); - } final String traceContext = "_DD_" + traceParent; - // SET doesn't work with parameters - try (Statement statement = connection.createStatement()) { - statement.execute("SET application_name = '" + traceContext + "';"); - } + connection.setClientInfo("ApplicationName", traceContext); } catch (Throwable e) { if (log.isDebugEnabled()) { log.debug(