Allow setting host/port without specifying writer type.

This commit is contained in:
Tyler Benson 2018-01-08 16:45:24 +10:00
parent cca7a730e0
commit d95309b9cd
13 changed files with 89 additions and 124 deletions

View File

@ -1,15 +1,19 @@
package com.datadoghq.trace; package com.datadoghq.trace;
import com.datadoghq.trace.sampling.Sampler;
import com.datadoghq.trace.writer.DDAgentWriter;
import com.datadoghq.trace.writer.Writer;
import java.util.Properties; import java.util.Properties;
/** /**
* Config gives priority to system properties and falls back to environment variables. * Config gives priority to system properties and falls back to environment variables. It also
* includes default values to ensure a valid config.
* *
* <p>System properties are {@link DDTraceConfig#PREFIX}'ed. Environment variables are the same as * <p>System properties are {@link DDTraceConfig#PREFIX}'ed. Environment variables are the same as
* the system property, but uppercased with '.' -> '_'. * the system property, but uppercased with '.' -> '_'.
*/ */
public class DDTraceConfig extends Properties { public class DDTraceConfig extends Properties {
/** Config keys bel */ /** Config keys below */
private static final String PREFIX = "dd."; private static final String PREFIX = "dd.";
public static final String SERVICE_NAME = "service.name"; public static final String SERVICE_NAME = "service.name";
@ -31,9 +35,13 @@ public class DDTraceConfig extends Properties {
final Properties defaults = new Properties(); final Properties defaults = new Properties();
defaults.setProperty(SERVICE_NAME, DDTracer.UNASSIGNED_DEFAULT_SERVICE_NAME); defaults.setProperty(SERVICE_NAME, DDTracer.UNASSIGNED_DEFAULT_SERVICE_NAME);
defaults.setProperty(WRITER_TYPE, Writer.DD_AGENT_WRITER_TYPE);
defaults.setProperty(AGENT_HOST, DDAgentWriter.DEFAULT_HOSTNAME);
defaults.setProperty(AGENT_PORT, String.valueOf(DDAgentWriter.DEFAULT_PORT));
defaults.setProperty(SAMPLER_TYPE, Sampler.ALL_SAMPLER_TYPE);
defaults.setProperty(SAMPLER_RATE, "1.0");
super.defaults = defaults; super.defaults = defaults;
final Properties baseValues = new Properties(defaults);
setIfNotNull(SERVICE_NAME, serviceName); setIfNotNull(SERVICE_NAME, serviceName);
setIfNotNull(WRITER_TYPE, writerType); setIfNotNull(WRITER_TYPE, writerType);
setIfNotNull(AGENT_HOST, agentHost); setIfNotNull(AGENT_HOST, agentHost);
@ -43,7 +51,7 @@ public class DDTraceConfig extends Properties {
} }
public DDTraceConfig(final String serviceName) { public DDTraceConfig(final String serviceName) {
super(); this();
put(SERVICE_NAME, serviceName); put(SERVICE_NAME, serviceName);
} }

View File

@ -6,7 +6,6 @@ import com.datadoghq.trace.propagation.HTTPCodec;
import com.datadoghq.trace.resolver.DDDecoratorsFactory; import com.datadoghq.trace.resolver.DDDecoratorsFactory;
import com.datadoghq.trace.sampling.AllSampler; import com.datadoghq.trace.sampling.AllSampler;
import com.datadoghq.trace.sampling.Sampler; import com.datadoghq.trace.sampling.Sampler;
import com.datadoghq.trace.writer.DDAgentWriter;
import com.datadoghq.trace.writer.Writer; import com.datadoghq.trace.writer.Writer;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import io.opentracing.ActiveSpan; import io.opentracing.ActiveSpan;
@ -30,17 +29,14 @@ import lombok.extern.slf4j.Slf4j;
public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentracing.Tracer { public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentracing.Tracer {
public static final String UNASSIGNED_DEFAULT_SERVICE_NAME = "unnamed-java-app"; public static final String UNASSIGNED_DEFAULT_SERVICE_NAME = "unnamed-java-app";
public static final Writer UNASSIGNED_WRITER = new DDAgentWriter();
public static final Sampler UNASSIGNED_SAMPLER = new AllSampler();
/** Default service name if none provided on the trace or span */
final String serviceName;
/** Writer is an charge of reporting traces and spans to the desired endpoint */ /** Writer is an charge of reporting traces and spans to the desired endpoint */
final Writer writer; final Writer writer;
/** Sampler defines the sampling policy in order to reduce the number of traces for instance */ /** Sampler defines the sampling policy in order to reduce the number of traces for instance */
final Sampler sampler; final Sampler sampler;
/** Default service name if none provided on the trace or span */
final String serviceName;
/** Span context decorators */ /** Span context decorators */
private final Map<String, List<AbstractDecorator>> spanContextDecorators = new HashMap<>(); private final Map<String, List<AbstractDecorator>> spanContextDecorators = new HashMap<>();
@ -83,11 +79,7 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac
} }
public DDTracer(final Writer writer) { public DDTracer(final Writer writer) {
this(writer, new AllSampler()); this(UNASSIGNED_DEFAULT_SERVICE_NAME, writer, new AllSampler());
}
public DDTracer(final Writer writer, final Sampler sampler) {
this(UNASSIGNED_DEFAULT_SERVICE_NAME, writer, sampler);
} }
/** /**

View File

@ -6,7 +6,12 @@ import com.datadoghq.trace.DDBaseSpan;
public class AllSampler extends AbstractSampler { public class AllSampler extends AbstractSampler {
@Override @Override
public boolean doSample(DDBaseSpan<?> span) { public boolean doSample(final DDBaseSpan<?> span) {
return true; return true;
} }
@Override
public String toString() {
return "AllSampler { sample=true }";
}
} }

View File

@ -2,8 +2,8 @@ package com.datadoghq.trace.sampling;
import com.datadoghq.trace.DDBaseSpan; import com.datadoghq.trace.DDBaseSpan;
import com.datadoghq.trace.DDTraceConfig; import com.datadoghq.trace.DDTraceConfig;
import com.datadoghq.trace.DDTracer;
import java.util.Properties; import java.util.Properties;
import lombok.extern.slf4j.Slf4j;
/** Main interface to sample a collection of traces. */ /** Main interface to sample a collection of traces. */
public interface Sampler { public interface Sampler {
@ -18,6 +18,7 @@ public interface Sampler {
*/ */
boolean sample(DDBaseSpan<?> span); boolean sample(DDBaseSpan<?> span);
@Slf4j
final class Builder { final class Builder {
public static Sampler forConfig(final Properties config) { public static Sampler forConfig(final Properties config) {
final Sampler sampler; final Sampler sampler;
@ -29,10 +30,15 @@ public interface Sampler {
} else if (ALL_SAMPLER_TYPE.equals(configuredType)) { } else if (ALL_SAMPLER_TYPE.equals(configuredType)) {
sampler = new AllSampler(); sampler = new AllSampler();
} else { } else {
sampler = DDTracer.UNASSIGNED_SAMPLER; log.warn(
"Sampler type not configured correctly: Type {} not recognized. Defaulting to AllSampler.",
configuredType);
sampler = new AllSampler();
} }
} else { } else {
sampler = DDTracer.UNASSIGNED_SAMPLER; log.warn(
"Sampler type not configured correctly: No config provided! Defaulting to AllSampler.");
sampler = new AllSampler();
} }
return sampler; return sampler;
} }

View File

@ -103,9 +103,10 @@ public class DDApi {
log.debug("Error while sending " + size + " " + type + " to the DD agent.", e); log.debug("Error while sending " + size + " " + type + " to the DD agent.", e);
} else if (loggingRateLimiter.tryAcquire()) { } else if (loggingRateLimiter.tryAcquire()) {
log.warn( log.warn(
"Error while sending {} {} to the DD agent. Message: {} (going silent for {} seconds)", "Error while sending {} {} to the DD agent. {}: {} (going silent for {} seconds)",
size, size,
type, type,
e.getClass().getName(),
e.getMessage(), e.getMessage(),
SECONDS_BETWEEN_ERROR_LOG); SECONDS_BETWEEN_ERROR_LOG);
} }

View File

@ -63,4 +63,9 @@ public class ListWriter extends CopyOnWriteArrayList<List<DDBaseSpan<?>>> implem
latches.clear(); latches.clear();
} }
} }
@Override
public String toString() {
return "ListWriter { size=" + this.size() + " }";
}
} }

View File

@ -30,4 +30,9 @@ public class LoggingWriter implements Writer {
public void start() { public void start() {
log.info("start()"); log.info("start()");
} }
@Override
public String toString() {
return "LoggingWriter { }";
}
} }

View File

@ -2,11 +2,11 @@ package com.datadoghq.trace.writer;
import com.datadoghq.trace.DDBaseSpan; import com.datadoghq.trace.DDBaseSpan;
import com.datadoghq.trace.DDTraceConfig; import com.datadoghq.trace.DDTraceConfig;
import com.datadoghq.trace.DDTracer;
import com.datadoghq.trace.Service; import com.datadoghq.trace.Service;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import lombok.extern.slf4j.Slf4j;
/** A writer is responsible to send collected spans to some place */ /** A writer is responsible to send collected spans to some place */
public interface Writer { public interface Writer {
@ -36,6 +36,7 @@ public interface Writer {
*/ */
void close(); void close();
@Slf4j
final class Builder { final class Builder {
public static Writer forConfig(final Properties config) { public static Writer forConfig(final Properties config) {
final Writer writer; final Writer writer;
@ -51,10 +52,19 @@ public interface Writer {
} else if (LOGGING_WRITER_TYPE.equals(configuredType)) { } else if (LOGGING_WRITER_TYPE.equals(configuredType)) {
writer = new LoggingWriter(); writer = new LoggingWriter();
} else { } else {
writer = DDTracer.UNASSIGNED_WRITER; log.warn(
"Writer type not configured correctly: Type {} not recognized. Defaulting to DDAgentWriter.",
configuredType);
writer =
new DDAgentWriter(
new DDApi(
config.getProperty(DDTraceConfig.AGENT_HOST),
Integer.parseInt(config.getProperty(DDTraceConfig.AGENT_PORT))));
} }
} else { } else {
writer = DDTracer.UNASSIGNED_WRITER; log.warn(
"Writer type not configured correctly: No config provided! Defaulting to DDAgentWriter.");
writer = new DDAgentWriter();
} }
return writer; return writer;

View File

@ -6,6 +6,7 @@ import com.datadoghq.trace.writer.DDAgentWriter
import com.datadoghq.trace.writer.ListWriter import com.datadoghq.trace.writer.ListWriter
import com.datadoghq.trace.writer.LoggingWriter import com.datadoghq.trace.writer.LoggingWriter
import spock.lang.Specification import spock.lang.Specification
import spock.lang.Unroll
import java.lang.reflect.Field import java.lang.reflect.Field
import java.lang.reflect.Modifier import java.lang.reflect.Modifier
@ -67,22 +68,22 @@ class DDTraceConfigTest extends Specification {
then: then:
config.getProperty(SERVICE_NAME) == "unnamed-java-app" config.getProperty(SERVICE_NAME) == "unnamed-java-app"
config.getProperty(WRITER_TYPE) == null config.getProperty(WRITER_TYPE) == "DDAgentWriter"
config.getProperty(AGENT_HOST) == null config.getProperty(AGENT_HOST) == "localhost"
config.getProperty(AGENT_PORT) == null config.getProperty(AGENT_PORT) == "8126"
config.getProperty(SAMPLER_TYPE) == null config.getProperty(SAMPLER_TYPE) == "AllSampler"
config.getProperty(SAMPLER_RATE) == null config.getProperty(SAMPLER_RATE) == "1.0"
when: when:
config = new DDTraceConfig("A different service name") config = new DDTraceConfig("A different service name")
then: then:
config.getProperty(SERVICE_NAME) == "A different service name" config.getProperty(SERVICE_NAME) == "A different service name"
config.getProperty(WRITER_TYPE) == null config.getProperty(WRITER_TYPE) == "DDAgentWriter"
config.getProperty(AGENT_HOST) == null config.getProperty(AGENT_HOST) == "localhost"
config.getProperty(AGENT_PORT) == null config.getProperty(AGENT_PORT) == "8126"
config.getProperty(SAMPLER_TYPE) == null config.getProperty(SAMPLER_TYPE) == "AllSampler"
config.getProperty(SAMPLER_RATE) == null config.getProperty(SAMPLER_RATE) == "1.0"
} }
def "specify overrides via system properties"() { def "specify overrides via system properties"() {
@ -144,4 +145,25 @@ class DDTraceConfigTest extends Specification {
tracer.spanContextDecorators.size() == 2 tracer.spanContextDecorators.size() == 2
} }
@Unroll
def "verify single override on #source for #key"() {
when:
System.setProperty(PREFIX + key, value)
def tracer = new DDTracer()
then:
tracer."$source".toString() == expected
where:
source | key | value | expected
"writer" | "default" | "default" | "DDAgentWriter { api=DDApi { tracesEndpoint=http://localhost:8126/v0.3/traces } }"
"writer" | "writer.type" | "LoggingWriter" | "LoggingWriter { }"
"writer" | "agent.host" | "somethingelse" | "DDAgentWriter { api=DDApi { tracesEndpoint=http://somethingelse:8126/v0.3/traces } }"
"writer" | "agent.port" | "9999" | "DDAgentWriter { api=DDApi { tracesEndpoint=http://localhost:9999/v0.3/traces } }"
"sampler" | "default" | "default" | "AllSampler { sample=true }"
"sampler" | "sampler.type" | "RateSampler" | "RateSampler { sampleRate=1.0 }"
"sampler" | "sampler.rate" | "100" | "AllSampler { sample=true }"
}
} }

View File

@ -54,7 +54,7 @@ class ServiceTest extends Specification {
setup: setup:
def writer = spy(new DDAgentWriter()) def writer = spy(new DDAgentWriter())
def tracer = new DDTracer(writer, new AllSampler()) def tracer = new DDTracer(DDTracer.UNASSIGNED_DEFAULT_SERVICE_NAME, writer, new AllSampler())
when: when:

View File

@ -1,37 +0,0 @@
import com.datadoghq.trace.DDTracer;
import com.datadoghq.trace.Service;
import com.datadoghq.trace.sampling.AllSampler;
import com.datadoghq.trace.writer.LoggingWriter;
import io.opentracing.Span;
public class ExampleWithLoggingWriter {
public static void main(final String[] args) throws Exception {
final DDTracer tracer = new DDTracer(new LoggingWriter(), new AllSampler());
tracer.addServiceInfo(new Service("api-intake", "spark", Service.AppType.CACHE));
final Span parent =
tracer.buildSpan("fetch.backend").withServiceName("api-intake").startManual();
parent.setBaggageItem("scope-id", "a-1337");
Thread.sleep(100);
final Span child =
tracer
.buildSpan("delete.resource")
.asChildOf(parent)
.withResourceName("delete")
.startManual();
Thread.sleep(100);
child.finish();
Thread.sleep(100);
parent.finish();
tracer.close();
}
}

View File

@ -30,7 +30,7 @@ public class DDTracerTest {
spans.add(span); spans.add(span);
spans.add(span); spans.add(span);
final DDTracer tracer = new DDTracer(writer, sampler); final DDTracer tracer = new DDTracer(DDTracer.UNASSIGNED_DEFAULT_SERVICE_NAME, writer, sampler);
tracer.write(spans); tracer.write(spans);
tracer.write(spans); tracer.write(spans);

View File

@ -1,52 +0,0 @@
package com.datadoghq.trace.sampling;
import com.datadoghq.trace.DDTracer;
import com.datadoghq.trace.writer.DDAgentWriter;
import com.datadoghq.trace.writer.Writer;
import io.opentracing.Span;
public class ExampleWithDDAgentWriter {
public static void main(final String[] args) throws Exception {
// Instantiate the DDWriter
// By default, traces are written to localhost:8126 (the ddagent)
final Writer writer = new DDAgentWriter();
// Instantiate the proper Sampler
// - RateSampler if you want to keep `ratio` traces
// - AllSampler to keep all traces
final Sampler sampler = new AllSampler();
// Create the tracer
final DDTracer tracer = new DDTracer(writer, sampler);
final Span parent =
tracer
.buildSpan("hello-world")
.withServiceName("my-service-name")
.withSpanType("web")
.startManual();
Thread.sleep(100);
parent.setBaggageItem("a-baggage", "value");
final Span child =
tracer
.buildSpan("hello-world")
.asChildOf(parent)
.withResourceName("my-resource-name")
.startManual();
Thread.sleep(100);
child.finish();
Thread.sleep(100);
parent.finish();
writer.close();
}
}