Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to not include couchbase internal spans #6763

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package datadog.trace.instrumentation.couchbase_31.client;

import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.blackholeSpan;
import static datadog.trace.instrumentation.couchbase_31.client.CouchbaseClientDecorator.COUCHBASE_CLIENT;

import com.couchbase.client.core.Core;
import com.couchbase.client.core.cnc.RequestSpan;
import com.couchbase.client.core.cnc.RequestTracer;
import datadog.trace.api.Config;
import datadog.trace.bootstrap.ContextStore;
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
Expand Down Expand Up @@ -37,7 +39,12 @@ public RequestSpan requestSpan(String requestName, RequestSpan requestParent) {
if (null == parent) {
parent = tracer.activeSpan();
}

if (null != parent && COUCHBASE_CLIENT.equals(parent.getTag(Tags.COMPONENT))) {
if (!Config.get().isCouchbaseInternalSpansEnabled()) {
// mute the tracing related to internal spans
return DatadogRequestSpan.wrap(blackholeSpan(), coreContext);
}
spanName = COUCHBASE_INTERNAL;
measured = false;
seedNodes = parent.getTag(InstrumentationTags.COUCHBASE_SEED_NODES);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import com.couchbase.client.core.env.TimeoutConfig
import com.couchbase.client.core.error.CouchbaseException
import com.couchbase.client.core.error.DocumentNotFoundException
import com.couchbase.client.core.error.ParsingFailureException
import com.couchbase.client.java.Bucket
Expand Down Expand Up @@ -107,8 +106,9 @@ abstract class CouchbaseClient31Test extends VersionedNamingTestBase {
}
}

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

Expand All @@ -122,7 +122,7 @@ abstract class CouchbaseClient31Test extends VersionedNamingTestBase {
then:
assertTraces(1) {
sortSpansByStart()
trace(2) {
trace(internalEnabled ? 2 : 1) {
assertCouchbaseCall(it, "cb.get", [
'db.couchbase.collection': '_default',
'db.couchbase.retries' : { Long },
Expand All @@ -131,9 +131,15 @@ abstract class CouchbaseClient31Test extends VersionedNamingTestBase {
'db.name' : BUCKET,
'db.operation' : 'get',
], false, ex)
assertCouchbaseDispatchCall(it, span(0))
if (internalEnabled) {
assertCouchbaseDispatchCall(it, span(0))
}
}
}
where:
internalEnabled | _
true | _
false | _
}

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

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

Expand All @@ -240,32 +248,40 @@ abstract class CouchbaseClient31Test extends VersionedNamingTestBase {
}

then:
count1 == 250
count2 == 250
count1 == expectedCount
count2 == expectedCount
assertTraces(1) {
sortSpansByStart()
trace(7) {
trace(internalEnabled ? 7 : 3) {
basicSpan(it, 'multiple.parent')
assertCouchbaseCall(it, "cb.query", [
'db.couchbase.retries' : { Long },
'db.couchbase.service' : 'query',
], normalizedQuery, span(0), false)
assertCouchbaseCall(it, "prepare", [
'db.couchbase.retries' : { Long },
'db.couchbase.service' : 'query',
], "PREPARE $normalizedQuery", span(1), true)
assertCouchbaseDispatchCall(it, span(2))
if (internalEnabled) {
assertCouchbaseCall(it, "prepare", [
'db.couchbase.retries': { Long },
'db.couchbase.service': 'query',
], "PREPARE $normalizedQuery", span(1), true)
assertCouchbaseDispatchCall(it, span(2))
}
assertCouchbaseCall(it, "cb.query", [
'db.couchbase.retries' : { Long },
'db.couchbase.service' : 'query',
], normalizedQuery, span(0), false)
assertCouchbaseCall(it, "execute", [
'db.couchbase.retries' : { Long },
'db.couchbase.service' : 'query',
], normalizedQuery, span(4), true)
assertCouchbaseDispatchCall(it, span(5))
if (internalEnabled) {
assertCouchbaseCall(it, "execute", [
'db.couchbase.retries': { Long },
'db.couchbase.service': 'query',
], normalizedQuery, span(4), true)
assertCouchbaseDispatchCall(it, span(5))
}
}
}
where:
internalEnabled | queryArg | expectedCount
true | "wonderful" | 250
false | "notinternal" | 0 // avoid having the query engine reusing previous prepared query
}

def "check error query spans with parent"() {
Expand Down Expand Up @@ -299,68 +315,6 @@ abstract class CouchbaseClient31Test extends VersionedNamingTestBase {
}
}

def "check multiple error query spans with parent and adhoc false"() {
def query = 'select count(1) from `test-bucket` where (`something` = "wonderful") limeit 1'
def normalizedQuery = 'select count(?) from `test-bucket` where (`something` = "wonderful") limeit ?'
int count1 = 0
int count2 = 0
Throwable ex1 = null
Throwable ex2 = null

when:
runUnderTrace('multiple.parent') {
// This results in a call to AsyncCluster.query(...)
try {
cluster.query(query, QueryOptions.queryOptions().adhoc(false)).each {
it.rowsAsObject().each {
count1 = it.getInt('$1')
}
}
} catch (CouchbaseException expected) {
ex1 = expected
}
try {
cluster.query(query, QueryOptions.queryOptions().adhoc(false)).each {
it.rowsAsObject().each {
count2 = it.getInt('$1')
}
}
} catch (CouchbaseException expected) {
ex2 = expected
}
}

then:
count1 == 0
count2 == 0
ex1 != null
ex2 != null
assertTraces(1) {
sortSpansByStart()
trace(7) {
basicSpan(it, 'multiple.parent')
assertCouchbaseCall(it, "cb.query", [
'db.couchbase.retries' : { Long },
'db.couchbase.service' : 'query',
], normalizedQuery, span(0), false, ex1)
assertCouchbaseCall(it, "prepare", [
'db.couchbase.retries' : { Long },
'db.couchbase.service' : 'query',
], "PREPARE $normalizedQuery", span(1), true, ex1)
assertCouchbaseDispatchCall(it, span(2))
assertCouchbaseCall(it, "cb.query", [
'db.couchbase.retries' : { Long },
'db.couchbase.service' : 'query',
], normalizedQuery, span(0), false, ex2)
assertCouchbaseCall(it, "prepare", [
'db.couchbase.retries' : { Long },
'db.couchbase.service' : 'query',
], "PREPARE $normalizedQuery", span(4), true, ex2)
assertCouchbaseDispatchCall(it, span(5))
}
}
}

void assertCouchbaseCall(TraceAssert trace, String name, Map<String, Serializable> extraTags, boolean internal = false, Throwable ex = null) {
assertCouchbaseCall(trace, name, extraTags, null, null, internal, ex)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package datadog.trace.instrumentation.couchbase_32.client;

import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.blackholeSpan;
import static datadog.trace.instrumentation.couchbase_32.client.CouchbaseClientDecorator.COUCHBASE_CLIENT;
import static datadog.trace.instrumentation.couchbase_32.client.CouchbaseClientDecorator.OPERATION_NAME;

import com.couchbase.client.core.Core;
import com.couchbase.client.core.cnc.RequestSpan;
import com.couchbase.client.core.cnc.RequestTracer;
import datadog.trace.api.Config;
import datadog.trace.bootstrap.ContextStore;
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
Expand Down Expand Up @@ -39,24 +41,32 @@ public RequestSpan requestSpan(String requestName, RequestSpan requestParent) {
if (null == parent) {
parent = tracer.activeSpan();
}
if (null != parent && COUCHBASE_CLIENT.equals(parent.getTag(Tags.COMPONENT))) {
spanName = COUCHBASE_INTERNAL;
measured = false;
seedNodes = parent.getTag(InstrumentationTags.COUCHBASE_SEED_NODES);
}
DatadogRequestSpan requestSpan = null;

AgentTracer.SpanBuilder builder = tracer.buildSpan(spanName);
if (null != parent) {
builder.asChildOf(parent.context());
if (null != parent && COUCHBASE_CLIENT.equals(parent.getTag(Tags.COMPONENT))) {
if (!Config.get().isCouchbaseInternalSpansEnabled()) {
// mute the tracing related to internal spans
requestSpan = DatadogRequestSpan.wrap(blackholeSpan(), coreContext);
} else {
spanName = COUCHBASE_INTERNAL;
measured = false;
seedNodes = parent.getTag(InstrumentationTags.COUCHBASE_SEED_NODES);
}
}
AgentSpan span = builder.start();
CouchbaseClientDecorator.DECORATE.afterStart(span);
span.setResourceName(requestName);
span.setMeasured(measured);
if (seedNodes != null) {
span.setTag(InstrumentationTags.COUCHBASE_SEED_NODES, seedNodes);
if (requestSpan == null) {
AgentTracer.SpanBuilder builder = tracer.buildSpan(spanName);
if (null != parent) {
builder.asChildOf(parent.context());
}
AgentSpan span = builder.start();
CouchbaseClientDecorator.DECORATE.afterStart(span);
span.setResourceName(requestName);
span.setMeasured(measured);
if (seedNodes != null) {
span.setTag(InstrumentationTags.COUCHBASE_SEED_NODES, seedNodes);
}
requestSpan = DatadogRequestSpan.wrap(span, coreContext);
}
DatadogRequestSpan requestSpan = DatadogRequestSpan.wrap(span, coreContext);
// When Couchbase converts a query to a prepare statement or execute statement,
// it will not finish the original span
switch (requestName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,9 @@ abstract class CouchbaseClient32Test extends VersionedNamingTestBase {
}
}

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

Expand All @@ -128,7 +129,7 @@ abstract class CouchbaseClient32Test extends VersionedNamingTestBase {
ex != null
assertTraces(1) {
sortSpansByStart()
trace(2) {
trace(internalEnabled ? 2: 1) {
assertCouchbaseCall(it, "get", [
'db.couchbase.collection' : '_default',
'db.couchbase.document_id': { String },
Expand All @@ -138,14 +139,18 @@ abstract class CouchbaseClient32Test extends VersionedNamingTestBase {
'db.name' : BUCKET,
'db.operation' : 'get'
], false, ex)
assertCouchbaseDispatchCall(it, span(0), [
'db.couchbase.collection' : '_default',
'db.couchbase.document_id' : { String },
'db.couchbase.scope' : '_default',
'db.name' : BUCKET
])
if (internalEnabled) {
assertCouchbaseDispatchCall(it, span(0), [
'db.couchbase.collection' : '_default',
'db.couchbase.document_id' : { String },
'db.couchbase.scope' : '_default',
'db.name' : BUCKET
])
}
}
}
where:
internalEnabled << [true, false]
}

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

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

then:
count1 == 250
count2 == 250
count1 == expectedCount
count2 == expectedCount
assertTraces(1) {
sortSpansByStart()
trace(extraPrepare ? 8 : 7) {
trace(internalEnabled ? (extraPrepare ? 8 : 7) : 3) {
sortSpansByStart()
basicSpan(it, 'async.multiple')
assertCouchbaseCall(it, normalizedQuery, [
'db.couchbase.retries' : { Long },
'db.couchbase.service' : 'query'
], span(0))
assertCouchbaseCall(it, "PREPARE $normalizedQuery", [
'db.couchbase.retries': { Long },
'db.couchbase.service': 'query'
], span(1), true)
assertCouchbaseDispatchCall(it, span(2))
if (internalEnabled) {
assertCouchbaseCall(it, "PREPARE $normalizedQuery", [
'db.couchbase.retries': { Long },
'db.couchbase.service': 'query'
], span(1), true)
assertCouchbaseDispatchCall(it, span(2))
}
assertCouchbaseCall(it, normalizedQuery, [
'db.couchbase.retries' : { Long },
'db.couchbase.service' : 'query'
], span(0))
if (extraPrepare) {
assertCouchbaseCall(it, "PREPARE $normalizedQuery", [
if (internalEnabled) {
if (extraPrepare) {
assertCouchbaseCall(it, "PREPARE $normalizedQuery", [
'db.couchbase.retries': { Long },
'db.couchbase.service': 'query'
], span(4), true)
}
assertCouchbaseCall(it, normalizedQuery, [
'db.couchbase.retries': { Long },
'db.couchbase.service': 'query'
], span(4), true)
assertCouchbaseDispatchCall(it, span(extraPrepare ? 6 : 5))
}
assertCouchbaseCall(it, normalizedQuery, [
'db.couchbase.retries': { Long },
'db.couchbase.service': 'query'
], span(4), true)
assertCouchbaseDispatchCall(it, span(extraPrepare ? 6 : 5))
}
}
where:
internalEnabled | queryArg | expectedCount
true | "wonderful" | 250
false | "notinternal" | 0 // avoid having the query engine reusing previous prepared query
}

def "check error query spans with parent"() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ public final class ConfigDefaults {

static final float DEFAULT_TRACE_FLUSH_INTERVAL = 1;

static final boolean DEFAULT_COUCHBASE_INTERNAL_SPANS_ENABLED = true;
static final boolean DEFAULT_ELASTICSEARCH_BODY_ENABLED = false;
static final boolean DEFAULT_ELASTICSEARCH_PARAMS_ENABLED = true;
static final boolean DEFAULT_ELASTICSEARCH_BODY_AND_PARAMS_ENABLED = false;
Expand Down
Loading
Loading