[core] override operation name using decorators

This commit is contained in:
Guillaume Polaert 2017-07-28 11:46:04 +02:00 committed by Emanuele Palazzetti
parent b28327655e
commit 63cca28fe7
5 changed files with 90 additions and 76 deletions

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

@ -1,71 +0,0 @@
package com.datadoghq.trace.integration;
import com.datadoghq.trace.DDSpanContext;
import com.datadoghq.trace.DDTags;
/**
* Span decorators are called when new tags are written and proceed to various remappings and
* enrichments
*/
public abstract class DDSpanContextDecorator {
private String matchingTag;
private String matchingValue;
private String setTag;
private String setValue;
public boolean afterSetTag(DDSpanContext context, String tag, Object value) {
if ((this.getMatchingValue() == null || value.equals(this.getMatchingValue()))) {
String targetTag = getSetTag() == null ? tag : getSetTag();
String targetValue = getSetValue() == null ? String.valueOf(value) : getSetValue();
if (targetTag.equals(DDTags.SERVICE_NAME)) {
context.setServiceName(targetValue);
} else if (targetTag.equals(DDTags.RESOURCE_NAME)) {
context.setResourceName(targetValue);
} else if (targetTag.equals(DDTags.SPAN_TYPE)) {
context.setSpanType(targetValue);
} else {
context.setTag(targetTag, targetValue);
}
return true;
} else {
return false;
}
}
public String getMatchingTag() {
return matchingTag;
}
public void setMatchingTag(String tag) {
this.matchingTag = tag;
}
public String getMatchingValue() {
return matchingValue;
}
public void setMatchingValue(String value) {
this.matchingValue = value;
}
public String getSetTag() {
return setTag;
}
public void setSetTag(String targetTag) {
this.setTag = targetTag;
}
public String getSetValue() {
return setValue;
}
public void setSetValue(String targetValue) {
this.setValue = targetValue;
}
}

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

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

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"
}
} }