Lazy init Writer from config to avoid premature resource allocation.

This commit is contained in:
Tyler Benson 2020-01-15 09:25:51 -08:00
parent e31cbd6c89
commit 075ecb9f37
5 changed files with 24 additions and 26 deletions

View File

@ -97,27 +97,20 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
private final HttpCodec.Extractor extractor; private final HttpCodec.Extractor extractor;
public static class Builder { public static class Builder {
public Builder() { public Builder() {
// Apply the default values from config. // Apply the default values from config.
withConfig(Config.get()); config(Config.get());
}
public Builder writer(final Writer writer) {
if (this.writer != null && this.writer != writer) {
// Try to avoid leaking resources
this.writer.close();
}
this.writer = writer;
return this;
} }
public Builder withProperties(final Properties properties) { public Builder withProperties(final Properties properties) {
return withConfig(Config.get(properties)); return config(Config.get(properties));
} }
public Builder withConfig(final Config config) { public Builder config(final Config config) {
this.config = config;
serviceName(config.getServiceName()); serviceName(config.getServiceName());
writer(Writer.Builder.forConfig(config)); // Explicitly skip setting writer to avoid allocating resources prematurely.
sampler(Sampler.Builder.forConfig(config)); sampler(Sampler.Builder.forConfig(config));
injector(HttpCodec.createInjector(config)); injector(HttpCodec.createInjector(config));
extractor(HttpCodec.createExtractor(config, config.getHeaderTags())); extractor(HttpCodec.createExtractor(config, config.getHeaderTags()));
@ -259,6 +252,7 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
final Map<String, String> taggedHeaders, final Map<String, String> taggedHeaders,
final int partialFlushMinSpans) { final int partialFlushMinSpans) {
this( this(
Config.get(),
serviceName, serviceName,
writer, writer,
sampler, sampler,
@ -274,6 +268,7 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
@lombok.Builder(builderClassName = "Builder") @lombok.Builder(builderClassName = "Builder")
// These field names must be stable to ensure the builder api is stable. // These field names must be stable to ensure the builder api is stable.
private DDTracer( private DDTracer(
final Config config,
final String serviceName, final String serviceName,
final Writer writer, final Writer writer,
final Sampler sampler, final Sampler sampler,
@ -285,14 +280,17 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
final Map<String, String> taggedHeaders, final Map<String, String> taggedHeaders,
final int partialFlushMinSpans) { final int partialFlushMinSpans) {
assert writer != null;
assert localRootSpanTags != null; assert localRootSpanTags != null;
assert defaultSpanTags != null; assert defaultSpanTags != null;
assert serviceNameMappings != null; assert serviceNameMappings != null;
assert taggedHeaders != null; assert taggedHeaders != null;
this.serviceName = serviceName; this.serviceName = serviceName;
if (writer == null) {
this.writer = Writer.Builder.forConfig(config);
} else {
this.writer = writer; this.writer = writer;
}
this.sampler = sampler; this.sampler = sampler;
this.injector = injector; this.injector = injector;
this.extractor = extractor; this.extractor = extractor;

View File

@ -16,7 +16,7 @@ public class DDTracerResolver extends TracerResolver {
Tracer resolve(final Config config) { Tracer resolve(final Config config) {
if (config.isTraceResolverEnabled()) { if (config.isTraceResolverEnabled()) {
log.info("Creating DDTracer with DDTracerResolver"); log.info("Creating DDTracer with DDTracerResolver");
return DDTracer.builder().withConfig(config).build(); return DDTracer.builder().config(config).build();
} else { } else {
log.info("DDTracerResolver disabled"); log.info("DDTracerResolver disabled");
return null; return null;

View File

@ -458,7 +458,7 @@ class DDSpanBuilderTest extends DDSpecification {
setup: setup:
System.setProperty("dd.trace.span.tags", tagString) System.setProperty("dd.trace.span.tags", tagString)
def config = new Config() def config = new Config()
tracer = DDTracer.builder().withConfig(config).writer(writer).build() tracer = DDTracer.builder().config(config).writer(writer).build()
def span = tracer.buildSpan("op name").withServiceName("foo").start() def span = tracer.buildSpan("op name").withServiceName("foo").start()
expect: expect:

View File

@ -195,7 +195,7 @@ class PendingTraceTest extends DDSpecification {
def properties = new Properties() def properties = new Properties()
properties.setProperty(PARTIAL_FLUSH_MIN_SPANS, "1") properties.setProperty(PARTIAL_FLUSH_MIN_SPANS, "1")
def config = Config.get(properties) def config = Config.get(properties)
def tracer = DDTracer.builder().withConfig(config).writer(writer).build() def tracer = DDTracer.builder().config(config).writer(writer).build()
def trace = new PendingTrace(tracer, traceId, [:]) def trace = new PendingTrace(tracer, traceId, [:])
def rootSpan = SpanFactory.newSpanOf(trace) def rootSpan = SpanFactory.newSpanOf(trace)
def child1 = tracer.buildSpan("child1").asChildOf(rootSpan).start() def child1 = tracer.buildSpan("child1").asChildOf(rootSpan).start()
@ -241,7 +241,7 @@ class PendingTraceTest extends DDSpecification {
def properties = new Properties() def properties = new Properties()
properties.setProperty(PARTIAL_FLUSH_MIN_SPANS, "1") properties.setProperty(PARTIAL_FLUSH_MIN_SPANS, "1")
def config = Config.get(properties) def config = Config.get(properties)
def tracer = DDTracer.builder().withConfig(config).writer(writer).build() def tracer = DDTracer.builder().config(config).writer(writer).build()
def trace = new PendingTrace(tracer, traceId, [:]) def trace = new PendingTrace(tracer, traceId, [:])
def rootSpan = SpanFactory.newSpanOf(trace) def rootSpan = SpanFactory.newSpanOf(trace)
def child1 = tracer.buildSpan("child1").asChildOf(rootSpan).start() def child1 = tracer.buildSpan("child1").asChildOf(rootSpan).start()

View File

@ -63,7 +63,7 @@ class DDTracerTest extends DDSpecification {
System.setProperty(PREFIX + HEALTH_METRICS_ENABLED, "true") System.setProperty(PREFIX + HEALTH_METRICS_ENABLED, "true")
when: when:
def tracer = DDTracer.builder().withConfig(new Config()).build() def tracer = DDTracer.builder().config(new Config()).build()
then: then:
tracer.writer.monitor instanceof Monitor.StatsD tracer.writer.monitor instanceof Monitor.StatsD
@ -75,7 +75,7 @@ class DDTracerTest extends DDSpecification {
setup: setup:
System.setProperty(PREFIX + PRIORITY_SAMPLING, "false") System.setProperty(PREFIX + PRIORITY_SAMPLING, "false")
when: when:
def tracer = DDTracer.builder().withConfig(new Config()).build() def tracer = DDTracer.builder().config(new Config()).build()
then: then:
tracer.sampler instanceof AllSampler tracer.sampler instanceof AllSampler
} }
@ -85,7 +85,7 @@ class DDTracerTest extends DDSpecification {
System.setProperty(PREFIX + WRITER_TYPE, "LoggingWriter") System.setProperty(PREFIX + WRITER_TYPE, "LoggingWriter")
when: when:
def tracer = DDTracer.builder().withConfig(new Config()).build() def tracer = DDTracer.builder().config(new Config()).build()
then: then:
tracer.writer instanceof LoggingWriter tracer.writer instanceof LoggingWriter
@ -98,7 +98,7 @@ class DDTracerTest extends DDSpecification {
System.setProperty(PREFIX + HEADER_TAGS, mapString) System.setProperty(PREFIX + HEADER_TAGS, mapString)
when: when:
def tracer = DDTracer.builder().withConfig(new Config()).build() def tracer = DDTracer.builder().config(new Config()).build()
// Datadog extractor gets placed first // Datadog extractor gets placed first
def taggedHeaders = tracer.extractor.extractors[0].taggedHeaders def taggedHeaders = tracer.extractor.extractors[0].taggedHeaders
@ -116,7 +116,7 @@ class DDTracerTest extends DDSpecification {
def "verify overriding host"() { def "verify overriding host"() {
when: when:
System.setProperty(PREFIX + key, value) System.setProperty(PREFIX + key, value)
def tracer = DDTracer.builder().withConfig(new Config()).build() def tracer = DDTracer.builder().config(new Config()).build()
then: then:
tracer.writer instanceof DDAgentWriter tracer.writer instanceof DDAgentWriter
@ -131,7 +131,7 @@ class DDTracerTest extends DDSpecification {
def "verify overriding port"() { def "verify overriding port"() {
when: when:
System.setProperty(PREFIX + key, value) System.setProperty(PREFIX + key, value)
def tracer = DDTracer.builder().withConfig(new Config()).build() def tracer = DDTracer.builder().config(new Config()).build()
then: then:
tracer.writer instanceof DDAgentWriter tracer.writer instanceof DDAgentWriter
@ -147,7 +147,7 @@ class DDTracerTest extends DDSpecification {
def "Writer is instance of LoggingWriter when property set"() { def "Writer is instance of LoggingWriter when property set"() {
when: when:
System.setProperty(PREFIX + "writer.type", "LoggingWriter") System.setProperty(PREFIX + "writer.type", "LoggingWriter")
def tracer = DDTracer.builder().withConfig(new Config()).build() def tracer = DDTracer.builder().config(new Config()).build()
then: then:
tracer.writer instanceof LoggingWriter tracer.writer instanceof LoggingWriter