From 26342e48d99f96b4b1cf0c54f65af33c8b010084 Mon Sep 17 00:00:00 2001 From: renaudboutet Date: Mon, 29 May 2017 19:17:44 +0200 Subject: [PATCH] Fix refactored decorators + ErrorFlag + DBStatement decorator + DDapi is streaming JSON (optim) --- .../main/resources/dd-trace-decorators.yaml | 6 +-- .../src/main/resources/dd-trace.yaml | 24 ++++++++++++ .../com/datadoghq/trace/DDSpanContext.java | 11 ++++-- .../java/com/datadoghq/trace/DDTracer.java | 5 +-- .../trace/integration/DBComponent.java | 3 -- .../DBStatementAsResourceName.java | 14 +++++++ .../integration/DDSpanContextDecorator.java | 14 ++++++- .../trace/integration/ErrorFlag.java | 24 ++++++++++++ .../trace/integration/HTTPComponent.java | 1 - .../trace/integration/URLAsResourceName.java | 2 +- .../trace/resolver/TracerConfig.java | 2 + .../com/datadoghq/trace/writer/DDApi.java | 38 +++++++------------ 12 files changed, 103 insertions(+), 41 deletions(-) create mode 100644 dd-trace-examples/dropwizard-mongo-client/src/main/resources/dd-trace.yaml create mode 100644 dd-trace/src/main/java/com/datadoghq/trace/integration/DBStatementAsResourceName.java create mode 100644 dd-trace/src/main/java/com/datadoghq/trace/integration/ErrorFlag.java diff --git a/dd-java-agent/src/main/resources/dd-trace-decorators.yaml b/dd-java-agent/src/main/resources/dd-trace-decorators.yaml index 07e079136c..31a9a50c6c 100644 --- a/dd-java-agent/src/main/resources/dd-trace-decorators.yaml +++ b/dd-java-agent/src/main/resources/dd-trace-decorators.yaml @@ -1,8 +1,6 @@ # Decorators are used to add extra information to span # Could be DBServiceDecorator, MapperDecorator or HTTPServiceDecorator decorators: - - type: HTTPComponent - matchingValue: java-web-servlet - type: HTTPComponent matchingValue: java-okhttp setValue: http-client @@ -15,4 +13,6 @@ decorators: - type: HTTPComponent matchingValue: java-aws-sdk setValue: aws-client - - type: URLAsResourceName \ No newline at end of file + - type: URLAsResourceName + - type: DBStatementAsResourceName + - type: ErrorFlag \ No newline at end of file diff --git a/dd-trace-examples/dropwizard-mongo-client/src/main/resources/dd-trace.yaml b/dd-trace-examples/dropwizard-mongo-client/src/main/resources/dd-trace.yaml new file mode 100644 index 0000000000..de87340c4b --- /dev/null +++ b/dd-trace-examples/dropwizard-mongo-client/src/main/resources/dd-trace.yaml @@ -0,0 +1,24 @@ +# Service name used if none is provided in the app +defaultServiceName: 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 + +# Enable custom tracing (annotations) +enableCustomTracing: true \ No newline at end of file diff --git a/dd-trace/src/main/java/com/datadoghq/trace/DDSpanContext.java b/dd-trace/src/main/java/com/datadoghq/trace/DDSpanContext.java index 7056a9db25..4b9fe0f41d 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/DDSpanContext.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/DDSpanContext.java @@ -36,6 +36,7 @@ public class DDSpanContext implements io.opentracing.SpanContext { * True indicates that the span reports an error */ private boolean errorFlag; + /** * The type of the span. If null, the Datadog Agent will report as a custom */ @@ -123,7 +124,10 @@ public class DDSpanContext implements io.opentracing.SpanContext { public boolean getErrorFlag() { return errorFlag; } - + + public void setErrorFlag(boolean errorFlag) { + this.errorFlag = errorFlag; + } public String getSpanType() { return spanType; @@ -175,8 +179,9 @@ public class DDSpanContext implements io.opentracing.SpanContext { this.tags.put(tag, value); //Call decorators - if (tracer.getSpanContextDecorators(tag) != null) { - for (DDSpanContextDecorator decorator : tracer.getSpanContextDecorators(tag)) { + List decorators = tracer.getSpanContextDecorators(tag); + if (decorators != null) { + for (DDSpanContextDecorator decorator : decorators) { decorator.afterSetTag(this, tag, value); } } diff --git a/dd-trace/src/main/java/com/datadoghq/trace/DDTracer.java b/dd-trace/src/main/java/com/datadoghq/trace/DDTracer.java index da5c2fbba0..778b95d4da 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/DDTracer.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/DDTracer.java @@ -78,10 +78,7 @@ public class DDTracer implements io.opentracing.Tracer { * @return the list of span context decorators */ public List getSpanContextDecorators(String tag) { - - List decorators = spanContextDecorators.get(tag); - - return decorators; + return spanContextDecorators.get(tag); } /** diff --git a/dd-trace/src/main/java/com/datadoghq/trace/integration/DBComponent.java b/dd-trace/src/main/java/com/datadoghq/trace/integration/DBComponent.java index 04040d9cd4..c2d19263ec 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/integration/DBComponent.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/integration/DBComponent.java @@ -22,9 +22,6 @@ public class DBComponent extends DDSpanContextDecorator { if (super.afterSetTag(context, tag, value)) { //Assign span type to DB context.setSpanType("db"); - - //Assign resource name - context.setResourceName(String.valueOf(value)); return true; } return false; diff --git a/dd-trace/src/main/java/com/datadoghq/trace/integration/DBStatementAsResourceName.java b/dd-trace/src/main/java/com/datadoghq/trace/integration/DBStatementAsResourceName.java new file mode 100644 index 0000000000..87f55983f1 --- /dev/null +++ b/dd-trace/src/main/java/com/datadoghq/trace/integration/DBStatementAsResourceName.java @@ -0,0 +1,14 @@ +package com.datadoghq.trace.integration; + +import com.datadoghq.trace.DDTags; + +import io.opentracing.tag.Tags; + +public class DBStatementAsResourceName extends DDSpanContextDecorator { + + public DBStatementAsResourceName() { + super(); + this.setMatchingTag(Tags.DB_STATEMENT.getKey()); + this.setSetTag(DDTags.RESOURCE_NAME); + } +} diff --git a/dd-trace/src/main/java/com/datadoghq/trace/integration/DDSpanContextDecorator.java b/dd-trace/src/main/java/com/datadoghq/trace/integration/DDSpanContextDecorator.java index e46f5269e9..14f0587306 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/integration/DDSpanContextDecorator.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/integration/DDSpanContextDecorator.java @@ -1,6 +1,7 @@ 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 @@ -18,8 +19,17 @@ public abstract class DDSpanContextDecorator { 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) : getSetTag(); - context.setTag(targetTag, targetValue); + 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; diff --git a/dd-trace/src/main/java/com/datadoghq/trace/integration/ErrorFlag.java b/dd-trace/src/main/java/com/datadoghq/trace/integration/ErrorFlag.java new file mode 100644 index 0000000000..b6e7a32bc8 --- /dev/null +++ b/dd-trace/src/main/java/com/datadoghq/trace/integration/ErrorFlag.java @@ -0,0 +1,24 @@ +package com.datadoghq.trace.integration; + +import com.datadoghq.trace.DDSpanContext; + +import io.opentracing.tag.Tags; + +public class ErrorFlag extends DDSpanContextDecorator { + + public ErrorFlag() { + super(); + this.setMatchingTag(Tags.DB_STATEMENT.getKey()); + } + + @Override + public boolean afterSetTag(DDSpanContext context, String tag, Object value) { + //Assign resource name + try{ + context.setErrorFlag(Boolean.parseBoolean(String.valueOf(value))); + }catch(Throwable t){ + //DO NOTHING + } + return true; + } +} diff --git a/dd-trace/src/main/java/com/datadoghq/trace/integration/HTTPComponent.java b/dd-trace/src/main/java/com/datadoghq/trace/integration/HTTPComponent.java index 8371153747..5b7fdd9924 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/integration/HTTPComponent.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/integration/HTTPComponent.java @@ -21,7 +21,6 @@ public class HTTPComponent extends DDSpanContextDecorator { 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; diff --git a/dd-trace/src/main/java/com/datadoghq/trace/integration/URLAsResourceName.java b/dd-trace/src/main/java/com/datadoghq/trace/integration/URLAsResourceName.java index d244abc1dc..1307f06848 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/integration/URLAsResourceName.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/integration/URLAsResourceName.java @@ -19,7 +19,7 @@ public class URLAsResourceName extends DDSpanContextDecorator { //Assign resource name try { String path = new java.net.URL(String.valueOf(value)).getPath(); - context.setTag(this.getSetTag(), path); + context.setResourceName(path); } catch (MalformedURLException e) { context.setResourceName(String.valueOf(value)); } diff --git a/dd-trace/src/main/java/com/datadoghq/trace/resolver/TracerConfig.java b/dd-trace/src/main/java/com/datadoghq/trace/resolver/TracerConfig.java index f8fa3c9aec..029bc5acaf 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/resolver/TracerConfig.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/resolver/TracerConfig.java @@ -3,6 +3,7 @@ package com.datadoghq.trace.resolver; import java.util.List; import java.util.Map; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; @@ -10,6 +11,7 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; /** * Tracer configuration */ +@JsonIgnoreProperties(ignoreUnknown = true) public class TracerConfig { private String defaultServiceName; private Map writer; diff --git a/dd-trace/src/main/java/com/datadoghq/trace/writer/DDApi.java b/dd-trace/src/main/java/com/datadoghq/trace/writer/DDApi.java index 8d491e0bb8..1c10f950ed 100644 --- a/dd-trace/src/main/java/com/datadoghq/trace/writer/DDApi.java +++ b/dd-trace/src/main/java/com/datadoghq/trace/writer/DDApi.java @@ -8,6 +8,10 @@ import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.ObjectMapper; + import io.opentracing.Span; /** @@ -22,21 +26,13 @@ public class DDApi { private final String tracesEndpoint; // private final String servicesEndpoint; - - /** - * The spans serializer: can be replaced. By default, it serialize in JSON. - */ - private final DDSpanSerializer spanSerializer; + + private final ObjectMapper objectMapper = new ObjectMapper(); + private final JsonFactory jsonFactory = objectMapper.getFactory(); public DDApi(String host, int port) { - this(host, port, new DDSpanSerializer()); - } - - public DDApi(String host, int port, DDSpanSerializer spanSerializer) { - super(); this.tracesEndpoint = "http://" + host + ":" + port + TRACES_ENDPOINT; -// this.servicesEndpoint = "http://" + host + ":" + port + SERVICES_ENDPOINT; - this.spanSerializer = spanSerializer; +// this.servicesEndpoint = "http://" + host + ":" + port + SERVICES_ENDPOINT; } /** @@ -46,15 +42,7 @@ public class DDApi { * @return the staus code returned */ public boolean sendTraces(List> traces) { - String payload = null; - try { - payload = spanSerializer.serialize(traces); - } catch (Exception e) { - logger.error("Error during serialization of " + traces.size() + " traces.", e); - return false; - } - - int status = callPUT(tracesEndpoint, payload); + int status = callPUT(tracesEndpoint, traces); if (status == 200) { logger.debug("Succesfully sent {} traces to the DD agent.", traces.size()); return true; @@ -71,7 +59,7 @@ public class DDApi { * @param content * @return the status code */ - private int callPUT(String endpoint, String content) { + private int callPUT(String endpoint, Object content) { HttpURLConnection httpCon = null; try { URL url = new URL(endpoint); @@ -86,8 +74,10 @@ public class DDApi { try { OutputStreamWriter out = new OutputStreamWriter(httpCon.getOutputStream()); - out.write(content); - out.close(); + JsonGenerator jsonGen = jsonFactory.createGenerator(out); + objectMapper.writeValue(jsonGen, content); + jsonGen.flush(); + jsonGen.close(); int responseCode = httpCon.getResponseCode(); if (responseCode == 200) { logger.debug("Sent the payload to the DD agent.");