Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
2952299401
|
@ -1,17 +1,18 @@
|
||||||
# Decorators are used to add extra information to span
|
# Decorators are used to add extra information to span
|
||||||
# Could be DBServiceDecorator, MapperDecorator or HTTPServiceDecorator
|
# Could be DBServiceDecorator, MapperDecorator or HTTPServiceDecorator
|
||||||
decorators:
|
decorators:
|
||||||
- type: HTTP
|
- type: HTTPComponent
|
||||||
componentName: java-web-servlet
|
matchingValue: java-web-servlet
|
||||||
- type: HTTP
|
- type: HTTPComponent
|
||||||
componentName: java-okhttp
|
matchingValue: java-okhttp
|
||||||
desiredServiceName: http-client
|
setValue: http-client
|
||||||
- type: DB
|
- type: DBComponent
|
||||||
componentName: java-mongo
|
matchingValue: java-mongo
|
||||||
desiredServiceName: mongo
|
setValue: mongo
|
||||||
- type: DB
|
- type: DBComponent
|
||||||
componentName: java-jdbc
|
matchingValue: java-jdbc
|
||||||
desiredServiceName: jdbc
|
setValue: jdbc
|
||||||
- type: HTTP
|
- type: HTTPComponent
|
||||||
componentName: java-aws-sdk
|
matchingValue: java-aws-sdk
|
||||||
desiredServiceName: aws-client
|
setValue: aws-client
|
||||||
|
- type: URLAsResourceName
|
|
@ -1,53 +0,0 @@
|
||||||
package com.datadoghq.trace.integration;
|
|
||||||
|
|
||||||
import com.datadoghq.trace.DDSpanContext;
|
|
||||||
|
|
||||||
import io.opentracing.tag.Tags;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
public class DB implements DDSpanContextDecorator {
|
|
||||||
|
|
||||||
protected final String componentName;
|
|
||||||
protected final String desiredServiceName;
|
|
||||||
|
|
||||||
public DB(String componentName) {
|
|
||||||
super();
|
|
||||||
this.componentName = componentName;
|
|
||||||
this.desiredServiceName = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DB(String componentName,String desiredServiceName) {
|
|
||||||
super();
|
|
||||||
this.componentName = componentName;
|
|
||||||
this.desiredServiceName = desiredServiceName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterSetTag(DDSpanContext context, String tag, Object value) {
|
|
||||||
//Assign service name
|
|
||||||
if(tag.equals(Tags.COMPONENT.getKey()) && value.equals(componentName)){
|
|
||||||
if(desiredServiceName != null){
|
|
||||||
context.setServiceName(desiredServiceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Assign span type to DB
|
|
||||||
context.setSpanType("db");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Assign resource name
|
|
||||||
if(tag.equals(Tags.DB_STATEMENT.getKey())){
|
|
||||||
context.setResourceName(String.valueOf(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getComponentName() {
|
|
||||||
return componentName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDesiredServiceName() {
|
|
||||||
return desiredServiceName;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.datadoghq.trace.integration;
|
||||||
|
|
||||||
|
import com.datadoghq.trace.DDSpanContext;
|
||||||
|
import com.datadoghq.trace.DDTags;
|
||||||
|
|
||||||
|
import io.opentracing.tag.Tags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
public class DBComponent extends DDSpanContextDecorator {
|
||||||
|
|
||||||
|
public DBComponent() {
|
||||||
|
super();
|
||||||
|
this.setMatchingTag(Tags.COMPONENT.getKey());
|
||||||
|
this.setSetTag(DDTags.SERVICE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean afterSetTag(DDSpanContext context, String tag, Object value) {
|
||||||
|
//Assign service name
|
||||||
|
if(super.afterSetTag(context, tag, value)){
|
||||||
|
//Assign span type to DB
|
||||||
|
context.setSpanType("db");
|
||||||
|
|
||||||
|
//Assign resource name
|
||||||
|
if(tag.equals(Tags.DB_STATEMENT.getKey())){
|
||||||
|
context.setResourceName(String.valueOf(value));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,16 +5,56 @@ import com.datadoghq.trace.DDSpanContext;
|
||||||
/**
|
/**
|
||||||
* Span decorators are called when new tags are written and proceed to various remappings and enrichments
|
* Span decorators are called when new tags are written and proceed to various remappings and enrichments
|
||||||
*/
|
*/
|
||||||
public interface DDSpanContextDecorator {
|
public abstract class DDSpanContextDecorator {
|
||||||
|
|
||||||
/**
|
private String matchingTag;
|
||||||
* A tag was just added to the context. The decorator provides a way to enrich the context a bit more.
|
|
||||||
*
|
private String matchingValue;
|
||||||
* @param context the target context to decorate
|
|
||||||
* @param tag The tag set
|
private String setTag;
|
||||||
* @param value the value assigned to the tag
|
|
||||||
*/
|
private String setValue;
|
||||||
public void afterSetTag(DDSpanContext context , String tag, Object value);
|
|
||||||
|
public boolean afterSetTag(DDSpanContext context, String tag, Object value){
|
||||||
|
if(tag.equals(this.getMatchingTag()) && (this.getMatchingValue()==null || value.equals(this.getMatchingValue()))){
|
||||||
|
String targetTag = getSetTag()==null?tag:getSetTag();
|
||||||
|
String targetValue = getSetValue()==null?String.valueOf(value):getSetTag();
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,62 +0,0 @@
|
||||||
package com.datadoghq.trace.integration;
|
|
||||||
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
import com.datadoghq.trace.DDSpanContext;
|
|
||||||
|
|
||||||
import io.opentracing.tag.Tags;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
public class HTTP implements DDSpanContextDecorator {
|
|
||||||
|
|
||||||
protected final String componentName;
|
|
||||||
protected final String desiredServiceName;
|
|
||||||
|
|
||||||
public HTTP(String componentName) {
|
|
||||||
super();
|
|
||||||
this.componentName = componentName;
|
|
||||||
this.desiredServiceName = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HTTP(String componentName,String desiredServiceName) {
|
|
||||||
super();
|
|
||||||
this.componentName = componentName;
|
|
||||||
this.desiredServiceName = desiredServiceName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterSetTag(DDSpanContext context, String tag, Object value) {
|
|
||||||
//Assign service name
|
|
||||||
if(tag.equals(Tags.COMPONENT.getKey()) && value.equals(componentName)){
|
|
||||||
if(desiredServiceName != null){
|
|
||||||
context.setServiceName(desiredServiceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Assign span type to WEB
|
|
||||||
context.setSpanType("web");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Assign resource name
|
|
||||||
if(tag.equals(Tags.HTTP_URL.getKey())){
|
|
||||||
try {
|
|
||||||
String path = new URL(String.valueOf(value)).getPath();
|
|
||||||
context.setResourceName(path);
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
context.setResourceName(String.valueOf(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getComponentName() {
|
|
||||||
return componentName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDesiredServiceName() {
|
|
||||||
return desiredServiceName;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.datadoghq.trace.integration;
|
||||||
|
|
||||||
|
import com.datadoghq.trace.DDSpanContext;
|
||||||
|
import com.datadoghq.trace.DDTags;
|
||||||
|
|
||||||
|
import io.opentracing.tag.Tags;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
public class HTTPComponent extends DDSpanContextDecorator {
|
||||||
|
|
||||||
|
public HTTPComponent() {
|
||||||
|
super();
|
||||||
|
this.setMatchingTag(Tags.COMPONENT.getKey());
|
||||||
|
this.setSetTag(DDTags.SERVICE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean afterSetTag(DDSpanContext context, String tag, Object value) {
|
||||||
|
//Assign service name
|
||||||
|
if(super.afterSetTag(context, tag, value)){
|
||||||
|
//Assign span type to WEB
|
||||||
|
context.setSpanType("web");
|
||||||
|
return true;
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,37 +0,0 @@
|
||||||
package com.datadoghq.trace.integration;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.datadoghq.trace.DDSpanContext;
|
|
||||||
import com.datadoghq.trace.DDTags;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a generic decorator, it remaps some tags to other tags
|
|
||||||
*/
|
|
||||||
public class MapperDecorator implements DDSpanContextDecorator {
|
|
||||||
|
|
||||||
private final Map<String,String> mappings;
|
|
||||||
|
|
||||||
public MapperDecorator(Map<String, String> mappings) {
|
|
||||||
super();
|
|
||||||
this.mappings = mappings;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterSetTag(DDSpanContext context, String tag, Object value) {
|
|
||||||
String toAssign = mappings.get(tag);
|
|
||||||
if(toAssign != null){
|
|
||||||
if(toAssign.equals(DDTags.SPAN_TYPE)){
|
|
||||||
context.setSpanType(String.valueOf(value));
|
|
||||||
}else if(toAssign.equals(DDTags.SERVICE_NAME)){
|
|
||||||
context.setServiceName(String.valueOf(value));
|
|
||||||
}else if(toAssign.equals(DDTags.RESOURCE_NAME)){
|
|
||||||
context.setResourceName(String.valueOf(value));
|
|
||||||
}else{
|
|
||||||
//General remap
|
|
||||||
context.setTag(toAssign, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.datadoghq.trace.integration;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
|
||||||
|
import com.datadoghq.trace.DDSpanContext;
|
||||||
|
import com.datadoghq.trace.DDTags;
|
||||||
|
|
||||||
|
import io.opentracing.tag.Tags;
|
||||||
|
|
||||||
|
public class URLAsResourceName extends DDSpanContextDecorator {
|
||||||
|
|
||||||
|
public URLAsResourceName() {
|
||||||
|
super();
|
||||||
|
this.setMatchingTag(Tags.HTTP_URL.getKey());
|
||||||
|
this.setSetTag(DDTags.RESOURCE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean afterSetTag(DDSpanContext context, String tag, Object value) {
|
||||||
|
//Assign resource name
|
||||||
|
if(tag.equals(Tags.HTTP_URL.getKey())){
|
||||||
|
try {
|
||||||
|
String path = new java.net.URL(String.valueOf(value)).getPath();
|
||||||
|
context.setTag(this.getSetTag(),path);
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
context.setResourceName(String.valueOf(value));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package com.datadoghq.trace.resolver;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.datadoghq.trace.integration.DDSpanContextDecorator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create DDSpaDecorators from a valid configuration
|
||||||
|
*/
|
||||||
|
public class DDDecoratorsFactory {
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(DDDecoratorsFactory.class);
|
||||||
|
|
||||||
|
public static String DECORATORS_PACKAGE = "com.datadoghq.trace.integration.";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create decorators from configuration
|
||||||
|
*
|
||||||
|
* @param decoratorsConfig
|
||||||
|
* @return the list of instanciated & configured decorators
|
||||||
|
*/
|
||||||
|
public static List<DDSpanContextDecorator> create(List<DDSpanDecoratorConfig> decoratorsConfig){
|
||||||
|
List<DDSpanContextDecorator> decorators = new ArrayList<DDSpanContextDecorator>();
|
||||||
|
for (DDSpanDecoratorConfig decoratorConfig : decoratorsConfig) {
|
||||||
|
if(decoratorConfig.getType()==null){
|
||||||
|
logger.warn("Cannot create decorator without type from configuration {}",decoratorConfig);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Find class and create
|
||||||
|
Class<?> decoratorClass;
|
||||||
|
try {
|
||||||
|
decoratorClass = Class.forName(DECORATORS_PACKAGE+decoratorConfig.getType());
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
logger.warn("Cannot create decorator as the class {} is not defined. Provided configuration {}",decoratorConfig);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
DDSpanContextDecorator decorator = null;
|
||||||
|
try{
|
||||||
|
decorator = (DDSpanContextDecorator) decoratorClass.getConstructor().newInstance();
|
||||||
|
}catch(Exception e){
|
||||||
|
logger.warn("Cannot create decorator as we could not invoke the default constructor. Provided configuration {}",decoratorConfig);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Fill with config values
|
||||||
|
if(decoratorConfig.getMatchingTag()!=null){
|
||||||
|
decorator.setMatchingTag(decoratorConfig.getMatchingTag());
|
||||||
|
}
|
||||||
|
if(decoratorConfig.getMatchingValue()!=null){
|
||||||
|
decorator.setMatchingValue(decoratorConfig.getMatchingValue());
|
||||||
|
}
|
||||||
|
if(decoratorConfig.getSetTag()!=null){
|
||||||
|
decorator.setSetTag(decoratorConfig.getSetTag());
|
||||||
|
}
|
||||||
|
if(decoratorConfig.getSetValue()!=null){
|
||||||
|
decorator.setSetValue(decoratorConfig.getSetValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
decorators.add(decorator);
|
||||||
|
}
|
||||||
|
return decorators;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
package com.datadoghq.trace.resolver;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DDSpanDecoratorConfig {
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
private String matchingTag;
|
||||||
|
|
||||||
|
private String matchingValue;
|
||||||
|
|
||||||
|
private String setTag;
|
||||||
|
|
||||||
|
private String setValue;
|
||||||
|
|
||||||
|
public String getMatchingTag() {
|
||||||
|
return matchingTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMatchingTag(String matchingTag) {
|
||||||
|
this.matchingTag = matchingTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMatchingValue() {
|
||||||
|
return matchingValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMatchingValue(String matchingValue) {
|
||||||
|
this.matchingValue = matchingValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSetTag() {
|
||||||
|
return setTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSetTag(String setTag) {
|
||||||
|
this.setTag = setTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSetValue() {
|
||||||
|
return setValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSetValue(String setValue) {
|
||||||
|
this.setValue = setValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
try {
|
||||||
|
return new ObjectMapper(new YAMLFactory()).writeValueAsString(this);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package com.datadoghq.trace.resolver;
|
||||||
|
|
||||||
|
import com.datadoghq.trace.DDTracer;
|
||||||
|
import com.datadoghq.trace.sampling.AllSampler;
|
||||||
|
import com.datadoghq.trace.sampling.RateSampler;
|
||||||
|
import com.datadoghq.trace.sampling.Sampler;
|
||||||
|
import com.datadoghq.trace.writer.DDAgentWriter;
|
||||||
|
import com.datadoghq.trace.writer.DDApi;
|
||||||
|
import com.datadoghq.trace.writer.LoggingWritter;
|
||||||
|
import com.datadoghq.trace.writer.Writer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a tracer from a configuration file
|
||||||
|
*/
|
||||||
|
public class DDTracerFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a tracer from a TracerConfig object
|
||||||
|
*
|
||||||
|
* @param config
|
||||||
|
* @return the corresponding tracer
|
||||||
|
*/
|
||||||
|
public static DDTracer create(TracerConfig config){
|
||||||
|
String defaultServiceName = config.getDefaultServiceName() != null ? config.getDefaultServiceName() : DDTracer.UNASSIGNED_DEFAULT_SERVICE_NAME;
|
||||||
|
|
||||||
|
//Create writer
|
||||||
|
Writer writer = DDTracer.UNASSIGNED_WRITER;
|
||||||
|
if (config.getWriter() != null && config.getWriter().get("type") != null) {
|
||||||
|
String type = (String) config.getWriter().get("type");
|
||||||
|
if (type.equals(DDAgentWriter.class.getSimpleName())) {
|
||||||
|
String host = config.getWriter().get("host") != null ? (String) config.getWriter().get("host") : DDAgentWriter.DEFAULT_HOSTNAME;
|
||||||
|
Integer port = config.getWriter().get("port") != null ? (Integer) config.getWriter().get("port") : DDAgentWriter.DEFAULT_PORT;
|
||||||
|
DDApi api = new DDApi(host, port);
|
||||||
|
writer = new DDAgentWriter(api);
|
||||||
|
} else if (type.equals(LoggingWritter.class.getSimpleName())) {
|
||||||
|
writer = new LoggingWritter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create sampler
|
||||||
|
Sampler rateSampler = DDTracer.UNASSIGNED_SAMPLER;
|
||||||
|
if (config.getSampler() != null && config.getSampler().get("type") != null) {
|
||||||
|
String type = (String) config.getSampler().get("type");
|
||||||
|
if (type.equals(AllSampler.class.getSimpleName())) {
|
||||||
|
rateSampler = new AllSampler();
|
||||||
|
} else if (type.equals(RateSampler.class.getSimpleName())) {
|
||||||
|
rateSampler = new RateSampler((Double) config.getSampler().get("rate"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create tracer
|
||||||
|
return new DDTracer(defaultServiceName, writer, rateSampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,23 +3,13 @@ package com.datadoghq.trace.resolver;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.datadoghq.trace.DDTracer;
|
import com.datadoghq.trace.DDTracer;
|
||||||
import com.datadoghq.trace.integration.DB;
|
|
||||||
import com.datadoghq.trace.integration.DDSpanContextDecorator;
|
import com.datadoghq.trace.integration.DDSpanContextDecorator;
|
||||||
import com.datadoghq.trace.integration.HTTP;
|
|
||||||
import com.datadoghq.trace.sampling.AllSampler;
|
|
||||||
import com.datadoghq.trace.sampling.RateSampler;
|
|
||||||
import com.datadoghq.trace.sampling.Sampler;
|
|
||||||
import com.datadoghq.trace.writer.DDAgentWriter;
|
|
||||||
import com.datadoghq.trace.writer.DDApi;
|
|
||||||
import com.datadoghq.trace.writer.LoggingWritter;
|
|
||||||
import com.datadoghq.trace.writer.Writer;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
|
@ -52,35 +42,7 @@ public class DDTracerResolver extends TracerResolver {
|
||||||
while (iter.hasMoreElements()) {
|
while (iter.hasMoreElements()) {
|
||||||
TracerConfig config = objectMapper.readValue(iter.nextElement().openStream(), TracerConfig.class);
|
TracerConfig config = objectMapper.readValue(iter.nextElement().openStream(), TracerConfig.class);
|
||||||
|
|
||||||
String defaultServiceName = config.getDefaultServiceName() != null ? config.getDefaultServiceName() : DDTracer.UNASSIGNED_DEFAULT_SERVICE_NAME;
|
tracer = DDTracerFactory.create(config);
|
||||||
|
|
||||||
//Create writer
|
|
||||||
Writer writer = DDTracer.UNASSIGNED_WRITER;
|
|
||||||
if (config.getWriter() != null && config.getWriter().get("type") != null) {
|
|
||||||
String type = (String) config.getWriter().get("type");
|
|
||||||
if (type.equals(DDAgentWriter.class.getSimpleName())) {
|
|
||||||
String host = config.getWriter().get("host") != null ? (String) config.getWriter().get("host") : DDAgentWriter.DEFAULT_HOSTNAME;
|
|
||||||
Integer port = config.getWriter().get("port") != null ? (Integer) config.getWriter().get("port") : DDAgentWriter.DEFAULT_PORT;
|
|
||||||
DDApi api = new DDApi(host, port);
|
|
||||||
writer = new DDAgentWriter(api);
|
|
||||||
} else if (type.equals(LoggingWritter.class.getSimpleName())) {
|
|
||||||
writer = new LoggingWritter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Create sampler
|
|
||||||
Sampler rateSampler = DDTracer.UNASSIGNED_SAMPLER;
|
|
||||||
if (config.getSampler() != null && config.getSampler().get("type") != null) {
|
|
||||||
String type = (String) config.getSampler().get("type");
|
|
||||||
if (type.equals(AllSampler.class.getSimpleName())) {
|
|
||||||
rateSampler = new AllSampler();
|
|
||||||
} else if (type.equals(RateSampler.class.getSimpleName())) {
|
|
||||||
rateSampler = new RateSampler((Double) config.getSampler().get("rate"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Create tracer
|
|
||||||
tracer = new DDTracer(defaultServiceName, writer, rateSampler);
|
|
||||||
|
|
||||||
break; // ONLY the closest resource file is taken into account
|
break; // ONLY the closest resource file is taken into account
|
||||||
}
|
}
|
||||||
|
@ -90,20 +52,8 @@ public class DDTracerResolver extends TracerResolver {
|
||||||
TracerConfig config = objectMapper.readValue(iter.nextElement().openStream(), TracerConfig.class);
|
TracerConfig config = objectMapper.readValue(iter.nextElement().openStream(), TracerConfig.class);
|
||||||
//Find decorators
|
//Find decorators
|
||||||
if (config.getDecorators() != null) {
|
if (config.getDecorators() != null) {
|
||||||
for (Map<String, Object> map : config.getDecorators()) {
|
for(DDSpanContextDecorator decorator:DDDecoratorsFactory.create(config.getDecorators())){
|
||||||
if (map.get("type") != null) {
|
tracer.addDecorator(decorator);
|
||||||
DDSpanContextDecorator decorator = null;
|
|
||||||
String componentName = (String) map.get("componentName");
|
|
||||||
String desiredServiceName = (String) map.get("desiredServiceName");
|
|
||||||
|
|
||||||
if (map.get("type").equals(HTTP.class.getSimpleName())) {
|
|
||||||
decorator = new HTTP(componentName, desiredServiceName);
|
|
||||||
tracer.addDecorator(decorator);
|
|
||||||
} else if (map.get("type").equals(DB.class.getSimpleName())) {
|
|
||||||
decorator = new DB(componentName, desiredServiceName);
|
|
||||||
tracer.addDecorator(decorator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,10 @@ package com.datadoghq.trace.resolver;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tracer configuration
|
* Tracer configuration
|
||||||
*/
|
*/
|
||||||
|
@ -10,7 +14,7 @@ public class TracerConfig {
|
||||||
private String defaultServiceName;
|
private String defaultServiceName;
|
||||||
private Map<String,Object> writer;
|
private Map<String,Object> writer;
|
||||||
private Map<String,Object> sampler;
|
private Map<String,Object> sampler;
|
||||||
private List<Map<String,Object>> decorators;
|
private List<DDSpanDecoratorConfig> decorators;
|
||||||
|
|
||||||
public String getDefaultServiceName() {
|
public String getDefaultServiceName() {
|
||||||
return defaultServiceName;
|
return defaultServiceName;
|
||||||
|
@ -30,10 +34,20 @@ public class TracerConfig {
|
||||||
public void setSampler(Map<String, Object> sampler) {
|
public void setSampler(Map<String, Object> sampler) {
|
||||||
this.sampler = sampler;
|
this.sampler = sampler;
|
||||||
}
|
}
|
||||||
public List<Map<String, Object>> getDecorators() {
|
public List<DDSpanDecoratorConfig> getDecorators() {
|
||||||
return decorators;
|
return decorators;
|
||||||
}
|
}
|
||||||
public void setDecorators(List<Map<String, Object>> decorators) {
|
public void setDecorators(List<DDSpanDecoratorConfig> decorators) {
|
||||||
this.decorators = decorators;
|
this.decorators = decorators;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
try {
|
||||||
|
return new ObjectMapper(new YAMLFactory()).writeValueAsString(this);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
//FIXME better toString() while config object stabilized
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
# Decorators are used to add extra information to span
|
|
||||||
# Could be DBServiceDecorator, MapperDecorator or HTTPServiceDecorator
|
|
||||||
decorators:
|
|
||||||
# This span decorator leverages HTTP tags such as the URL requested
|
|
||||||
- type: HTTP
|
|
||||||
componentName: http
|
|
||||||
desiredServiceName: unnamed-java-http
|
|
||||||
# This span decorator leverages DB tags such as the statement requested
|
|
||||||
- type: DB
|
|
||||||
componentName: db
|
|
||||||
desiredServiceName: unnamed-java-db
|
|
|
@ -1,21 +0,0 @@
|
||||||
# Service name used if none is provided in the app
|
|
||||||
defaultServiceName: unnamed-java-app
|
|
||||||
|
|
||||||
# The writer to use.
|
|
||||||
# Could be: LoggingWritter or DDAgentWriter (default)
|
|
||||||
writer:
|
|
||||||
# LoggingWriter: Spans are logged using the application configuration
|
|
||||||
# DDAgentWriter: Spans are forwarding to a Datadog Agent
|
|
||||||
# - Param 'host': the hostname where the DD Agent running (default: localhost)
|
|
||||||
# - Param 'port': the port to reach the DD Agent (default: 8126)
|
|
||||||
type: DDAgentWriter
|
|
||||||
host: localhost
|
|
||||||
port: 8126
|
|
||||||
|
|
||||||
# The sampler to use.
|
|
||||||
# Could be: AllSampler (default) or RateSampler
|
|
||||||
sampler:
|
|
||||||
# AllSampler: all spans are reported to the writer
|
|
||||||
# RateSample: only a portion of spans are reported to the writer
|
|
||||||
# - Param 'rate': the portion of spans to keep
|
|
||||||
type: AllSampler
|
|
|
@ -8,7 +8,8 @@ import org.junit.Test;
|
||||||
|
|
||||||
import com.datadoghq.trace.DDTracer;
|
import com.datadoghq.trace.DDTracer;
|
||||||
import com.datadoghq.trace.integration.DDSpanContextDecorator;
|
import com.datadoghq.trace.integration.DDSpanContextDecorator;
|
||||||
import com.datadoghq.trace.integration.HTTP;
|
import com.datadoghq.trace.integration.HTTPComponent;
|
||||||
|
import com.datadoghq.trace.integration.URLAsResourceName;
|
||||||
|
|
||||||
public class TracerResolverTest {
|
public class TracerResolverTest {
|
||||||
|
|
||||||
|
@ -19,12 +20,18 @@ public class TracerResolverTest {
|
||||||
|
|
||||||
List<DDSpanContextDecorator> decorators = tracer.getSpanContextDecorators();
|
List<DDSpanContextDecorator> decorators = tracer.getSpanContextDecorators();
|
||||||
|
|
||||||
assertThat(decorators.size()).isEqualTo(1);
|
assertThat(decorators.size()).isEqualTo(2);
|
||||||
DDSpanContextDecorator decorator = decorators.get(0);
|
DDSpanContextDecorator decorator = decorators.get(0);
|
||||||
assertThat(decorator.getClass()).isEqualTo(HTTP.class);
|
assertThat(decorator.getClass()).isEqualTo(HTTPComponent.class);
|
||||||
HTTP httpServiceDecorator = (HTTP) decorator;
|
HTTPComponent httpServiceDecorator = (HTTPComponent) decorator;
|
||||||
assertThat(httpServiceDecorator.getComponentName()).isEqualTo("hello");
|
|
||||||
assertThat(httpServiceDecorator.getDesiredServiceName()).isEqualTo("world");
|
assertThat(httpServiceDecorator.getMatchingTag()).isEqualTo("component");
|
||||||
|
assertThat(httpServiceDecorator.getMatchingValue()).isEqualTo("hello");
|
||||||
|
assertThat(httpServiceDecorator.getSetValue()).isEqualTo("world");
|
||||||
|
|
||||||
|
decorator = decorators.get(1);
|
||||||
|
assertThat(decorator.getClass()).isEqualTo(URLAsResourceName.class);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
decorators:
|
decorators:
|
||||||
- type: HTTP
|
- type: HTTPComponent
|
||||||
componentName: hello
|
matchingValue: hello
|
||||||
desiredServiceName: world
|
setValue: world
|
||||||
|
- type: URLAsResourceName
|
Loading…
Reference in New Issue