Skip to content

Commit aeb7876

Browse files
authored
Merge pull request #6763 from brentm5/bm-set-optional-couchbase-internal-spans
Add option to not include couchbase internal spans
2 parents 938c791 + 3ff5ce4 commit aeb7876

File tree

7 files changed

+124
-125
lines changed

7 files changed

+124
-125
lines changed

dd-java-agent/instrumentation/couchbase/couchbase-3.1/src/main/java/datadog/trace/instrumentation/couchbase_31/client/DatadogRequestTracer.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package datadog.trace.instrumentation.couchbase_31.client;
22

3+
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.blackholeSpan;
34
import static datadog.trace.instrumentation.couchbase_31.client.CouchbaseClientDecorator.COUCHBASE_CLIENT;
45

56
import com.couchbase.client.core.Core;
67
import com.couchbase.client.core.cnc.RequestSpan;
78
import com.couchbase.client.core.cnc.RequestTracer;
9+
import datadog.trace.api.Config;
810
import datadog.trace.bootstrap.ContextStore;
911
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
1012
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
@@ -37,7 +39,12 @@ public RequestSpan requestSpan(String requestName, RequestSpan requestParent) {
3739
if (null == parent) {
3840
parent = tracer.activeSpan();
3941
}
42+
4043
if (null != parent && COUCHBASE_CLIENT.equals(parent.getTag(Tags.COMPONENT))) {
44+
if (!Config.get().isCouchbaseInternalSpansEnabled()) {
45+
// mute the tracing related to internal spans
46+
return DatadogRequestSpan.wrap(blackholeSpan(), coreContext);
47+
}
4148
spanName = COUCHBASE_INTERNAL;
4249
measured = false;
4350
seedNodes = parent.getTag(InstrumentationTags.COUCHBASE_SEED_NODES);

dd-java-agent/instrumentation/couchbase/couchbase-3.1/src/test/groovy/CouchbaseClient31Test.groovy

Lines changed: 36 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import com.couchbase.client.core.env.TimeoutConfig
2-
import com.couchbase.client.core.error.CouchbaseException
32
import com.couchbase.client.core.error.DocumentNotFoundException
43
import com.couchbase.client.core.error.ParsingFailureException
54
import com.couchbase.client.java.Bucket
@@ -107,8 +106,9 @@ abstract class CouchbaseClient31Test extends VersionedNamingTestBase {
107106
}
108107
}
109108

110-
def "check basic error spans"() {
109+
def "check basic error spans with internal spans enabled #internalEnabled"() {
111110
setup:
111+
injectSysConfig("trace.couchbase.internal-spans.enabled", "$internalEnabled")
112112
def collection = bucket.defaultCollection()
113113
Throwable ex = null
114114

@@ -122,7 +122,7 @@ abstract class CouchbaseClient31Test extends VersionedNamingTestBase {
122122
then:
123123
assertTraces(1) {
124124
sortSpansByStart()
125-
trace(2) {
125+
trace(internalEnabled ? 2 : 1) {
126126
assertCouchbaseCall(it, "cb.get", [
127127
'db.couchbase.collection': '_default',
128128
'db.couchbase.retries' : { Long },
@@ -131,9 +131,15 @@ abstract class CouchbaseClient31Test extends VersionedNamingTestBase {
131131
'db.name' : BUCKET,
132132
'db.operation' : 'get',
133133
], false, ex)
134-
assertCouchbaseDispatchCall(it, span(0))
134+
if (internalEnabled) {
135+
assertCouchbaseDispatchCall(it, span(0))
136+
}
135137
}
136138
}
139+
where:
140+
internalEnabled | _
141+
true | _
142+
false | _
137143
}
138144

139145
def "check query spans"() {
@@ -218,9 +224,11 @@ abstract class CouchbaseClient31Test extends VersionedNamingTestBase {
218224
adhoc << [true, false]
219225
}
220226

221-
def "check multiple query spans with parent and adhoc false"() {
222-
def query = 'select count(1) from `test-bucket` where (`something` = "wonderful") limit 1'
223-
def normalizedQuery = 'select count(?) from `test-bucket` where (`something` = "wonderful") limit ?'
227+
def "check multiple query spans with parent and adhoc false and internal spans enabled = #internalEnabled"() {
228+
setup:
229+
injectSysConfig("trace.couchbase.internal-spans.enabled", "$internalEnabled")
230+
def query = "select count(1) from `test-bucket` where (`something` = \"$queryArg\") limit 1"
231+
def normalizedQuery = "select count(?) from `test-bucket` where (`something` = \"$queryArg\") limit ?"
224232
int count1 = 0
225233
int count2 = 0
226234

@@ -240,32 +248,40 @@ abstract class CouchbaseClient31Test extends VersionedNamingTestBase {
240248
}
241249

242250
then:
243-
count1 == 250
244-
count2 == 250
251+
count1 == expectedCount
252+
count2 == expectedCount
245253
assertTraces(1) {
246254
sortSpansByStart()
247-
trace(7) {
255+
trace(internalEnabled ? 7 : 3) {
248256
basicSpan(it, 'multiple.parent')
249257
assertCouchbaseCall(it, "cb.query", [
250258
'db.couchbase.retries' : { Long },
251259
'db.couchbase.service' : 'query',
252260
], normalizedQuery, span(0), false)
253-
assertCouchbaseCall(it, "prepare", [
254-
'db.couchbase.retries' : { Long },
255-
'db.couchbase.service' : 'query',
256-
], "PREPARE $normalizedQuery", span(1), true)
257-
assertCouchbaseDispatchCall(it, span(2))
261+
if (internalEnabled) {
262+
assertCouchbaseCall(it, "prepare", [
263+
'db.couchbase.retries': { Long },
264+
'db.couchbase.service': 'query',
265+
], "PREPARE $normalizedQuery", span(1), true)
266+
assertCouchbaseDispatchCall(it, span(2))
267+
}
258268
assertCouchbaseCall(it, "cb.query", [
259269
'db.couchbase.retries' : { Long },
260270
'db.couchbase.service' : 'query',
261271
], normalizedQuery, span(0), false)
262-
assertCouchbaseCall(it, "execute", [
263-
'db.couchbase.retries' : { Long },
264-
'db.couchbase.service' : 'query',
265-
], normalizedQuery, span(4), true)
266-
assertCouchbaseDispatchCall(it, span(5))
272+
if (internalEnabled) {
273+
assertCouchbaseCall(it, "execute", [
274+
'db.couchbase.retries': { Long },
275+
'db.couchbase.service': 'query',
276+
], normalizedQuery, span(4), true)
277+
assertCouchbaseDispatchCall(it, span(5))
278+
}
267279
}
268280
}
281+
where:
282+
internalEnabled | queryArg | expectedCount
283+
true | "wonderful" | 250
284+
false | "notinternal" | 0 // avoid having the query engine reusing previous prepared query
269285
}
270286

271287
def "check error query spans with parent"() {
@@ -299,68 +315,6 @@ abstract class CouchbaseClient31Test extends VersionedNamingTestBase {
299315
}
300316
}
301317

302-
def "check multiple error query spans with parent and adhoc false"() {
303-
def query = 'select count(1) from `test-bucket` where (`something` = "wonderful") limeit 1'
304-
def normalizedQuery = 'select count(?) from `test-bucket` where (`something` = "wonderful") limeit ?'
305-
int count1 = 0
306-
int count2 = 0
307-
Throwable ex1 = null
308-
Throwable ex2 = null
309-
310-
when:
311-
runUnderTrace('multiple.parent') {
312-
// This results in a call to AsyncCluster.query(...)
313-
try {
314-
cluster.query(query, QueryOptions.queryOptions().adhoc(false)).each {
315-
it.rowsAsObject().each {
316-
count1 = it.getInt('$1')
317-
}
318-
}
319-
} catch (CouchbaseException expected) {
320-
ex1 = expected
321-
}
322-
try {
323-
cluster.query(query, QueryOptions.queryOptions().adhoc(false)).each {
324-
it.rowsAsObject().each {
325-
count2 = it.getInt('$1')
326-
}
327-
}
328-
} catch (CouchbaseException expected) {
329-
ex2 = expected
330-
}
331-
}
332-
333-
then:
334-
count1 == 0
335-
count2 == 0
336-
ex1 != null
337-
ex2 != null
338-
assertTraces(1) {
339-
sortSpansByStart()
340-
trace(7) {
341-
basicSpan(it, 'multiple.parent')
342-
assertCouchbaseCall(it, "cb.query", [
343-
'db.couchbase.retries' : { Long },
344-
'db.couchbase.service' : 'query',
345-
], normalizedQuery, span(0), false, ex1)
346-
assertCouchbaseCall(it, "prepare", [
347-
'db.couchbase.retries' : { Long },
348-
'db.couchbase.service' : 'query',
349-
], "PREPARE $normalizedQuery", span(1), true, ex1)
350-
assertCouchbaseDispatchCall(it, span(2))
351-
assertCouchbaseCall(it, "cb.query", [
352-
'db.couchbase.retries' : { Long },
353-
'db.couchbase.service' : 'query',
354-
], normalizedQuery, span(0), false, ex2)
355-
assertCouchbaseCall(it, "prepare", [
356-
'db.couchbase.retries' : { Long },
357-
'db.couchbase.service' : 'query',
358-
], "PREPARE $normalizedQuery", span(4), true, ex2)
359-
assertCouchbaseDispatchCall(it, span(5))
360-
}
361-
}
362-
}
363-
364318
void assertCouchbaseCall(TraceAssert trace, String name, Map<String, Serializable> extraTags, boolean internal = false, Throwable ex = null) {
365319
assertCouchbaseCall(trace, name, extraTags, null, null, internal, ex)
366320
}

dd-java-agent/instrumentation/couchbase/couchbase-3.2/src/main/java/datadog/trace/instrumentation/couchbase_32/client/DatadogRequestTracer.java

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package datadog.trace.instrumentation.couchbase_32.client;
22

3+
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.blackholeSpan;
34
import static datadog.trace.instrumentation.couchbase_32.client.CouchbaseClientDecorator.COUCHBASE_CLIENT;
45
import static datadog.trace.instrumentation.couchbase_32.client.CouchbaseClientDecorator.OPERATION_NAME;
56

67
import com.couchbase.client.core.Core;
78
import com.couchbase.client.core.cnc.RequestSpan;
89
import com.couchbase.client.core.cnc.RequestTracer;
10+
import datadog.trace.api.Config;
911
import datadog.trace.bootstrap.ContextStore;
1012
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
1113
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
@@ -39,24 +41,32 @@ public RequestSpan requestSpan(String requestName, RequestSpan requestParent) {
3941
if (null == parent) {
4042
parent = tracer.activeSpan();
4143
}
42-
if (null != parent && COUCHBASE_CLIENT.equals(parent.getTag(Tags.COMPONENT))) {
43-
spanName = COUCHBASE_INTERNAL;
44-
measured = false;
45-
seedNodes = parent.getTag(InstrumentationTags.COUCHBASE_SEED_NODES);
46-
}
44+
DatadogRequestSpan requestSpan = null;
4745

48-
AgentTracer.SpanBuilder builder = tracer.buildSpan(spanName);
49-
if (null != parent) {
50-
builder.asChildOf(parent.context());
46+
if (null != parent && COUCHBASE_CLIENT.equals(parent.getTag(Tags.COMPONENT))) {
47+
if (!Config.get().isCouchbaseInternalSpansEnabled()) {
48+
// mute the tracing related to internal spans
49+
requestSpan = DatadogRequestSpan.wrap(blackholeSpan(), coreContext);
50+
} else {
51+
spanName = COUCHBASE_INTERNAL;
52+
measured = false;
53+
seedNodes = parent.getTag(InstrumentationTags.COUCHBASE_SEED_NODES);
54+
}
5155
}
52-
AgentSpan span = builder.start();
53-
CouchbaseClientDecorator.DECORATE.afterStart(span);
54-
span.setResourceName(requestName);
55-
span.setMeasured(measured);
56-
if (seedNodes != null) {
57-
span.setTag(InstrumentationTags.COUCHBASE_SEED_NODES, seedNodes);
56+
if (requestSpan == null) {
57+
AgentTracer.SpanBuilder builder = tracer.buildSpan(spanName);
58+
if (null != parent) {
59+
builder.asChildOf(parent.context());
60+
}
61+
AgentSpan span = builder.start();
62+
CouchbaseClientDecorator.DECORATE.afterStart(span);
63+
span.setResourceName(requestName);
64+
span.setMeasured(measured);
65+
if (seedNodes != null) {
66+
span.setTag(InstrumentationTags.COUCHBASE_SEED_NODES, seedNodes);
67+
}
68+
requestSpan = DatadogRequestSpan.wrap(span, coreContext);
5869
}
59-
DatadogRequestSpan requestSpan = DatadogRequestSpan.wrap(span, coreContext);
6070
// When Couchbase converts a query to a prepare statement or execute statement,
6171
// it will not finish the original span
6272
switch (requestName) {

dd-java-agent/instrumentation/couchbase/couchbase-3.2/src/test/groovy/CouchbaseClient32Test.groovy

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,9 @@ abstract class CouchbaseClient32Test extends VersionedNamingTestBase {
112112
}
113113
}
114114

115-
def "check basic error spans"() {
115+
def "check basic error spans with internal spans enabled #internalEnabled"() {
116116
setup:
117+
injectSysConfig("trace.couchbase.internal-spans.enabled", "$internalEnabled")
117118
def collection = bucket.defaultCollection()
118119
Throwable ex = null
119120

@@ -128,7 +129,7 @@ abstract class CouchbaseClient32Test extends VersionedNamingTestBase {
128129
ex != null
129130
assertTraces(1) {
130131
sortSpansByStart()
131-
trace(2) {
132+
trace(internalEnabled ? 2: 1) {
132133
assertCouchbaseCall(it, "get", [
133134
'db.couchbase.collection' : '_default',
134135
'db.couchbase.document_id': { String },
@@ -138,14 +139,18 @@ abstract class CouchbaseClient32Test extends VersionedNamingTestBase {
138139
'db.name' : BUCKET,
139140
'db.operation' : 'get'
140141
], false, ex)
141-
assertCouchbaseDispatchCall(it, span(0), [
142-
'db.couchbase.collection' : '_default',
143-
'db.couchbase.document_id' : { String },
144-
'db.couchbase.scope' : '_default',
145-
'db.name' : BUCKET
146-
])
142+
if (internalEnabled) {
143+
assertCouchbaseDispatchCall(it, span(0), [
144+
'db.couchbase.collection' : '_default',
145+
'db.couchbase.document_id' : { String },
146+
'db.couchbase.scope' : '_default',
147+
'db.name' : BUCKET
148+
])
149+
}
147150
}
148151
}
152+
where:
153+
internalEnabled << [true, false]
149154
}
150155

151156
def "check query spans"() {
@@ -228,10 +233,11 @@ abstract class CouchbaseClient32Test extends VersionedNamingTestBase {
228233
adhoc << [true, false]
229234
}
230235

231-
def "check multiple async query spans with parent and adhoc false"() {
236+
def "check multiple async query spans with parent and adhoc false and internal spans enabled = #internalEnabled"() {
232237
setup:
233-
def query = 'select count(1) from `test-bucket` where (`something` = "wonderful") limit 1'
234-
def normalizedQuery = 'select count(?) from `test-bucket` where (`something` = "wonderful") limit ?'
238+
injectSysConfig("trace.couchbase.internal-spans.enabled", "$internalEnabled")
239+
def query = "select count(1) from `test-bucket` where (`something` = \"$queryArg\") limit 1"
240+
def normalizedQuery = "select count(?) from `test-bucket` where (`something` = \"$queryArg\") limit ?"
235241
int count1 = 0
236242
int count2 = 0
237243
def extraPrepare = isLatestDepTest
@@ -252,38 +258,46 @@ abstract class CouchbaseClient32Test extends VersionedNamingTestBase {
252258
}
253259

254260
then:
255-
count1 == 250
256-
count2 == 250
261+
count1 == expectedCount
262+
count2 == expectedCount
257263
assertTraces(1) {
258-
sortSpansByStart()
259-
trace(extraPrepare ? 8 : 7) {
264+
trace(internalEnabled ? (extraPrepare ? 8 : 7) : 3) {
265+
sortSpansByStart()
260266
basicSpan(it, 'async.multiple')
261267
assertCouchbaseCall(it, normalizedQuery, [
262268
'db.couchbase.retries' : { Long },
263269
'db.couchbase.service' : 'query'
264270
], span(0))
265-
assertCouchbaseCall(it, "PREPARE $normalizedQuery", [
266-
'db.couchbase.retries': { Long },
267-
'db.couchbase.service': 'query'
268-
], span(1), true)
269-
assertCouchbaseDispatchCall(it, span(2))
271+
if (internalEnabled) {
272+
assertCouchbaseCall(it, "PREPARE $normalizedQuery", [
273+
'db.couchbase.retries': { Long },
274+
'db.couchbase.service': 'query'
275+
], span(1), true)
276+
assertCouchbaseDispatchCall(it, span(2))
277+
}
270278
assertCouchbaseCall(it, normalizedQuery, [
271279
'db.couchbase.retries' : { Long },
272280
'db.couchbase.service' : 'query'
273281
], span(0))
274-
if (extraPrepare) {
275-
assertCouchbaseCall(it, "PREPARE $normalizedQuery", [
282+
if (internalEnabled) {
283+
if (extraPrepare) {
284+
assertCouchbaseCall(it, "PREPARE $normalizedQuery", [
285+
'db.couchbase.retries': { Long },
286+
'db.couchbase.service': 'query'
287+
], span(4), true)
288+
}
289+
assertCouchbaseCall(it, normalizedQuery, [
276290
'db.couchbase.retries': { Long },
277291
'db.couchbase.service': 'query'
278292
], span(4), true)
293+
assertCouchbaseDispatchCall(it, span(extraPrepare ? 6 : 5))
279294
}
280-
assertCouchbaseCall(it, normalizedQuery, [
281-
'db.couchbase.retries': { Long },
282-
'db.couchbase.service': 'query'
283-
], span(4), true)
284-
assertCouchbaseDispatchCall(it, span(extraPrepare ? 6 : 5))
285295
}
286296
}
297+
where:
298+
internalEnabled | queryArg | expectedCount
299+
true | "wonderful" | 250
300+
false | "notinternal" | 0 // avoid having the query engine reusing previous prepared query
287301
}
288302

289303
def "check error query spans with parent"() {

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
@@ -215,6 +215,7 @@ public final class ConfigDefaults {
215215

216216
static final float DEFAULT_TRACE_FLUSH_INTERVAL = 1;
217217

218+
static final boolean DEFAULT_COUCHBASE_INTERNAL_SPANS_ENABLED = true;
218219
static final boolean DEFAULT_ELASTICSEARCH_BODY_ENABLED = false;
219220
static final boolean DEFAULT_ELASTICSEARCH_PARAMS_ENABLED = true;
220221
static final boolean DEFAULT_ELASTICSEARCH_BODY_AND_PARAMS_ENABLED = false;

0 commit comments

Comments
 (0)