commit
e6b086ac4c
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Uber Technologies, Inc
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package com.datadoghq.trace;
|
||||
|
||||
|
||||
import com.datadoghq.trace.impl.DDSpanContext;
|
||||
|
||||
public interface Codec<T> {
|
||||
|
||||
void inject(DDSpanContext context, T carrier);
|
||||
|
||||
DDSpanContext extract(T carrier);
|
||||
}
|
|
@ -118,7 +118,13 @@ public class DDSpan implements io.opentracing.Span {
|
|||
* @return true if root, false otherwise
|
||||
*/
|
||||
private boolean isRootSpan() {
|
||||
return context.getTraceId() == context.getSpanId();
|
||||
|
||||
if (context().getTrace().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
// First item of the array AND tracer set
|
||||
DDSpan first = (DDSpan) context().getTrace().get(0);
|
||||
return first.context.getSpanId() == this.context.getSpanId() && this.context.getTracer() != null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
|
|
@ -9,14 +9,17 @@ import java.util.Map;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.datadoghq.trace.Codec;
|
||||
import com.datadoghq.trace.Sampler;
|
||||
import com.datadoghq.trace.Writer;
|
||||
import com.datadoghq.trace.propagation.impl.HTTPCodec;
|
||||
import com.datadoghq.trace.writer.impl.LoggingWritter;
|
||||
|
||||
import io.opentracing.Span;
|
||||
import io.opentracing.SpanContext;
|
||||
import io.opentracing.propagation.Format;
|
||||
|
||||
|
||||
/**
|
||||
* DDTracer makes it easy to send traces and span to DD using the OpenTracing instrumentation.
|
||||
*/
|
||||
|
@ -38,6 +41,7 @@ public class DDTracer implements io.opentracing.Tracer {
|
|||
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(DDTracer.class);
|
||||
private final CodecRegistry registry;
|
||||
|
||||
/**
|
||||
* Default constructor, trace/spans are logged, no trace/span dropped
|
||||
|
@ -49,9 +53,10 @@ public class DDTracer implements io.opentracing.Tracer {
|
|||
public DDTracer(Writer writer, Sampler sampler) {
|
||||
this.writer = writer;
|
||||
this.sampler = sampler;
|
||||
registry = new CodecRegistry();
|
||||
registry.register(Format.Builtin.HTTP_HEADERS, new HTTPCodec());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the list of span context decorators
|
||||
*
|
||||
|
@ -74,14 +79,25 @@ public class DDTracer implements io.opentracing.Tracer {
|
|||
return new DDSpanBuilder(operationName);
|
||||
}
|
||||
|
||||
public <C> void inject(SpanContext spanContext, Format<C> format, C c) {
|
||||
//FIXME Implement it ASAP
|
||||
logger.warn("Method `inject` not implemented yet");
|
||||
|
||||
public <T> void inject(SpanContext spanContext, Format<T> format, T carrier) {
|
||||
|
||||
Codec<T> codec = registry.get(format);
|
||||
if (codec == null) {
|
||||
logger.warn("Unsupported format for propagation - {}", format.getClass().getName());
|
||||
} else {
|
||||
codec.inject((DDSpanContext) spanContext, carrier);
|
||||
}
|
||||
}
|
||||
|
||||
public <C> SpanContext extract(Format<C> format, C c) {
|
||||
//FIXME Implement it ASAP
|
||||
logger.warn("Method `inject` not implemented yet");
|
||||
public <T> SpanContext extract(Format<T> format, T carrier) {
|
||||
|
||||
Codec<T> codec = registry.get(format);
|
||||
if (codec == null) {
|
||||
logger.warn("Unsupported format for propagation - {}", format.getClass().getName());
|
||||
} else {
|
||||
return codec.extract(carrier);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -263,6 +279,20 @@ public class DDTracer implements io.opentracing.Tracer {
|
|||
|
||||
}
|
||||
|
||||
private static class CodecRegistry {
|
||||
|
||||
private final Map<Format<?>, Codec<?>> codecs = new HashMap<Format<?>, Codec<?>>();
|
||||
|
||||
<T> Codec<T> get(Format<T> format) {
|
||||
return (Codec<T>) codecs.get(format);
|
||||
}
|
||||
|
||||
public <T> void register(Format<T> format, Codec<T> codec) {
|
||||
codecs.put(format, codec);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DDTracer{" +
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
package com.datadoghq.trace.propagation.impl;
|
||||
|
||||
import com.datadoghq.trace.Codec;
|
||||
import com.datadoghq.trace.impl.DDSpanContext;
|
||||
import io.opentracing.propagation.TextMap;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class HTTPCodec implements Codec<TextMap> {
|
||||
|
||||
private static final String OT_PREFIX = "ot-tracer-";
|
||||
private static final String OT_BAGGAGE_PREFIX = "ot-baggage-";
|
||||
private static final String TRACE_ID_KEY = OT_PREFIX + "traceid";
|
||||
private static final String SPAN_ID_KEY = OT_PREFIX + "spanid";
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(HTTPCodec.class);
|
||||
|
||||
@Override
|
||||
public void inject(DDSpanContext context, TextMap carrier) {
|
||||
|
||||
carrier.put(TRACE_ID_KEY, String.valueOf(context.getTraceId()));
|
||||
carrier.put(SPAN_ID_KEY, String.valueOf(context.getSpanId()));
|
||||
|
||||
for (Map.Entry<String, String> entry : context.baggageItems()) {
|
||||
carrier.put(OT_BAGGAGE_PREFIX + entry.getKey(), encode(entry.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public DDSpanContext extract(TextMap carrier) {
|
||||
|
||||
Map<String, String> baggage = Collections.emptyMap();
|
||||
Long traceId = 0L;
|
||||
Long spanId = 0L;
|
||||
|
||||
for (Map.Entry<String, String> entry : carrier) {
|
||||
|
||||
if (entry.getKey().equals(TRACE_ID_KEY)) {
|
||||
traceId = Long.parseLong(entry.getValue());
|
||||
} else if (entry.getKey().equals(SPAN_ID_KEY)) {
|
||||
spanId = Long.parseLong(entry.getValue());
|
||||
} else if (entry.getKey().startsWith(OT_BAGGAGE_PREFIX)) {
|
||||
if (baggage.isEmpty()) {
|
||||
baggage = new HashMap<String, String>();
|
||||
}
|
||||
baggage.put(entry.getKey(), decode(entry.getValue()));
|
||||
}
|
||||
}
|
||||
DDSpanContext context = null;
|
||||
if (traceId != 0L) {
|
||||
|
||||
context = new DDSpanContext(
|
||||
traceId,
|
||||
spanId,
|
||||
0L,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
baggage,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
|
||||
logger.debug("{} - Parent context extracted", context);
|
||||
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
private String encode(String value) {
|
||||
String encoded = value;
|
||||
try {
|
||||
encoded = URLEncoder.encode(value, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.info("Failed to encode value - {}", value);
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
private String decode(String value) {
|
||||
String decoded = value;
|
||||
try {
|
||||
decoded = URLDecoder.decode(value, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.info("Failed to decode value - {}", value);
|
||||
}
|
||||
return decoded;
|
||||
}
|
||||
|
||||
}
|
|
@ -93,7 +93,7 @@ public class DDApi {
|
|||
out.write(content);
|
||||
out.close();
|
||||
int responseCode = httpCon.getResponseCode();
|
||||
if (responseCode != 200) {
|
||||
if (responseCode == 200) {
|
||||
logger.debug("Sent the payload to the DD agent.");
|
||||
} else {
|
||||
logger.warn("Could not send the payload to the DD agent. Status: {} ResponseMessage: {}", httpCon.getResponseCode(), httpCon.getResponseMessage());
|
||||
|
|
Loading…
Reference in New Issue