Ability to add extra service information (WIP)
This commit is contained in:
parent
f1b31a661a
commit
4072edb405
|
@ -7,13 +7,19 @@ import com.datadoghq.trace.sampling.AllSampler;
|
||||||
import com.datadoghq.trace.sampling.Sampler;
|
import com.datadoghq.trace.sampling.Sampler;
|
||||||
import com.datadoghq.trace.writer.LoggingWriter;
|
import com.datadoghq.trace.writer.LoggingWriter;
|
||||||
import com.datadoghq.trace.writer.Writer;
|
import com.datadoghq.trace.writer.Writer;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import io.opentracing.ActiveSpan;
|
import io.opentracing.ActiveSpan;
|
||||||
import io.opentracing.ActiveSpanSource;
|
import io.opentracing.ActiveSpanSource;
|
||||||
import io.opentracing.BaseSpan;
|
import io.opentracing.BaseSpan;
|
||||||
import io.opentracing.SpanContext;
|
import io.opentracing.SpanContext;
|
||||||
import io.opentracing.propagation.Format;
|
import io.opentracing.propagation.Format;
|
||||||
import io.opentracing.util.ThreadLocalActiveSpanSource;
|
import io.opentracing.util.ThreadLocalActiveSpanSource;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Queue;
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@ -37,6 +43,7 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac
|
||||||
private final Map<String, List<AbstractDecorator>> spanContextDecorators = new HashMap<>();
|
private final Map<String, List<AbstractDecorator>> spanContextDecorators = new HashMap<>();
|
||||||
|
|
||||||
private final CodecRegistry registry;
|
private final CodecRegistry registry;
|
||||||
|
private final List<Service> services = new ArrayList<>();
|
||||||
|
|
||||||
/** Default constructor, trace/spans are logged, no trace/span dropped */
|
/** Default constructor, trace/spans are logged, no trace/span dropped */
|
||||||
public DDTracer() {
|
public DDTracer() {
|
||||||
|
@ -137,6 +144,33 @@ public class DDTracer extends ThreadLocalActiveSpanSource implements io.opentrac
|
||||||
return "DDTracer{" + "writer=" + writer + ", sampler=" + sampler + '}';
|
return "DDTracer{" + "writer=" + writer + ", sampler=" + sampler + '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register additional information about a service. Service additional information are a Datadog
|
||||||
|
* feature only. Services are reported through a specific Datadog endpoint.
|
||||||
|
*
|
||||||
|
* @param service additional service information
|
||||||
|
*/
|
||||||
|
public void addServiceInfo(final Service service) {
|
||||||
|
services.add(service);
|
||||||
|
// Update the write
|
||||||
|
try {
|
||||||
|
// We don't bother to send multiple times the list of services at this time
|
||||||
|
writer.writeServices(services);
|
||||||
|
} catch (final Throwable ex) {
|
||||||
|
log.warn("Failed to report additional service information, reason: {}", ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the list of additional service information registered
|
||||||
|
*
|
||||||
|
* @return the list of additional service information
|
||||||
|
*/
|
||||||
|
@JsonIgnore
|
||||||
|
public List<Service> getServiceInfo() {
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
private static class CodecRegistry {
|
private static class CodecRegistry {
|
||||||
|
|
||||||
private final Map<Format<?>, Codec<?>> codecs = new HashMap<>();
|
private final Map<Format<?>, Codec<?>> codecs = new HashMap<>();
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.datadoghq.trace;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
public class Service {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final String appName;
|
||||||
|
private final Service.AppType appType;
|
||||||
|
|
||||||
|
public Service(final String name, final String appName, final AppType appType) {
|
||||||
|
this.name = name;
|
||||||
|
this.appName = appName;
|
||||||
|
this.appType = appType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("service")
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("app")
|
||||||
|
public String getAppName() {
|
||||||
|
return appName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty("app_type")
|
||||||
|
public AppType getAppType() {
|
||||||
|
return appType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum AppType {
|
||||||
|
WEB("web"),
|
||||||
|
DB("db"),
|
||||||
|
CUSTOM("custom");
|
||||||
|
|
||||||
|
private final String type;
|
||||||
|
|
||||||
|
AppType(final String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package com.datadoghq.trace.writer;
|
package com.datadoghq.trace.writer;
|
||||||
|
|
||||||
import com.datadoghq.trace.DDBaseSpan;
|
import com.datadoghq.trace.DDBaseSpan;
|
||||||
|
import com.datadoghq.trace.Service;
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
@ -80,6 +81,9 @@ public class DDAgentWriter implements Writer {
|
||||||
queueFullReported = false;
|
queueFullReported = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeServices(final List<Service> services) {}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see com.datadoghq.trace.writer.Writer#start()
|
* @see com.datadoghq.trace.writer.Writer#start()
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package com.datadoghq.trace.writer;
|
package com.datadoghq.trace.writer;
|
||||||
|
|
||||||
import com.datadoghq.trace.DDBaseSpan;
|
import com.datadoghq.trace.DDBaseSpan;
|
||||||
|
import com.datadoghq.trace.Service;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
|
||||||
|
|
||||||
/** List writer used by tests mostly */
|
/** List writer used by tests mostly */
|
||||||
public class ListWriter extends CopyOnWriteArrayList<List<DDBaseSpan<?>>> implements Writer {
|
public class ListWriter extends CopyOnWriteArrayList<List<DDBaseSpan<?>>> implements Writer {
|
||||||
|
@ -20,6 +22,11 @@ public class ListWriter extends CopyOnWriteArrayList<List<DDBaseSpan<?>>> implem
|
||||||
add(trace);
|
add(trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeServices(final List<Service> services) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
clear();
|
clear();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.datadoghq.trace.writer;
|
package com.datadoghq.trace.writer;
|
||||||
|
|
||||||
import com.datadoghq.trace.DDBaseSpan;
|
import com.datadoghq.trace.DDBaseSpan;
|
||||||
|
import com.datadoghq.trace.Service;
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
@ -14,6 +15,11 @@ public class LoggingWriter implements Writer {
|
||||||
log.info("write(trace): {}", trace);
|
log.info("write(trace): {}", trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeServices(final List<Service> services) {
|
||||||
|
log.info("additional service information: {}", services);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
log.info("close()");
|
log.info("close()");
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.datadoghq.trace.writer;
|
package com.datadoghq.trace.writer;
|
||||||
|
|
||||||
import com.datadoghq.trace.DDBaseSpan;
|
import com.datadoghq.trace.DDBaseSpan;
|
||||||
|
import com.datadoghq.trace.Service;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** A writer is responsible to send collected spans to some place */
|
/** A writer is responsible to send collected spans to some place */
|
||||||
|
@ -13,6 +14,13 @@ public interface Writer {
|
||||||
*/
|
*/
|
||||||
void write(List<DDBaseSpan<?>> trace);
|
void write(List<DDBaseSpan<?>> trace);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report additional service information to the endpoint
|
||||||
|
*
|
||||||
|
* @param services a list of extra information about services
|
||||||
|
*/
|
||||||
|
void writeServices(List<Service> services);
|
||||||
|
|
||||||
/** Start the writer */
|
/** Start the writer */
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
package com.datadoghq.trace
|
||||||
|
|
||||||
|
import com.datadoghq.trace.sampling.AllSampler
|
||||||
|
import com.datadoghq.trace.writer.DDAgentWriter
|
||||||
|
import org.mockito.Mockito
|
||||||
|
import spock.lang.Specification
|
||||||
|
|
||||||
|
class ServiceTest extends Specification {
|
||||||
|
|
||||||
|
|
||||||
|
def "getter/setter"() {
|
||||||
|
|
||||||
|
setup:
|
||||||
|
def service = new Service("service-name", "app-name", Service.AppType.CUSTOM)
|
||||||
|
|
||||||
|
expect:
|
||||||
|
service.getName() == "service-name"
|
||||||
|
service.getAppName() == "app-name"
|
||||||
|
service.getAppType() == Service.AppType.CUSTOM
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
def "enum"() {
|
||||||
|
|
||||||
|
expect:
|
||||||
|
Service.AppType.values().size() == 3
|
||||||
|
Service.AppType.DB.toString() == "db"
|
||||||
|
Service.AppType.WEB.toString() == "web"
|
||||||
|
Service.AppType.CUSTOM.toString() == "custom"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
def "add extra info about a specific service"() {
|
||||||
|
|
||||||
|
setup:
|
||||||
|
def tracer = new DDTracer()
|
||||||
|
def service = new Service("service-name", "app-name", Service.AppType.CUSTOM)
|
||||||
|
|
||||||
|
when:
|
||||||
|
tracer.addServiceInfo(service)
|
||||||
|
|
||||||
|
then:
|
||||||
|
tracer.getServiceInfo().size() == 1
|
||||||
|
tracer.getServiceInfo().get(0) == service
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
def "add a extra info is reported to the writer"() {
|
||||||
|
|
||||||
|
setup:
|
||||||
|
def writer = Mockito.spy(new DDAgentWriter())
|
||||||
|
def tracer = new DDTracer(writer, new AllSampler())
|
||||||
|
|
||||||
|
|
||||||
|
when:
|
||||||
|
tracer.addServiceInfo(new Service("service-name", "app-name", Service.AppType.CUSTOM))
|
||||||
|
|
||||||
|
then:
|
||||||
|
Mockito.verify(writer, Mockito.times(1)).writeServices(Mockito.any(List.class))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue