Merge pull request #71 from gpolaert/operation-name

Override the operation name
This commit is contained in:
Emanuele Palazzetti 2017-08-01 12:30:50 +02:00 committed by GitHub
commit 7667fb6021
15 changed files with 167 additions and 109 deletions

View File

@ -5,6 +5,7 @@ import com.mongodb.MongoClientOptions;
import com.mongodb.event.CommandStartedEvent; import com.mongodb.event.CommandStartedEvent;
import io.opentracing.Span; import io.opentracing.Span;
import io.opentracing.contrib.mongo.TracingCommandListener; import io.opentracing.contrib.mongo.TracingCommandListener;
import io.opentracing.tag.Tags;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -50,8 +51,14 @@ public class MongoHelper extends DDAgentTracingHelper<MongoClientOptions.Builder
public void decorate(final Span span, final CommandStartedEvent event) { public void decorate(final Span span, final CommandStartedEvent event) {
try { try {
// normalize the Mongo command so that parameters are removed from the string
final BsonDocument normalized = norm(event.getCommand()); final BsonDocument normalized = norm(event.getCommand());
span.setTag(DDTags.RESOURCE_NAME, normalized.toString()); final String mongoCmd = normalized.toString();
// add specific resource name and replace the `db.statement` OpenTracing
// tag with the quantized version of the Mongo command
span.setTag(DDTags.RESOURCE_NAME, mongoCmd);
span.setTag(Tags.DB_STATEMENT.getKey(), mongoCmd);
} catch (final Throwable e) { } catch (final Throwable e) {
log.warn("Couldn't decorate the mongo query: " + e.getMessage(), e); log.warn("Couldn't decorate the mongo query: " + e.getMessage(), e);
} }

View File

@ -1,6 +1,6 @@
package com.datadoghq.trace; package com.datadoghq.trace;
import com.datadoghq.trace.integration.DDSpanContextDecorator; import com.datadoghq.trace.integration.AbstractDecorator;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import io.opentracing.tag.Tags; import io.opentracing.tag.Tags;
@ -28,28 +28,27 @@ public class DDSpanContext implements io.opentracing.SpanContext {
private final long parentId; private final long parentId;
private final String threadName = Thread.currentThread().getName(); private final String threadName = Thread.currentThread().getName();
private final long threadId = Thread.currentThread().getId(); private final long threadId = Thread.currentThread().getId();
private Map<String, String> baggageItems; /** The collection of all span related to this one */
private final Queue<DDBaseSpan<?>> trace;
// DD attributes // DD attributes
/** For technical reasons, the ref to the original tracer */
private final DDTracer tracer;
private Map<String, String> baggageItems;
/** The service name is required, otherwise the span are dropped by the agent */ /** The service name is required, otherwise the span are dropped by the agent */
private String serviceName; private String serviceName;
/** The resource associated to the service (server_web, database, etc.) */ /** The resource associated to the service (server_web, database, etc.) */
private String resourceName; private String resourceName;
/** True indicates that the span reports an error */ /** True indicates that the span reports an error */
private boolean errorFlag; private boolean errorFlag;
/** The type of the span. If null, the Datadog Agent will report as a custom */ /** The type of the span. If null, the Datadog Agent will report as a custom */
private String spanType; private String spanType;
/** The collection of all span related to this one */
private final Queue<DDBaseSpan<?>> trace;
/** Each span have an operation name describing the current span */ /** Each span have an operation name describing the current span */
private String operationName; private String operationName;
// Others attributes
/** Tags are associated to the current span, they will not propagate to the children span */ /** Tags are associated to the current span, they will not propagate to the children span */
private Map<String, Object> tags; private Map<String, Object> tags;
// Others attributes
/** For technical reasons, the ref to the original tracer */
private final DDTracer tracer;
public DDSpanContext( public DDSpanContext(
final long traceId, final long traceId,
@ -109,12 +108,20 @@ public class DDSpanContext implements io.opentracing.SpanContext {
return serviceName; return serviceName;
} }
public void setServiceName(final String serviceName) {
this.serviceName = serviceName;
}
public String getResourceName() { public String getResourceName() {
return this.resourceName == null || this.resourceName.isEmpty() return this.resourceName == null || this.resourceName.isEmpty()
? this.operationName ? this.operationName
: this.resourceName; : this.resourceName;
} }
public void setResourceName(final String resourceName) {
this.resourceName = resourceName;
}
public boolean getErrorFlag() { public boolean getErrorFlag() {
return errorFlag; return errorFlag;
} }
@ -127,6 +134,10 @@ public class DDSpanContext implements io.opentracing.SpanContext {
return spanType; return spanType;
} }
public void setSpanType(final String spanType) {
this.spanType = spanType;
}
public void setBaggageItem(final String key, final String value) { public void setBaggageItem(final String key, final String value) {
if (this.baggageItems.isEmpty()) { if (this.baggageItems.isEmpty()) {
this.baggageItems = new HashMap<String, String>(); this.baggageItems = new HashMap<String, String>();
@ -184,9 +195,9 @@ public class DDSpanContext implements io.opentracing.SpanContext {
this.tags.put(tag, value); this.tags.put(tag, value);
//Call decorators //Call decorators
final List<DDSpanContextDecorator> decorators = tracer.getSpanContextDecorators(tag); final List<AbstractDecorator> decorators = tracer.getSpanContextDecorators(tag);
if (decorators != null) { if (decorators != null) {
for (final DDSpanContextDecorator decorator : decorators) { for (final AbstractDecorator decorator : decorators) {
decorator.afterSetTag(this, tag, value); decorator.afterSetTag(this, tag, value);
} }
} }
@ -223,23 +234,11 @@ public class DDSpanContext implements io.opentracing.SpanContext {
.toString(); .toString();
} }
public void setOperationName(final String operationName) {
this.operationName = operationName;
}
public String getOperationName() { public String getOperationName() {
return operationName; return operationName;
} }
public void setServiceName(final String serviceName) { public void setOperationName(final String operationName) {
this.serviceName = serviceName; this.operationName = operationName;
}
public void setResourceName(final String resourceName) {
this.resourceName = resourceName;
}
public void setSpanType(final String spanType) {
this.spanType = spanType;
} }
} }

View File

@ -1,6 +1,6 @@
package com.datadoghq.trace; package com.datadoghq.trace;
import com.datadoghq.trace.integration.DDSpanContextDecorator; import com.datadoghq.trace.integration.AbstractDecorator;
import com.datadoghq.trace.propagation.Codec; import com.datadoghq.trace.propagation.Codec;
import com.datadoghq.trace.propagation.HTTPCodec; import com.datadoghq.trace.propagation.HTTPCodec;
import com.datadoghq.trace.sampling.AllSampler; import com.datadoghq.trace.sampling.AllSampler;
@ -39,7 +39,7 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac
private final String defaultServiceName; private final String defaultServiceName;
/** Span context decorators */ /** Span context decorators */
private final Map<String, List<DDSpanContextDecorator>> spanContextDecorators = new HashMap<>(); private final Map<String, List<AbstractDecorator>> spanContextDecorators = new HashMap<>();
private final CodecRegistry registry; private final CodecRegistry registry;
@ -70,18 +70,18 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac
* *
* @return the list of span context decorators * @return the list of span context decorators
*/ */
public List<DDSpanContextDecorator> getSpanContextDecorators(final String tag) { public List<AbstractDecorator> getSpanContextDecorators(final String tag) {
return spanContextDecorators.get(tag); return spanContextDecorators.get(tag);
} }
/** /**
* Add a new decorator in the list ({@link DDSpanContextDecorator}) * Add a new decorator in the list ({@link AbstractDecorator})
* *
* @param decorator The decorator in the list * @param decorator The decorator in the list
*/ */
public void addDecorator(final DDSpanContextDecorator decorator) { public void addDecorator(final AbstractDecorator decorator) {
List<DDSpanContextDecorator> list = spanContextDecorators.get(decorator.getMatchingTag()); List<AbstractDecorator> list = spanContextDecorators.get(decorator.getMatchingTag());
if (list == null) { if (list == null) {
list = new ArrayList<>(); list = new ArrayList<>();
} }

View File

@ -7,7 +7,7 @@ import com.datadoghq.trace.DDTags;
* Span decorators are called when new tags are written and proceed to various remappings and * Span decorators are called when new tags are written and proceed to various remappings and
* enrichments * enrichments
*/ */
public abstract class DDSpanContextDecorator { public abstract class AbstractDecorator {
private String matchingTag; private String matchingTag;
@ -17,10 +17,10 @@ public abstract class DDSpanContextDecorator {
private String setValue; private String setValue;
public boolean afterSetTag(DDSpanContext context, String tag, Object value) { public boolean afterSetTag(final DDSpanContext context, final String tag, final Object value) {
if ((this.getMatchingValue() == null || value.equals(this.getMatchingValue()))) { if ((this.getMatchingValue() == null || value.equals(this.getMatchingValue()))) {
String targetTag = getSetTag() == null ? tag : getSetTag(); final String targetTag = getSetTag() == null ? tag : getSetTag();
String targetValue = getSetValue() == null ? String.valueOf(value) : getSetValue(); final String targetValue = getSetValue() == null ? String.valueOf(value) : getSetValue();
if (targetTag.equals(DDTags.SERVICE_NAME)) { if (targetTag.equals(DDTags.SERVICE_NAME)) {
context.setServiceName(targetValue); context.setServiceName(targetValue);
@ -41,7 +41,7 @@ public abstract class DDSpanContextDecorator {
return matchingTag; return matchingTag;
} }
public void setMatchingTag(String tag) { public void setMatchingTag(final String tag) {
this.matchingTag = tag; this.matchingTag = tag;
} }
@ -49,7 +49,7 @@ public abstract class DDSpanContextDecorator {
return matchingValue; return matchingValue;
} }
public void setMatchingValue(String value) { public void setMatchingValue(final String value) {
this.matchingValue = value; this.matchingValue = value;
} }
@ -57,7 +57,7 @@ public abstract class DDSpanContextDecorator {
return setTag; return setTag;
} }
public void setSetTag(String targetTag) { public void setSetTag(final String targetTag) {
this.setTag = targetTag; this.setTag = targetTag;
} }
@ -65,7 +65,7 @@ public abstract class DDSpanContextDecorator {
return setValue; return setValue;
} }
public void setSetValue(String targetValue) { public void setSetValue(final String targetValue) {
this.setValue = targetValue; this.setValue = targetValue;
} }
} }

View File

@ -3,42 +3,11 @@ package com.datadoghq.trace.integration;
import com.datadoghq.trace.DDTags; import com.datadoghq.trace.DDTags;
import io.opentracing.tag.Tags; import io.opentracing.tag.Tags;
public class DBStatementAsResourceName extends DDSpanContextDecorator { public class DBStatementAsResourceName extends AbstractDecorator {
public DBStatementAsResourceName() { public DBStatementAsResourceName() {
super(); super();
this.setMatchingTag(Tags.DB_STATEMENT.getKey()); this.setMatchingTag(Tags.DB_STATEMENT.getKey());
this.setSetTag(DDTags.RESOURCE_NAME); this.setSetTag(DDTags.RESOURCE_NAME);
} }
//{ "insert" : "calls", "ordered" : true, "documents" : [{ "_id" : { "$oid" : "5979bbb0ed6fed5749cc9e7c" }, "name" : "MongoDB", "type" : "database", "identifier" : "10", "versions" : ["v3.2", "v3.0", "v2.6"], "info" : { "x" : 203, "y" : 102 } }] }
private void normalizeFilter(final Object f) {}
} }
/*
def normalize_filter(f=None):
if f is None:
return {}
elif isinstance(f, list):
# normalize lists of filters
# e.g. {$or: [ { age: { $lt: 30 } }, { type: 1 } ]}
return [normalize_filter(s) for s in f]
elif isinstance(f, dict):
# normalize dicts of filters
# {$or: [ { age: { $lt: 30 } }, { type: 1 } ]})
out = {}
for k, v in iteritems(f):
if k == "$in" or k == "$nin":
# special case $in queries so we don't loop over lists.
out[k] = "?"
elif isinstance(v, list) or isinstance(v, dict):
# RECURSION ALERT: needs to move to the agent
out[k] = normalize_filter(v)
else:
# NOTE: this shouldn't happen, but let's have a safeguard.
out[k] = '?'
return out
else:
# FIXME[matt] unexpected type. not sure this should ever happen, but at
# least it won't crash.
return {}*/

View File

@ -8,9 +8,9 @@ import io.opentracing.tag.Tags;
* This span decorator leverages DB tags. It allows the dev to define a custom service name and * This span decorator leverages DB tags. It allows the dev to define a custom service name and
* retrieves some DB meta such as the statement * retrieves some DB meta such as the statement
*/ */
public class DBComponent extends DDSpanContextDecorator { public class DBTypeDecorator extends AbstractDecorator {
public DBComponent() { public DBTypeDecorator() {
super(); super();
this.setMatchingTag(Tags.DB_TYPE.getKey()); this.setMatchingTag(Tags.DB_TYPE.getKey());
this.setSetTag(DDTags.SERVICE_NAME); this.setSetTag(DDTags.SERVICE_NAME);
@ -22,6 +22,8 @@ public class DBComponent extends DDSpanContextDecorator {
if (super.afterSetTag(context, tag, value)) { if (super.afterSetTag(context, tag, value)) {
//Assign span type to DB //Assign span type to DB
context.setSpanType("db"); context.setSpanType("db");
// Works for: mongo, cassandra, jdbc
context.setOperationName(String.valueOf(value) + ".query");
return true; return true;
} }
return false; return false;

View File

@ -3,18 +3,18 @@ package com.datadoghq.trace.integration;
import com.datadoghq.trace.DDSpanContext; import com.datadoghq.trace.DDSpanContext;
import io.opentracing.tag.Tags; import io.opentracing.tag.Tags;
public class ErrorFlag extends DDSpanContextDecorator { public class ErrorFlag extends AbstractDecorator {
public ErrorFlag() { public ErrorFlag() {
super(); super();
this.setMatchingTag(Tags.ERROR.getKey()); this.setMatchingTag(Tags.ERROR.getKey());
} }
@Override @Override
public boolean afterSetTag(DDSpanContext context, String tag, Object value) { public boolean afterSetTag(final DDSpanContext context, final String tag, final Object value) {
//Assign resource name //Assign resource name
try { try {
context.setErrorFlag(Boolean.parseBoolean(String.valueOf(value))); context.setErrorFlag(Boolean.parseBoolean(String.valueOf(value)));
} catch (Throwable t) { } catch (final Throwable t) {
//DO NOTHING //DO NOTHING
} }
return true; return true;

View File

@ -8,7 +8,7 @@ import io.opentracing.tag.Tags;
* This span decorator leverages HTTP tags. It allows the dev to define a custom service name and * This span decorator leverages HTTP tags. It allows the dev to define a custom service name and
* retrieves some HTTP meta such as the request path * retrieves some HTTP meta such as the request path
*/ */
public class HTTPComponent extends DDSpanContextDecorator { public class HTTPComponent extends AbstractDecorator {
public HTTPComponent() { public HTTPComponent() {
super(); super();
@ -17,7 +17,7 @@ public class HTTPComponent extends DDSpanContextDecorator {
} }
@Override @Override
public boolean afterSetTag(DDSpanContext context, String tag, Object value) { public boolean afterSetTag(final DDSpanContext context, final String tag, final Object value) {
//Assign service name //Assign service name
if (super.afterSetTag(context, tag, value)) { if (super.afterSetTag(context, tag, value)) {
//Assign span type to WEB //Assign span type to WEB

View File

@ -0,0 +1,43 @@
package com.datadoghq.trace.integration;
import com.datadoghq.trace.DDSpanContext;
import io.opentracing.tag.Tags;
import java.util.HashMap;
import java.util.Map;
/**
* This span decorator is a simple mapping to override the operation DB tags. The operation name of
* DB integration are handled by the DBTypeDecorator
*/
public class OperationDecorator extends AbstractDecorator {
static final Map<String, String> MAPPINGS =
new HashMap<String, String>() {
{
// Component name <> Operation name
put("apache-httpclient", "apache.http");
put("java-aws-sdk", "aws.http");
// Jetty + Tomcat (same integration used)
put("java-web-servlet", "servlet.request");
// FIXME: JMS ops card is low (jms-send or jms-receive), may be this mapping is useless
put("java-jms", "jms");
put("okhttp", "okhttp.http");
// Cassandra, Mongo, JDBC are set via DBTypeDecorator
}
};
public OperationDecorator() {
super();
this.setMatchingTag(Tags.COMPONENT.getKey());
}
@Override
public boolean afterSetTag(final DDSpanContext context, final String tag, final Object value) {
if (MAPPINGS.containsKey(String.valueOf(value))) {
context.setOperationName(MAPPINGS.get(String.valueOf(value)));
return true;
}
return false;
}
}

View File

@ -5,7 +5,7 @@ import com.datadoghq.trace.DDTags;
import io.opentracing.tag.Tags; import io.opentracing.tag.Tags;
import java.net.MalformedURLException; import java.net.MalformedURLException;
public class URLAsResourceName extends DDSpanContextDecorator { public class URLAsResourceName extends AbstractDecorator {
public URLAsResourceName() { public URLAsResourceName() {
super(); super();
@ -14,12 +14,12 @@ public class URLAsResourceName extends DDSpanContextDecorator {
} }
@Override @Override
public boolean afterSetTag(DDSpanContext context, String tag, Object value) { public boolean afterSetTag(final DDSpanContext context, final String tag, final Object value) {
//Assign resource name //Assign resource name
try { try {
String path = new java.net.URL(String.valueOf(value)).getPath(); final String path = new java.net.URL(String.valueOf(value)).getPath();
context.setResourceName(path); context.setResourceName(path);
} catch (MalformedURLException e) { } catch (final MalformedURLException e) {
context.setResourceName(String.valueOf(value)); context.setResourceName(String.valueOf(value));
} }
return true; return true;

View File

@ -1,6 +1,6 @@
package com.datadoghq.trace.resolver; package com.datadoghq.trace.resolver;
import com.datadoghq.trace.integration.DDSpanContextDecorator; import com.datadoghq.trace.integration.AbstractDecorator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -9,9 +9,8 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public class DDDecoratorsFactory { public class DDDecoratorsFactory {
public static String DECORATORS_PACKAGE = "com.datadoghq.trace.integration.";
public static final String CONFIG_PATH = "dd-trace-decorators"; public static final String CONFIG_PATH = "dd-trace-decorators";
public static String DECORATORS_PACKAGE = "com.datadoghq.trace.integration.";
/** /**
* Create decorators from configuration * Create decorators from configuration
@ -19,9 +18,8 @@ public class DDDecoratorsFactory {
* @param decoratorsConfig * @param decoratorsConfig
* @return the list of instanciated and configured decorators * @return the list of instanciated and configured decorators
*/ */
public static List<DDSpanContextDecorator> create( public static List<AbstractDecorator> create(final List<DDSpanDecoratorConfig> decoratorsConfig) {
final List<DDSpanDecoratorConfig> decoratorsConfig) { final List<AbstractDecorator> decorators = new ArrayList<>();
final List<DDSpanContextDecorator> decorators = new ArrayList<>();
for (final DDSpanDecoratorConfig decoratorConfig : decoratorsConfig) { for (final DDSpanDecoratorConfig decoratorConfig : decoratorsConfig) {
if (decoratorConfig.getType() == null) { if (decoratorConfig.getType() == null) {
log.warn("Cannot create decorator without type from configuration {}", decoratorConfig); log.warn("Cannot create decorator without type from configuration {}", decoratorConfig);
@ -39,9 +37,9 @@ public class DDDecoratorsFactory {
continue; continue;
} }
DDSpanContextDecorator decorator = null; AbstractDecorator decorator = null;
try { try {
decorator = (DDSpanContextDecorator) decoratorClass.getConstructor().newInstance(); decorator = (AbstractDecorator) decoratorClass.getConstructor().newInstance();
} catch (final Exception e) { } catch (final Exception e) {
log.warn( log.warn(
"Cannot create decorator as we could not invoke the default constructor. Provided configuration {}", "Cannot create decorator as we could not invoke the default constructor. Provided configuration {}",
@ -68,8 +66,8 @@ public class DDDecoratorsFactory {
return decorators; return decorators;
} }
public static List<DDSpanContextDecorator> createFromResources() { public static List<AbstractDecorator> createFromResources() {
List<DDSpanContextDecorator> result = new ArrayList<>(); List<AbstractDecorator> result = new ArrayList<>();
final TracerConfig config = final TracerConfig config =
FactoryUtils.loadConfigFromResource(CONFIG_PATH, TracerConfig.class); FactoryUtils.loadConfigFromResource(CONFIG_PATH, TracerConfig.class);
if (config != null) { if (config != null) {

View File

@ -1,7 +1,7 @@
package com.datadoghq.trace.resolver; package com.datadoghq.trace.resolver;
import com.datadoghq.trace.DDTracer; import com.datadoghq.trace.DDTracer;
import com.datadoghq.trace.integration.DDSpanContextDecorator; import com.datadoghq.trace.integration.AbstractDecorator;
import com.datadoghq.trace.sampling.AbstractSampler; import com.datadoghq.trace.sampling.AbstractSampler;
import com.datadoghq.trace.sampling.AllSampler; import com.datadoghq.trace.sampling.AllSampler;
import com.datadoghq.trace.sampling.RateSampler; import com.datadoghq.trace.sampling.RateSampler;
@ -102,8 +102,8 @@ public class DDTracerFactory {
} }
//Create decorators from resource files //Create decorators from resource files
final List<DDSpanContextDecorator> decorators = DDDecoratorsFactory.createFromResources(); final List<AbstractDecorator> decorators = DDDecoratorsFactory.createFromResources();
for (final DDSpanContextDecorator decorator : decorators) { for (final AbstractDecorator decorator : decorators) {
tracer.addDecorator(decorator); tracer.addDecorator(decorator);
} }

View File

@ -4,9 +4,9 @@ decorators:
- type: HTTPComponent - type: HTTPComponent
matchingValue: java-okhttp matchingValue: java-okhttp
setValue: http-client setValue: http-client
- type: DBComponent
- type: HTTPComponent - type: HTTPComponent
matchingValue: java-aws-sdk matchingValue: java-aws-sdk
setValue: aws-client setValue: aws-client
# - type: DBStatementAsResourceName
- type: ErrorFlag - type: ErrorFlag
- type: DBTypeDecorator
- type: OperationDecorator

View File

@ -4,6 +4,7 @@ import com.datadoghq.trace.DDSpanContext
import com.datadoghq.trace.DDTracer import com.datadoghq.trace.DDTracer
import com.datadoghq.trace.SpanFactory import com.datadoghq.trace.SpanFactory
import io.opentracing.tag.StringTag import io.opentracing.tag.StringTag
import io.opentracing.tag.Tags
import spock.lang.Specification import spock.lang.Specification
class SpanDecoratorTest extends Specification { class SpanDecoratorTest extends Specification {
@ -11,7 +12,7 @@ class SpanDecoratorTest extends Specification {
def "adding span personalisation using Decorators"() { def "adding span personalisation using Decorators"() {
setup: setup:
def tracer = new DDTracer() def tracer = new DDTracer()
def decorator = new DDSpanContextDecorator() { def decorator = new AbstractDecorator() {
@Override @Override
boolean afterSetTag(DDSpanContext context, String tag, Object value) { boolean afterSetTag(DDSpanContext context, String tag, Object value) {
@ -32,4 +33,44 @@ class SpanDecoratorTest extends Specification {
span.getTags().containsKey("newFoo") span.getTags().containsKey("newFoo")
span.getTags().get("newFoo") == "newBar" span.getTags().get("newFoo") == "newBar"
} }
def "override operation with OperationDecorator"() {
setup:
def tracer = new DDTracer()
def span = SpanFactory.newSpanOf(tracer)
tracer.addDecorator(new OperationDecorator())
when:
Tags.COMPONENT.set(span, component)
then:
span.getOperationName() == operationName
where:
component << OperationDecorator.MAPPINGS.keySet()
operationName << OperationDecorator.MAPPINGS.values()
}
def "override operation with DBTypeDecorator"() {
setup:
def tracer = new DDTracer()
def span = SpanFactory.newSpanOf(tracer)
tracer.addDecorator(new DBTypeDecorator())
when:
Tags.DB_TYPE.set(span, type)
then:
span.getOperationName() == type + ".query"
span.context().getSpanType() == "db"
where:
type = "foo"
}
} }

View File

@ -3,7 +3,7 @@ package com.datadoghq.trace.resolver;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import com.datadoghq.trace.DDTracer; import com.datadoghq.trace.DDTracer;
import com.datadoghq.trace.integration.DDSpanContextDecorator; import com.datadoghq.trace.integration.AbstractDecorator;
import com.datadoghq.trace.integration.HTTPComponent; import com.datadoghq.trace.integration.HTTPComponent;
import com.datadoghq.trace.integration.URLAsResourceName; import com.datadoghq.trace.integration.URLAsResourceName;
import io.opentracing.NoopTracerFactory; import io.opentracing.NoopTracerFactory;
@ -19,17 +19,16 @@ public class TracerResolverTest {
@Test @Test
public void testResolve() { public void testResolve() {
DDTracerResolver tracerResolver = new DDTracerResolver(); final DDTracerResolver tracerResolver = new DDTracerResolver();
DDTracer tracer = (DDTracer) tracerResolver.resolve(); final DDTracer tracer = (DDTracer) tracerResolver.resolve();
// for HTTP decorators // for HTTP decorators
List<DDSpanContextDecorator> decorators = List<AbstractDecorator> decorators = tracer.getSpanContextDecorators(Tags.COMPONENT.getKey());
tracer.getSpanContextDecorators(Tags.COMPONENT.getKey());
assertThat(decorators.size()).isEqualTo(2); assertThat(decorators.size()).isEqualTo(2);
DDSpanContextDecorator decorator = decorators.get(0); AbstractDecorator decorator = decorators.get(0);
assertThat(decorator.getClass()).isEqualTo(HTTPComponent.class); assertThat(decorator.getClass()).isEqualTo(HTTPComponent.class);
HTTPComponent httpServiceDecorator = (HTTPComponent) decorator; final HTTPComponent httpServiceDecorator = (HTTPComponent) decorator;
assertThat(httpServiceDecorator.getMatchingTag()).isEqualTo("component"); assertThat(httpServiceDecorator.getMatchingTag()).isEqualTo("component");
assertThat(httpServiceDecorator.getMatchingValue()).isEqualTo("hello"); assertThat(httpServiceDecorator.getMatchingValue()).isEqualTo("hello");
assertThat(httpServiceDecorator.getSetValue()).isEqualTo("world"); assertThat(httpServiceDecorator.getSetValue()).isEqualTo("world");
@ -44,13 +43,13 @@ public class TracerResolverTest {
@Test @Test
public void testResolveTracer() throws Exception { public void testResolveTracer() throws Exception {
Field tracerField = GlobalTracer.class.getDeclaredField("tracer"); final Field tracerField = GlobalTracer.class.getDeclaredField("tracer");
tracerField.setAccessible(true); tracerField.setAccessible(true);
tracerField.set(null, NoopTracerFactory.create()); tracerField.set(null, NoopTracerFactory.create());
assertThat(GlobalTracer.isRegistered()).isFalse(); assertThat(GlobalTracer.isRegistered()).isFalse();
Tracer tracer = TracerResolver.resolveTracer(); final Tracer tracer = TracerResolver.resolveTracer();
assertThat(GlobalTracer.isRegistered()).isFalse(); assertThat(GlobalTracer.isRegistered()).isFalse();
assertThat(tracer).isInstanceOf(DDTracer.class); assertThat(tracer).isInstanceOf(DDTracer.class);
@ -58,7 +57,7 @@ public class TracerResolverTest {
@Test @Test
public void testRegisterTracer() throws Exception { public void testRegisterTracer() throws Exception {
Field tracerField = GlobalTracer.class.getDeclaredField("tracer"); final Field tracerField = GlobalTracer.class.getDeclaredField("tracer");
tracerField.setAccessible(true); tracerField.setAccessible(true);
tracerField.set(null, NoopTracerFactory.create()); tracerField.set(null, NoopTracerFactory.create());