Skip to content

Commit 29ed9f5

Browse files
authored
Add option to JDBC instrumentation to always append DBM comment (#9798)
* Add option to JDBC instrumentation to always append DBM comment DBMON-5791 * document the newly added DBM environment variable * flip order of comment append condition in JDBC instrumentation * use static final variable to decide if we should append SQL comment * reformat code to be spotless * fix typo in the newly added environment variable
1 parent dc6264e commit 29ed9f5

File tree

9 files changed

+76
-11
lines changed

9 files changed

+76
-11
lines changed

dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/DBMCompatibleConnectionInstrumentation.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,9 @@ public static String onEnter(
126126
dbService =
127127
traceConfig(activeSpan()).getServiceMapping().getOrDefault(dbService, dbService);
128128
}
129-
boolean append = "sqlserver".equals(dbInfo.getType());
129+
130+
boolean append =
131+
DECORATE.DBM_ALWAYS_APPEND_SQL_COMMENT || "sqlserver".equals(dbInfo.getType());
130132
sql =
131133
SQLCommenter.inject(
132134
sql, dbService, dbInfo.getType(), dbInfo.getHost(), dbInfo.getDb(), null, append);

dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/JDBCDecorator.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ public class JDBCDecorator extends DatabaseClientDecorator<DBInfo> {
5959
DBM_PROPAGATION_MODE.equals(DBM_PROPAGATION_MODE_FULL);
6060
public static final boolean DBM_TRACE_PREPARED_STATEMENTS =
6161
Config.get().isDbmTracePreparedStatements();
62+
public static final boolean DBM_ALWAYS_APPEND_SQL_COMMENT =
63+
Config.get().isDbmAlwaysAppendSqlComment();
6264

6365
private volatile boolean warnedAboutDBMPropagationMode = false; // to log a warning only once
6466

dd-java-agent/instrumentation/jdbc/src/main/java/datadog/trace/instrumentation/jdbc/StatementInstrumentation.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,15 @@ public static AgentScope onEnter(
127127
final boolean injectTraceInComment = injectTraceContext && !isSqlServer && !isOracle;
128128

129129
// prepend mode will prepend the SQL comment to the raw sql query
130-
boolean appendComment = false;
130+
boolean appendComment = DECORATE.DBM_ALWAYS_APPEND_SQL_COMMENT;
131131

132132
// There is a bug in the SQL Server JDBC driver that prevents
133133
// the generated keys from being returned when the
134134
// SQL comment is prepended to the SQL query.
135135
// We only append in this case to avoid the comment from being truncated.
136136
// @see https://github.com/microsoft/mssql-jdbc/issues/2729
137137
if (isSqlServer
138+
&& !appendComment
138139
&& args.length == 2
139140
&& args[1] instanceof Integer
140141
&& (Integer) args[1] == Statement.RETURN_GENERATED_KEYS) {

dd-java-agent/instrumentation/jdbc/src/test/groovy/DBMInjectionForkedTest.groovy

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import test.TestConnection
55
import test.TestPreparedStatement
66
import test.TestStatement
77

8-
class DBMInjectionForkedTest extends InstrumentationSpecification {
9-
8+
abstract class InjectionTest extends InstrumentationSpecification {
109
@Override
1110
void configurePreAgent() {
1211
super.configurePreAgent()
@@ -21,8 +20,9 @@ class DBMInjectionForkedTest extends InstrumentationSpecification {
2120

2221
static query = "SELECT 1"
2322
static serviceInjection = "ddps='my_service_name',dddbs='remapped_testdb',ddh='localhost'"
24-
static fullInjection = serviceInjection + ",traceparent='00-00000000000000000000000000000004-0000000000000003-01'"
23+
}
2524

25+
class DBMInjectionForkedTest extends InjectionTest {
2626
def "prepared stmt"() {
2727
setup:
2828
def connection = new TestConnection(false)
@@ -45,6 +45,35 @@ class DBMInjectionForkedTest extends InstrumentationSpecification {
4545
statement.executeQuery(query)
4646

4747
then:
48-
assert statement.sql == "/*${fullInjection}*/ ${query}"
48+
assert statement.sql == "/*${serviceInjection},traceparent='00-00000000000000000000000000000004-0000000000000003-01'*/ ${query}"
49+
}
50+
}
51+
52+
class DBMAppendInjectionForkedTest extends InjectionTest {
53+
def "append comment on prepared stmt"() {
54+
setup:
55+
injectSysConfig(TraceInstrumentationConfig.DB_DBM_ALWAYS_APPEND_SQL_COMMENT, "true")
56+
def connection = new TestConnection(false)
57+
58+
when:
59+
def statement = connection.prepareStatement(query) as TestPreparedStatement
60+
statement.execute()
61+
62+
then:
63+
// even in full propagation mode, we cannot inject trace info in prepared statements
64+
assert statement.sql == "${query} /*${serviceInjection}*/"
65+
}
66+
67+
def "append comment on single query"() {
68+
setup:
69+
injectSysConfig(TraceInstrumentationConfig.DB_DBM_ALWAYS_APPEND_SQL_COMMENT, "true")
70+
def connection = new TestConnection(false)
71+
72+
when:
73+
def statement = connection.createStatement() as TestStatement
74+
statement.executeQuery(query)
75+
76+
then:
77+
assert statement.sql == "${query} /*${serviceInjection},traceparent='00-00000000000000000000000000000004-0000000000000003-01'*/"
4978
}
5079
}

dd-java-agent/instrumentation/jdbc/src/test/groovy/SQLServerInjectionForkedTest.groovy

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
2-
31
import datadog.trace.agent.test.InstrumentationSpecification
42
import datadog.trace.api.config.TraceInstrumentationConfig
53
import test.TestConnection
64
import test.TestDatabaseMetaData
75
import test.TestStatement
86

9-
class SQLServerInjectionForkedTest extends InstrumentationSpecification {
10-
7+
abstract class InjectionForkedTest extends InstrumentationSpecification {
118
@Override
129
void configurePreAgent() {
1310
super.configurePreAgent()
@@ -18,7 +15,9 @@ class SQLServerInjectionForkedTest extends InstrumentationSpecification {
1815

1916
static query = "SELECT 1"
2017
static serviceInjection = "ddps='my_service_name',dddbs='sqlserver',ddh='localhost',dddb='testdb'"
18+
}
2119

20+
class SQLServerInjectionForkedTest extends InjectionForkedTest {
2221
def "SQL Server no trace injection with full propagation mode"() {
2322
setup:
2423
def connection = new TestConnection(false)
@@ -37,7 +36,7 @@ class SQLServerInjectionForkedTest extends InstrumentationSpecification {
3736
assert !statement.sql.contains("traceparent")
3837
}
3938

40-
def "SQL Server apend comment when getting generated keys"() {
39+
def "SQL Server append comment when getting generated keys"() {
4140
setup:
4241
def connection = new TestConnection(false)
4342
def metadata = new TestDatabaseMetaData()
@@ -52,3 +51,21 @@ class SQLServerInjectionForkedTest extends InstrumentationSpecification {
5251
assert statement.sql == "${query} /*${serviceInjection}*/"
5352
}
5453
}
54+
55+
class SQLServerAppendInjectionForkedTest extends InjectionForkedTest {
56+
def "SQL Server append comment when configured to do so"() {
57+
setup:
58+
injectSysConfig(TraceInstrumentationConfig.DB_DBM_ALWAYS_APPEND_SQL_COMMENT, "true")
59+
def connection = new TestConnection(false)
60+
def metadata = new TestDatabaseMetaData()
61+
metadata.setURL("jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=testdb;")
62+
connection.setMetaData(metadata)
63+
64+
when:
65+
def statement = connection.createStatement() as TestStatement
66+
statement.executeUpdate(query)
67+
68+
then:
69+
assert statement.sql == "${query} /*${serviceInjection}*/"
70+
}
71+
}

dd-trace-api/src/main/java/datadog/trace/api/ConfigDefaults.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public final class ConfigDefaults {
7272
static final boolean DEFAULT_DB_CLIENT_HOST_SPLIT_BY_HOST = false;
7373
static final String DEFAULT_DB_DBM_PROPAGATION_MODE_MODE = "disabled";
7474
static final boolean DEFAULT_DB_DBM_TRACE_PREPARED_STATEMENTS = false;
75+
static final boolean DEFAULT_DB_DBM_ALWAYS_APPEND_SQL_COMMENT = false;
7576
// Default value is set to 0, it disables the latency trace interceptor
7677
static final int DEFAULT_TRACE_KEEP_LATENCY_THRESHOLD_MS = 0;
7778
static final int DEFAULT_SCOPE_DEPTH_LIMIT = 100;

dd-trace-api/src/main/java/datadog/trace/api/config/TraceInstrumentationConfig.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public final class TraceInstrumentationConfig {
6969
public static final String DB_DBM_INJECT_SQL_BASEHASH = "dbm.inject.sql.basehash";
7070
public static final String DB_DBM_PROPAGATION_MODE_MODE = "dbm.propagation.mode";
7171
public static final String DB_DBM_TRACE_PREPARED_STATEMENTS = "dbm.trace_prepared_statements";
72+
public static final String DB_DBM_ALWAYS_APPEND_SQL_COMMENT = "dbm.always_append_sql_comment";
7273

7374
public static final String JDBC_CONNECTION_CLASS_NAME = "trace.jdbc.connection.class.name";
7475

internal-api/src/main/java/datadog/trace/api/Config.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import static datadog.trace.api.ConfigDefaults.DEFAULT_DB_CLIENT_HOST_SPLIT_BY_HOST;
5656
import static datadog.trace.api.ConfigDefaults.DEFAULT_DB_CLIENT_HOST_SPLIT_BY_INSTANCE;
5757
import static datadog.trace.api.ConfigDefaults.DEFAULT_DB_CLIENT_HOST_SPLIT_BY_INSTANCE_TYPE_SUFFIX;
58+
import static datadog.trace.api.ConfigDefaults.DEFAULT_DB_DBM_ALWAYS_APPEND_SQL_COMMENT;
5859
import static datadog.trace.api.ConfigDefaults.DEFAULT_DB_DBM_PROPAGATION_MODE_MODE;
5960
import static datadog.trace.api.ConfigDefaults.DEFAULT_DB_DBM_TRACE_PREPARED_STATEMENTS;
6061
import static datadog.trace.api.ConfigDefaults.DEFAULT_DEBUGGER_EXCEPTION_CAPTURE_INTERMEDIATE_SPANS_ENABLED;
@@ -508,6 +509,7 @@
508509
import static datadog.trace.api.config.TraceInstrumentationConfig.DB_CLIENT_HOST_SPLIT_BY_HOST;
509510
import static datadog.trace.api.config.TraceInstrumentationConfig.DB_CLIENT_HOST_SPLIT_BY_INSTANCE;
510511
import static datadog.trace.api.config.TraceInstrumentationConfig.DB_CLIENT_HOST_SPLIT_BY_INSTANCE_TYPE_SUFFIX;
512+
import static datadog.trace.api.config.TraceInstrumentationConfig.DB_DBM_ALWAYS_APPEND_SQL_COMMENT;
511513
import static datadog.trace.api.config.TraceInstrumentationConfig.DB_DBM_INJECT_SQL_BASEHASH;
512514
import static datadog.trace.api.config.TraceInstrumentationConfig.DB_DBM_PROPAGATION_MODE_MODE;
513515
import static datadog.trace.api.config.TraceInstrumentationConfig.DB_DBM_TRACE_PREPARED_STATEMENTS;
@@ -1076,6 +1078,7 @@ public static String getHostName() {
10761078
private final boolean dbmInjectSqlBaseHash;
10771079
private final String dbmPropagationMode;
10781080
private final boolean dbmTracePreparedStatements;
1081+
private final boolean dbmAlwaysAppendSqlComment;
10791082

10801083
private final boolean dynamicInstrumentationEnabled;
10811084
private final String dynamicInstrumentationSnapshotUrl;
@@ -1639,6 +1642,10 @@ private Config(final ConfigProvider configProvider, final InstrumenterConfig ins
16391642
configProvider.getBoolean(
16401643
DB_DBM_TRACE_PREPARED_STATEMENTS, DEFAULT_DB_DBM_TRACE_PREPARED_STATEMENTS);
16411644

1645+
dbmAlwaysAppendSqlComment =
1646+
configProvider.getBoolean(
1647+
DB_DBM_ALWAYS_APPEND_SQL_COMMENT, DEFAULT_DB_DBM_ALWAYS_APPEND_SQL_COMMENT);
1648+
16421649
dbmInjectSqlBaseHash = configProvider.getBoolean(DB_DBM_INJECT_SQL_BASEHASH, false);
16431650

16441651
splitByTags = tryMakeImmutableSet(configProvider.getList(SPLIT_BY_TAGS));
@@ -5042,6 +5049,10 @@ public boolean isDbmTracePreparedStatements() {
50425049
return dbmTracePreparedStatements;
50435050
}
50445051

5052+
public boolean isDbmAlwaysAppendSqlComment() {
5053+
return dbmAlwaysAppendSqlComment;
5054+
}
5055+
50455056
public String getDbmPropagationMode() {
50465057
return dbmPropagationMode;
50475058
}

metadata/supported-configurations.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@
139139
"DD_DATA_STREAMS_BUCKET_DURATION_SECONDS": ["A"],
140140
"DD_DATA_STREAMS_ENABLED": ["A"],
141141
"DD_DBM_INJECT_SQL_BASEHASH": ["A"],
142+
"DD_DBM_ALWAYS_APPEND_SQL_COMMENT": ["A"],
142143
"DD_DBM_PROPAGATION_MODE": ["A"],
143144
"DD_DBM_TRACE_PREPARED_STATEMENTS": ["A"],
144145
"DD_DISTRIBUTED_DEBUGGER_ENABLED": ["A"],

0 commit comments

Comments
 (0)