Add config for tags that propagate to JMXFetch and spans
Also add runtime-id tag to root span and JMXFetch metrics
This commit is contained in:
parent
9b3019c612
commit
34372533c1
|
@ -5,7 +5,7 @@ apply from: "${rootDir}/gradle/java.gradle"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile 'com.heliosapm.jmxlocal:jmxlocal:1.0'
|
compile 'com.heliosapm.jmxlocal:jmxlocal:1.0'
|
||||||
compile 'com.datadoghq:jmxfetch:0.21.0'
|
compile 'com.datadoghq:jmxfetch:0.22.0'
|
||||||
compile deps.slf4j
|
compile deps.slf4j
|
||||||
compile project(':dd-trace-api')
|
compile project(':dd-trace-api')
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package datadog.trace.agent.jmxfetch;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import datadog.trace.api.Config;
|
import datadog.trace.api.Config;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.datadog.jmxfetch.App;
|
import org.datadog.jmxfetch.App;
|
||||||
import org.datadog.jmxfetch.AppConfig;
|
import org.datadog.jmxfetch.AppConfig;
|
||||||
|
@ -29,15 +30,17 @@ public class JMXFetch {
|
||||||
final List<String> metricsConfigs = config.getJmxFetchMetricsConfigs();
|
final List<String> metricsConfigs = config.getJmxFetchMetricsConfigs();
|
||||||
final Integer checkPeriod = config.getJmxFetchCheckPeriod();
|
final Integer checkPeriod = config.getJmxFetchCheckPeriod();
|
||||||
final Integer refreshBeansPeriod = config.getJmxFetchRefreshBeansPeriod();
|
final Integer refreshBeansPeriod = config.getJmxFetchRefreshBeansPeriod();
|
||||||
|
final Map<String, String> globalTags = config.getMergedJmxTags();
|
||||||
final String reporter = getReporter(config);
|
final String reporter = getReporter(config);
|
||||||
final String logLocation = getLogLocation();
|
final String logLocation = getLogLocation();
|
||||||
final String logLevel = getLogLevel();
|
final String logLevel = getLogLevel();
|
||||||
|
|
||||||
log.error(
|
log.error(
|
||||||
"JMXFetch config: {} {} {} {} {} {}",
|
"JMXFetch config: {} {} {} {} {} {} {}",
|
||||||
metricsConfigs,
|
metricsConfigs,
|
||||||
checkPeriod,
|
checkPeriod,
|
||||||
refreshBeansPeriod,
|
refreshBeansPeriod,
|
||||||
|
globalTags,
|
||||||
reporter,
|
reporter,
|
||||||
logLocation,
|
logLocation,
|
||||||
logLevel);
|
logLevel);
|
||||||
|
@ -47,6 +50,7 @@ public class JMXFetch {
|
||||||
metricsConfigs,
|
metricsConfigs,
|
||||||
checkPeriod,
|
checkPeriod,
|
||||||
refreshBeansPeriod,
|
refreshBeansPeriod,
|
||||||
|
globalTags,
|
||||||
reporter,
|
reporter,
|
||||||
logLocation,
|
logLocation,
|
||||||
logLevel);
|
logLevel);
|
||||||
|
|
|
@ -52,7 +52,7 @@ class AkkaHttpServerInstrumentationTest extends AgentTestRunner {
|
||||||
spanType DDSpanTypes.HTTP_SERVER
|
spanType DDSpanTypes.HTTP_SERVER
|
||||||
errored false
|
errored false
|
||||||
tags {
|
tags {
|
||||||
defaultTags()
|
defaultTags(true)
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
"$Tags.HTTP_STATUS.key" 200
|
||||||
"$Tags.HTTP_URL.key" "http://localhost:$port/test"
|
"$Tags.HTTP_URL.key" "http://localhost:$port/test"
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
"$Tags.HTTP_METHOD.key" "GET"
|
||||||
|
|
|
@ -97,7 +97,7 @@ class GrpcStreamingTest extends AgentTestRunner {
|
||||||
tags {
|
tags {
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
"$DDTags.SPAN_TYPE" DDSpanTypes.RPC
|
"$DDTags.SPAN_TYPE" DDSpanTypes.RPC
|
||||||
defaultTags()
|
defaultTags(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clientRange.each {
|
clientRange.each {
|
||||||
|
|
|
@ -53,7 +53,7 @@ class GrpcTest extends AgentTestRunner {
|
||||||
tags {
|
tags {
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
"$DDTags.SPAN_TYPE" DDSpanTypes.RPC
|
"$DDTags.SPAN_TYPE" DDSpanTypes.RPC
|
||||||
defaultTags()
|
defaultTags(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
span(1) {
|
span(1) {
|
||||||
|
@ -144,7 +144,7 @@ class GrpcTest extends AgentTestRunner {
|
||||||
tags {
|
tags {
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
"$DDTags.SPAN_TYPE" DDSpanTypes.RPC
|
"$DDTags.SPAN_TYPE" DDSpanTypes.RPC
|
||||||
defaultTags()
|
defaultTags(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
span(1) {
|
span(1) {
|
||||||
|
@ -230,7 +230,7 @@ class GrpcTest extends AgentTestRunner {
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
"$DDTags.SPAN_TYPE" DDSpanTypes.RPC
|
"$DDTags.SPAN_TYPE" DDSpanTypes.RPC
|
||||||
errorTags error.class, error.message
|
errorTags error.class, error.message
|
||||||
defaultTags()
|
defaultTags(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
span(1) {
|
span(1) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import datadog.trace.agent.test.AgentTestRunner
|
import datadog.trace.agent.test.AgentTestRunner
|
||||||
import datadog.trace.agent.test.TestUtils
|
import datadog.trace.agent.test.TestUtils
|
||||||
import datadog.trace.agent.test.utils.OkHttpUtils
|
import datadog.trace.agent.test.utils.OkHttpUtils
|
||||||
|
import datadog.trace.api.Config
|
||||||
import datadog.trace.api.DDSpanTypes
|
import datadog.trace.api.DDSpanTypes
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import org.eclipse.jetty.continuation.Continuation
|
import org.eclipse.jetty.continuation.Continuation
|
||||||
|
@ -74,8 +75,9 @@ class JettyHandlerTest extends AgentTestRunner {
|
||||||
tags["http.status_code"] == 200
|
tags["http.status_code"] == 200
|
||||||
tags["thread.name"] != null
|
tags["thread.name"] != null
|
||||||
tags["thread.id"] != null
|
tags["thread.id"] != null
|
||||||
|
tags[Config.RUNTIME_ID_TAG] == Config.get().runtimeId
|
||||||
tags["span.origin.type"] == handler.class.name
|
tags["span.origin.type"] == handler.class.name
|
||||||
tags.size() == 9
|
tags.size() == 10
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -162,10 +164,11 @@ class JettyHandlerTest extends AgentTestRunner {
|
||||||
tags["http.status_code"] == 500
|
tags["http.status_code"] == 500
|
||||||
tags["thread.name"] != null
|
tags["thread.name"] != null
|
||||||
tags["thread.id"] != null
|
tags["thread.id"] != null
|
||||||
|
tags[Config.RUNTIME_ID_TAG] == Config.get().runtimeId
|
||||||
tags["span.origin.type"] == handler.class.name
|
tags["span.origin.type"] == handler.class.name
|
||||||
tags["error"] == true
|
tags["error"] == true
|
||||||
tags["error.type"] == RuntimeException.name
|
tags["error.type"] == RuntimeException.name
|
||||||
tags["error.stack"] != null
|
tags["error.stack"] != null
|
||||||
tags.size() == 12
|
tags.size() == 13
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,7 @@ class JMS2Test extends AgentTestRunner {
|
||||||
errored false
|
errored false
|
||||||
|
|
||||||
tags {
|
tags {
|
||||||
defaultTags()
|
defaultTags(true)
|
||||||
"${DDTags.SPAN_TYPE}" DDSpanTypes.MESSAGE_CONSUMER
|
"${DDTags.SPAN_TYPE}" DDSpanTypes.MESSAGE_CONSUMER
|
||||||
"${Tags.COMPONENT.key}" "jms"
|
"${Tags.COMPONENT.key}" "jms"
|
||||||
"${Tags.SPAN_KIND.key}" "consumer"
|
"${Tags.SPAN_KIND.key}" "consumer"
|
||||||
|
@ -145,7 +145,7 @@ class JMS2Test extends AgentTestRunner {
|
||||||
errored false
|
errored false
|
||||||
|
|
||||||
tags {
|
tags {
|
||||||
defaultTags()
|
defaultTags(true)
|
||||||
"${DDTags.SPAN_TYPE}" DDSpanTypes.MESSAGE_CONSUMER
|
"${DDTags.SPAN_TYPE}" DDSpanTypes.MESSAGE_CONSUMER
|
||||||
"${Tags.COMPONENT.key}" "jms"
|
"${Tags.COMPONENT.key}" "jms"
|
||||||
"${Tags.SPAN_KIND.key}" "consumer"
|
"${Tags.SPAN_KIND.key}" "consumer"
|
||||||
|
|
|
@ -59,7 +59,7 @@ class JMS1Test extends AgentTestRunner {
|
||||||
errored false
|
errored false
|
||||||
|
|
||||||
tags {
|
tags {
|
||||||
defaultTags()
|
defaultTags(true)
|
||||||
"${DDTags.SPAN_TYPE}" DDSpanTypes.MESSAGE_CONSUMER
|
"${DDTags.SPAN_TYPE}" DDSpanTypes.MESSAGE_CONSUMER
|
||||||
"${Tags.COMPONENT.key}" "jms"
|
"${Tags.COMPONENT.key}" "jms"
|
||||||
"${Tags.SPAN_KIND.key}" "consumer"
|
"${Tags.SPAN_KIND.key}" "consumer"
|
||||||
|
@ -111,7 +111,7 @@ class JMS1Test extends AgentTestRunner {
|
||||||
errored false
|
errored false
|
||||||
|
|
||||||
tags {
|
tags {
|
||||||
defaultTags()
|
defaultTags(true)
|
||||||
"${DDTags.SPAN_TYPE}" DDSpanTypes.MESSAGE_CONSUMER
|
"${DDTags.SPAN_TYPE}" DDSpanTypes.MESSAGE_CONSUMER
|
||||||
"${Tags.COMPONENT.key}" "jms"
|
"${Tags.COMPONENT.key}" "jms"
|
||||||
"${Tags.SPAN_KIND.key}" "consumer"
|
"${Tags.SPAN_KIND.key}" "consumer"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import datadog.trace.agent.test.AgentTestRunner
|
import datadog.trace.agent.test.AgentTestRunner
|
||||||
|
import datadog.trace.api.Config
|
||||||
import org.apache.kafka.clients.consumer.ConsumerRecord
|
import org.apache.kafka.clients.consumer.ConsumerRecord
|
||||||
import org.junit.ClassRule
|
import org.junit.ClassRule
|
||||||
import org.springframework.kafka.core.DefaultKafkaConsumerFactory
|
import org.springframework.kafka.core.DefaultKafkaConsumerFactory
|
||||||
|
@ -93,7 +94,8 @@ class KafkaClientTest extends AgentTestRunner {
|
||||||
t1tags1["span.type"] == "queue"
|
t1tags1["span.type"] == "queue"
|
||||||
t1tags1["thread.name"] != null
|
t1tags1["thread.name"] != null
|
||||||
t1tags1["thread.id"] != null
|
t1tags1["thread.id"] != null
|
||||||
t1tags1.size() == 5
|
t1tags1[Config.RUNTIME_ID_TAG] == Config.get().runtimeId
|
||||||
|
t1tags1.size() == 6
|
||||||
|
|
||||||
and: // CONSUMER span 0
|
and: // CONSUMER span 0
|
||||||
def t2span1 = t2[0]
|
def t2span1 = t2[0]
|
||||||
|
@ -113,7 +115,8 @@ class KafkaClientTest extends AgentTestRunner {
|
||||||
t2tags1["offset"] == 0
|
t2tags1["offset"] == 0
|
||||||
t2tags1["thread.name"] != null
|
t2tags1["thread.name"] != null
|
||||||
t2tags1["thread.id"] != null
|
t2tags1["thread.id"] != null
|
||||||
t2tags1.size() == 7
|
t2tags1[Config.RUNTIME_ID_TAG] == Config.get().runtimeId
|
||||||
|
t2tags1.size() == 8
|
||||||
|
|
||||||
def headers = received.headers()
|
def headers = received.headers()
|
||||||
headers.iterator().hasNext()
|
headers.iterator().hasNext()
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import datadog.trace.agent.test.AgentTestRunner
|
import datadog.trace.agent.test.AgentTestRunner
|
||||||
|
import datadog.trace.api.Config
|
||||||
import org.apache.kafka.clients.consumer.ConsumerRecord
|
import org.apache.kafka.clients.consumer.ConsumerRecord
|
||||||
import org.apache.kafka.common.serialization.Serdes
|
import org.apache.kafka.common.serialization.Serdes
|
||||||
import org.apache.kafka.streams.KafkaStreams
|
import org.apache.kafka.streams.KafkaStreams
|
||||||
|
@ -119,7 +120,8 @@ class KafkaStreamsTest extends AgentTestRunner {
|
||||||
t1tags1["span.type"] == "queue"
|
t1tags1["span.type"] == "queue"
|
||||||
t1tags1["thread.name"] != null
|
t1tags1["thread.name"] != null
|
||||||
t1tags1["thread.id"] != null
|
t1tags1["thread.id"] != null
|
||||||
t1tags1.size() == 5
|
t1tags1[Config.RUNTIME_ID_TAG] == Config.get().runtimeId
|
||||||
|
t1tags1.size() == 6
|
||||||
|
|
||||||
and: // STREAMING span 0
|
and: // STREAMING span 0
|
||||||
def t2span1 = t2[0]
|
def t2span1 = t2[0]
|
||||||
|
@ -157,8 +159,9 @@ class KafkaStreamsTest extends AgentTestRunner {
|
||||||
t2tags2["offset"] == 0
|
t2tags2["offset"] == 0
|
||||||
t2tags2["thread.name"] != null
|
t2tags2["thread.name"] != null
|
||||||
t2tags2["thread.id"] != null
|
t2tags2["thread.id"] != null
|
||||||
|
t2tags2[Config.RUNTIME_ID_TAG] == Config.get().runtimeId
|
||||||
t2tags2["asdf"] == "testing"
|
t2tags2["asdf"] == "testing"
|
||||||
t2tags2.size() == 8
|
t2tags2.size() == 9
|
||||||
|
|
||||||
and: // CONSUMER span 0
|
and: // CONSUMER span 0
|
||||||
def t3span1 = t3[0]
|
def t3span1 = t3[0]
|
||||||
|
@ -178,8 +181,9 @@ class KafkaStreamsTest extends AgentTestRunner {
|
||||||
t3tags1["offset"] == 0
|
t3tags1["offset"] == 0
|
||||||
t3tags1["thread.name"] != null
|
t3tags1["thread.name"] != null
|
||||||
t3tags1["thread.id"] != null
|
t3tags1["thread.id"] != null
|
||||||
|
t3tags1[Config.RUNTIME_ID_TAG] == Config.get().runtimeId
|
||||||
t3tags1["testing"] == 123
|
t3tags1["testing"] == 123
|
||||||
t3tags1.size() == 8
|
t3tags1.size() == 9
|
||||||
|
|
||||||
def headers = received.headers()
|
def headers = received.headers()
|
||||||
headers.iterator().hasNext()
|
headers.iterator().hasNext()
|
||||||
|
|
|
@ -38,7 +38,12 @@ class Netty40ServerTest extends AgentTestRunner {
|
||||||
int port = TestUtils.randomOpenPort()
|
int port = TestUtils.randomOpenPort()
|
||||||
initializeServer(eventLoopGroup, port, handlers, HttpResponseStatus.OK)
|
initializeServer(eventLoopGroup, port, handlers, HttpResponseStatus.OK)
|
||||||
|
|
||||||
def request = new Request.Builder().url("http://localhost:$port/").get().build()
|
def request = new Request.Builder()
|
||||||
|
.url("http://localhost:$port/")
|
||||||
|
.header("x-datadog-trace-id", "123")
|
||||||
|
.header("x-datadog-parent-id", "456")
|
||||||
|
.get()
|
||||||
|
.build()
|
||||||
def response = client.newCall(request).execute()
|
def response = client.newCall(request).execute()
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
|
@ -49,6 +54,8 @@ class Netty40ServerTest extends AgentTestRunner {
|
||||||
assertTraces(1) {
|
assertTraces(1) {
|
||||||
trace(0, 1) {
|
trace(0, 1) {
|
||||||
span(0) {
|
span(0) {
|
||||||
|
traceId "123"
|
||||||
|
parentId "456"
|
||||||
serviceName "unnamed-java-app"
|
serviceName "unnamed-java-app"
|
||||||
operationName "netty.request"
|
operationName "netty.request"
|
||||||
resourceName "GET /"
|
resourceName "GET /"
|
||||||
|
@ -63,7 +70,7 @@ class Netty40ServerTest extends AgentTestRunner {
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_SERVER
|
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_SERVER
|
||||||
defaultTags()
|
defaultTags(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ class Netty41ServerTest extends AgentTestRunner {
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_SERVER
|
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_SERVER
|
||||||
defaultTags()
|
defaultTags(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,17 +101,17 @@ class RabbitMQTest extends AgentTestRunner {
|
||||||
and:
|
and:
|
||||||
assertTraces(2) {
|
assertTraces(2) {
|
||||||
trace(0, 1) {
|
trace(0, 1) {
|
||||||
rabbitSpan(it, "basic.get <generated>", TEST_WRITER[1][1])
|
rabbitSpan(it, "basic.get <generated>", true, TEST_WRITER[1][1])
|
||||||
}
|
}
|
||||||
trace(1, 5) {
|
trace(1, 5) {
|
||||||
span(0) {
|
span(0) {
|
||||||
operationName "parent"
|
operationName "parent"
|
||||||
}
|
}
|
||||||
// reverse order
|
// reverse order
|
||||||
rabbitSpan(it, 1, "basic.publish $exchangeName -> $routingKey", span(0))
|
rabbitSpan(it, 1, "basic.publish $exchangeName -> $routingKey", false, span(0))
|
||||||
rabbitSpan(it, 2, "queue.bind", span(0))
|
rabbitSpan(it, 2, "queue.bind", false, span(0))
|
||||||
rabbitSpan(it, 3, "queue.declare", span(0))
|
rabbitSpan(it, 3, "queue.declare", false, span(0))
|
||||||
rabbitSpan(it, 4, "exchange.declare", span(0))
|
rabbitSpan(it, 4, "exchange.declare", false, span(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ class RabbitMQTest extends AgentTestRunner {
|
||||||
rabbitSpan(it, "basic.publish <default> -> <generated>")
|
rabbitSpan(it, "basic.publish <default> -> <generated>")
|
||||||
}
|
}
|
||||||
trace(2, 1) {
|
trace(2, 1) {
|
||||||
rabbitSpan(it, "basic.get <generated>", TEST_WRITER[1][0])
|
rabbitSpan(it, "basic.get <generated>", true, TEST_WRITER[1][0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ class RabbitMQTest extends AgentTestRunner {
|
||||||
rabbitSpan(it, "basic.publish $exchangeName -> <all>")
|
rabbitSpan(it, "basic.publish $exchangeName -> <all>")
|
||||||
}
|
}
|
||||||
trace(3 + (it * 2), 1) {
|
trace(3 + (it * 2), 1) {
|
||||||
rabbitSpan(it, resource, publishSpan)
|
rabbitSpan(it, resource, true, publishSpan)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,7 @@ class RabbitMQTest extends AgentTestRunner {
|
||||||
|
|
||||||
assertTraces(1) {
|
assertTraces(1) {
|
||||||
trace(0, 1) {
|
trace(0, 1) {
|
||||||
rabbitSpan(it, command, null, throwable, errorMsg)
|
rabbitSpan(it, command, false, null, throwable, errorMsg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,16 +259,31 @@ class RabbitMQTest extends AgentTestRunner {
|
||||||
rabbitSpan(it, "basic.publish <default> -> some-routing-queue")
|
rabbitSpan(it, "basic.publish <default> -> some-routing-queue")
|
||||||
}
|
}
|
||||||
trace(2, 1) {
|
trace(2, 1) {
|
||||||
rabbitSpan(it, "basic.get $queue.name", TEST_WRITER[1][0])
|
rabbitSpan(it, "basic.get $queue.name", true, TEST_WRITER[1][0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def rabbitSpan(TraceAssert trace, String resource, DDSpan parentSpan = null, Throwable exception = null, String errorMsg = null) {
|
def rabbitSpan(
|
||||||
rabbitSpan(trace, 0, resource, parentSpan, exception, errorMsg)
|
TraceAssert trace,
|
||||||
|
String resource,
|
||||||
|
Boolean distributedRootSpan = false,
|
||||||
|
DDSpan parentSpan = null,
|
||||||
|
Throwable exception = null,
|
||||||
|
String errorMsg = null
|
||||||
|
) {
|
||||||
|
rabbitSpan(trace, 0, resource, distributedRootSpan, parentSpan, exception, errorMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
def rabbitSpan(TraceAssert trace, int index, String resource, DDSpan parentSpan = null, Throwable exception = null, String errorMsg = null) {
|
def rabbitSpan(
|
||||||
|
TraceAssert trace,
|
||||||
|
int index,
|
||||||
|
String resource,
|
||||||
|
Boolean distributedRootSpan = false,
|
||||||
|
DDSpan parentSpan = null,
|
||||||
|
Throwable exception = null,
|
||||||
|
String errorMsg = null
|
||||||
|
) {
|
||||||
trace.span(index) {
|
trace.span(index) {
|
||||||
serviceName "rabbitmq"
|
serviceName "rabbitmq"
|
||||||
operationName "amqp.command"
|
operationName "amqp.command"
|
||||||
|
@ -322,7 +337,7 @@ class RabbitMQTest extends AgentTestRunner {
|
||||||
"$DDTags.SPAN_TYPE" DDSpanTypes.MESSAGE_CLIENT
|
"$DDTags.SPAN_TYPE" DDSpanTypes.MESSAGE_CLIENT
|
||||||
"amqp.command" { it == null || it == resource }
|
"amqp.command" { it == null || it == resource }
|
||||||
}
|
}
|
||||||
defaultTags()
|
defaultTags(distributedRootSpan)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,9 +47,6 @@ class JettyServlet2Test extends AgentTestRunner {
|
||||||
|
|
||||||
jettyServer.setHandler(servletContext)
|
jettyServer.setHandler(servletContext)
|
||||||
jettyServer.start()
|
jettyServer.start()
|
||||||
|
|
||||||
System.out.println(
|
|
||||||
"Jetty server: http://localhost:" + port + "/")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def cleanup() {
|
def cleanup() {
|
||||||
|
@ -57,11 +54,15 @@ class JettyServlet2Test extends AgentTestRunner {
|
||||||
jettyServer.destroy()
|
jettyServer.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test #path servlet call"() {
|
def "test #path servlet call (auth: #auth, distributed tracing: #distributedTracing)"() {
|
||||||
setup:
|
setup:
|
||||||
def requestBuilder = new Request.Builder()
|
def requestBuilder = new Request.Builder()
|
||||||
.url("http://localhost:$port/ctx/$path")
|
.url("http://localhost:$port/ctx/$path")
|
||||||
.get()
|
.get()
|
||||||
|
if (distributedTracing) {
|
||||||
|
requestBuilder.header("x-datadog-trace-id", "123")
|
||||||
|
requestBuilder.header("x-datadog-parent-id", "456")
|
||||||
|
}
|
||||||
if (auth) {
|
if (auth) {
|
||||||
requestBuilder.header(HttpHeaders.AUTHORIZATION, Credentials.basic("user", "password"))
|
requestBuilder.header(HttpHeaders.AUTHORIZATION, Credentials.basic("user", "password"))
|
||||||
}
|
}
|
||||||
|
@ -73,12 +74,17 @@ class JettyServlet2Test extends AgentTestRunner {
|
||||||
assertTraces(1) {
|
assertTraces(1) {
|
||||||
trace(0, 1) {
|
trace(0, 1) {
|
||||||
span(0) {
|
span(0) {
|
||||||
|
if (distributedTracing) {
|
||||||
|
traceId "123"
|
||||||
|
parentId "456"
|
||||||
|
} else {
|
||||||
|
parent()
|
||||||
|
}
|
||||||
serviceName "ctx"
|
serviceName "ctx"
|
||||||
operationName "servlet.request"
|
operationName "servlet.request"
|
||||||
resourceName "GET /ctx/$path"
|
resourceName "GET /ctx/$path"
|
||||||
spanType DDSpanTypes.WEB_SERVLET
|
spanType DDSpanTypes.WEB_SERVLET
|
||||||
errored false
|
errored false
|
||||||
parent()
|
|
||||||
tags {
|
tags {
|
||||||
"http.url" "http://localhost:$port/ctx/$path"
|
"http.url" "http://localhost:$port/ctx/$path"
|
||||||
"http.method" "GET"
|
"http.method" "GET"
|
||||||
|
@ -90,16 +96,18 @@ class JettyServlet2Test extends AgentTestRunner {
|
||||||
if (auth) {
|
if (auth) {
|
||||||
"user.principal" "user"
|
"user.principal" "user"
|
||||||
}
|
}
|
||||||
defaultTags()
|
defaultTags(distributedTracing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
where:
|
where:
|
||||||
path | expectedResponse | auth
|
path | expectedResponse | auth | distributedTracing
|
||||||
"sync" | "Hello Sync" | false
|
"sync" | "Hello Sync" | false | false
|
||||||
"auth/sync" | "Hello Sync" | true
|
"auth/sync" | "Hello Sync" | true | false
|
||||||
|
"sync" | "Hello Sync" | false | true
|
||||||
|
"auth/sync" | "Hello Sync" | true | true
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test #path error servlet call"() {
|
def "test #path error servlet call"() {
|
||||||
|
|
|
@ -100,7 +100,7 @@ class JettyServlet3Test extends AgentTestRunner {
|
||||||
if (auth) {
|
if (auth) {
|
||||||
"user.principal" "user"
|
"user.principal" "user"
|
||||||
}
|
}
|
||||||
defaultTags()
|
defaultTags(distributedTracing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ class TomcatServlet3Test extends AgentTestRunner {
|
||||||
"span.origin.type" ApplicationFilterChain.name
|
"span.origin.type" ApplicationFilterChain.name
|
||||||
"servlet.context" "/my-context"
|
"servlet.context" "/my-context"
|
||||||
"http.status_code" 200
|
"http.status_code" 200
|
||||||
defaultTags()
|
defaultTags(distributedTracing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import datadog.trace.agent.test.AgentTestRunner
|
import datadog.trace.agent.test.AgentTestRunner
|
||||||
import datadog.trace.agent.test.TestUtils
|
import datadog.trace.agent.test.TestUtils
|
||||||
import datadog.trace.agent.test.utils.OkHttpUtils
|
import datadog.trace.agent.test.utils.OkHttpUtils
|
||||||
|
import datadog.trace.api.Config
|
||||||
import datadog.trace.api.DDSpanTypes
|
import datadog.trace.api.DDSpanTypes
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
|
@ -91,8 +92,9 @@ class SparkJavaBasedTest extends AgentTestRunner {
|
||||||
tags["http.status_code"] == 200
|
tags["http.status_code"] == 200
|
||||||
tags["thread.name"] != null
|
tags["thread.name"] != null
|
||||||
tags["thread.id"] != null
|
tags["thread.id"] != null
|
||||||
|
tags[Config.RUNTIME_ID_TAG] == Config.get().runtimeId
|
||||||
tags["span.origin.type"] == JettyHandler.name
|
tags["span.origin.type"] == JettyHandler.name
|
||||||
tags.size() == 9
|
tags.size() == 10
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ class VertxServerTest extends AgentTestRunner {
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_SERVER
|
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_SERVER
|
||||||
defaultTags()
|
defaultTags(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
span(1) {
|
span(1) {
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
package datadog.trace.agent.test.asserts
|
package datadog.trace.agent.test.asserts
|
||||||
|
|
||||||
import datadog.opentracing.DDSpan
|
import datadog.opentracing.DDSpan
|
||||||
|
import datadog.trace.api.Config
|
||||||
import groovy.transform.stc.ClosureParams
|
import groovy.transform.stc.ClosureParams
|
||||||
import groovy.transform.stc.SimpleType
|
import groovy.transform.stc.SimpleType
|
||||||
|
|
||||||
class TagsAssert {
|
class TagsAssert {
|
||||||
|
private final String spanParentId
|
||||||
private final Map<String, Object> tags
|
private final Map<String, Object> tags
|
||||||
private final Set<String> assertedTags = new TreeSet<>()
|
private final Set<String> assertedTags = new TreeSet<>()
|
||||||
|
|
||||||
private TagsAssert(DDSpan span) {
|
private TagsAssert(DDSpan span) {
|
||||||
|
this.spanParentId = span.parentId
|
||||||
this.tags = span.tags
|
this.tags = span.tags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,12 +26,21 @@ class TagsAssert {
|
||||||
asserter.assertTagsAllVerified()
|
asserter.assertTagsAllVerified()
|
||||||
}
|
}
|
||||||
|
|
||||||
def defaultTags() {
|
/**
|
||||||
|
* @param distributedRootSpan set to true if current span has a parent span but still considered 'root' for current service
|
||||||
|
*/
|
||||||
|
def defaultTags(boolean distributedRootSpan = false) {
|
||||||
assertedTags.add("thread.name")
|
assertedTags.add("thread.name")
|
||||||
assertedTags.add("thread.id")
|
assertedTags.add("thread.id")
|
||||||
|
assertedTags.add(Config.RUNTIME_ID_TAG)
|
||||||
|
|
||||||
assert tags["thread.name"] != null
|
assert tags["thread.name"] != null
|
||||||
assert tags["thread.id"] != null
|
assert tags["thread.id"] != null
|
||||||
|
if ("0" == spanParentId || distributedRootSpan) {
|
||||||
|
assert tags[Config.RUNTIME_ID_TAG] == Config.get().runtimeId
|
||||||
|
} else {
|
||||||
|
assert tags[Config.RUNTIME_ID_TAG] == null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def errorTags(Class<Throwable> errorType) {
|
def errorTags(Class<Throwable> errorType) {
|
||||||
|
|
|
@ -104,7 +104,7 @@ class TestHttpServer implements AutoCloseable {
|
||||||
childOf(parentSpan)
|
childOf(parentSpan)
|
||||||
}
|
}
|
||||||
tags {
|
tags {
|
||||||
defaultTags()
|
defaultTags(parentSpan != null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
apply from: "${rootDir}/gradle/java.gradle"
|
apply from: "${rootDir}/gradle/java.gradle"
|
||||||
|
|
||||||
minimumBranchCoverage = 0.5
|
minimumBranchCoverage = 0.5
|
||||||
minimumInstructionCoverage = 0.6
|
minimumInstructionCoverage = 0.5
|
||||||
excludedClassesConverage += [
|
excludedClassesConverage += [
|
||||||
'datadog.trace.agent.test.asserts.*Assert',
|
'datadog.trace.agent.test.asserts.*Assert',
|
||||||
'datadog.trace.agent.test.AgentTestRunner.ErrorCountingListener',
|
'datadog.trace.agent.test.AgentTestRunner.ErrorCountingListener',
|
||||||
|
|
|
@ -6,6 +6,7 @@ import java.util.HashMap;
|
||||||
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 java.util.UUID;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
@ -34,7 +35,9 @@ public class Config {
|
||||||
public static final String PRIORITY_SAMPLING = "priority.sampling";
|
public static final String PRIORITY_SAMPLING = "priority.sampling";
|
||||||
public static final String TRACE_RESOLVER_ENABLED = "trace.resolver.enabled";
|
public static final String TRACE_RESOLVER_ENABLED = "trace.resolver.enabled";
|
||||||
public static final String SERVICE_MAPPING = "service.mapping";
|
public static final String SERVICE_MAPPING = "service.mapping";
|
||||||
|
public static final String GLOBAL_TAGS = "trace.global.tags";
|
||||||
public static final String SPAN_TAGS = "trace.span.tags";
|
public static final String SPAN_TAGS = "trace.span.tags";
|
||||||
|
public static final String JMX_TAGS = "trace.jmx.tags";
|
||||||
public static final String HEADER_TAGS = "trace.header.tags";
|
public static final String HEADER_TAGS = "trace.header.tags";
|
||||||
public static final String JMX_FETCH_ENABLED = "jmxfetch.enabled";
|
public static final String JMX_FETCH_ENABLED = "jmxfetch.enabled";
|
||||||
public static final String JMX_FETCH_METRICS_CONFIGS = "jmxfetch.metrics-configs";
|
public static final String JMX_FETCH_METRICS_CONFIGS = "jmxfetch.metrics-configs";
|
||||||
|
@ -43,6 +46,7 @@ public class Config {
|
||||||
public static final String JMX_FETCH_STATSD_HOST = "jmxfetch.statsd.host";
|
public static final String JMX_FETCH_STATSD_HOST = "jmxfetch.statsd.host";
|
||||||
public static final String JMX_FETCH_STATSD_PORT = "jmxfetch.statsd.port";
|
public static final String JMX_FETCH_STATSD_PORT = "jmxfetch.statsd.port";
|
||||||
|
|
||||||
|
public static final String RUNTIME_ID_TAG = "runtime-id";
|
||||||
public static final String DEFAULT_SERVICE_NAME = "unnamed-java-app";
|
public static final String DEFAULT_SERVICE_NAME = "unnamed-java-app";
|
||||||
|
|
||||||
public static final String DD_AGENT_WRITER_TYPE = "DDAgentWriter";
|
public static final String DD_AGENT_WRITER_TYPE = "DDAgentWriter";
|
||||||
|
@ -58,6 +62,8 @@ public class Config {
|
||||||
|
|
||||||
public static final int DEFAULT_JMX_FETCH_STATSD_PORT = 8125;
|
public static final int DEFAULT_JMX_FETCH_STATSD_PORT = 8125;
|
||||||
|
|
||||||
|
@Getter private final String runtimeId;
|
||||||
|
|
||||||
@Getter private final String serviceName;
|
@Getter private final String serviceName;
|
||||||
@Getter private final String writerType;
|
@Getter private final String writerType;
|
||||||
@Getter private final String agentHost;
|
@Getter private final String agentHost;
|
||||||
|
@ -65,7 +71,9 @@ public class Config {
|
||||||
@Getter private final boolean prioritySamplingEnabled;
|
@Getter private final boolean prioritySamplingEnabled;
|
||||||
@Getter private final boolean traceResolverEnabled;
|
@Getter private final boolean traceResolverEnabled;
|
||||||
@Getter private final Map<String, String> serviceMapping;
|
@Getter private final Map<String, String> serviceMapping;
|
||||||
@Getter private final Map<String, String> spanTags;
|
private final Map<String, String> globalTags;
|
||||||
|
private final Map<String, String> spanTags;
|
||||||
|
private final Map<String, String> jmxTags;
|
||||||
@Getter private final Map<String, String> headerTags;
|
@Getter private final Map<String, String> headerTags;
|
||||||
@Getter private final boolean jmxFetchEnabled;
|
@Getter private final boolean jmxFetchEnabled;
|
||||||
@Getter private final List<String> jmxFetchMetricsConfigs;
|
@Getter private final List<String> jmxFetchMetricsConfigs;
|
||||||
|
@ -77,6 +85,8 @@ public class Config {
|
||||||
// Read order: System Properties -> Env Variables, [-> default value]
|
// Read order: System Properties -> Env Variables, [-> default value]
|
||||||
// Visible for testing
|
// Visible for testing
|
||||||
Config() {
|
Config() {
|
||||||
|
runtimeId = UUID.randomUUID().toString();
|
||||||
|
|
||||||
serviceName = getSettingFromEnvironment(SERVICE_NAME, DEFAULT_SERVICE_NAME);
|
serviceName = getSettingFromEnvironment(SERVICE_NAME, DEFAULT_SERVICE_NAME);
|
||||||
writerType = getSettingFromEnvironment(WRITER_TYPE, DEFAULT_AGENT_WRITER_TYPE);
|
writerType = getSettingFromEnvironment(WRITER_TYPE, DEFAULT_AGENT_WRITER_TYPE);
|
||||||
agentHost = getSettingFromEnvironment(AGENT_HOST, DEFAULT_AGENT_HOST);
|
agentHost = getSettingFromEnvironment(AGENT_HOST, DEFAULT_AGENT_HOST);
|
||||||
|
@ -86,7 +96,11 @@ public class Config {
|
||||||
traceResolverEnabled =
|
traceResolverEnabled =
|
||||||
getBooleanSettingFromEnvironment(TRACE_RESOLVER_ENABLED, DEFAULT_TRACE_RESOLVER_ENABLED);
|
getBooleanSettingFromEnvironment(TRACE_RESOLVER_ENABLED, DEFAULT_TRACE_RESOLVER_ENABLED);
|
||||||
serviceMapping = getMapSettingFromEnvironment(SERVICE_MAPPING, null);
|
serviceMapping = getMapSettingFromEnvironment(SERVICE_MAPPING, null);
|
||||||
|
|
||||||
|
globalTags = getMapSettingFromEnvironment(GLOBAL_TAGS, null);
|
||||||
spanTags = getMapSettingFromEnvironment(SPAN_TAGS, null);
|
spanTags = getMapSettingFromEnvironment(SPAN_TAGS, null);
|
||||||
|
jmxTags = getMapSettingFromEnvironment(JMX_TAGS, null);
|
||||||
|
|
||||||
headerTags = getMapSettingFromEnvironment(HEADER_TAGS, null);
|
headerTags = getMapSettingFromEnvironment(HEADER_TAGS, null);
|
||||||
jmxFetchEnabled =
|
jmxFetchEnabled =
|
||||||
getBooleanSettingFromEnvironment(JMX_FETCH_ENABLED, DEFAULT_JMX_FETCH_ENABLED);
|
getBooleanSettingFromEnvironment(JMX_FETCH_ENABLED, DEFAULT_JMX_FETCH_ENABLED);
|
||||||
|
@ -101,6 +115,8 @@ public class Config {
|
||||||
|
|
||||||
// Read order: Properties -> Parent
|
// Read order: Properties -> Parent
|
||||||
private Config(final Properties properties, final Config parent) {
|
private Config(final Properties properties, final Config parent) {
|
||||||
|
runtimeId = parent.runtimeId;
|
||||||
|
|
||||||
serviceName = properties.getProperty(SERVICE_NAME, parent.serviceName);
|
serviceName = properties.getProperty(SERVICE_NAME, parent.serviceName);
|
||||||
writerType = properties.getProperty(WRITER_TYPE, parent.writerType);
|
writerType = properties.getProperty(WRITER_TYPE, parent.writerType);
|
||||||
agentHost = properties.getProperty(AGENT_HOST, parent.agentHost);
|
agentHost = properties.getProperty(AGENT_HOST, parent.agentHost);
|
||||||
|
@ -110,7 +126,11 @@ public class Config {
|
||||||
traceResolverEnabled =
|
traceResolverEnabled =
|
||||||
getPropertyBooleanValue(properties, TRACE_RESOLVER_ENABLED, parent.traceResolverEnabled);
|
getPropertyBooleanValue(properties, TRACE_RESOLVER_ENABLED, parent.traceResolverEnabled);
|
||||||
serviceMapping = getPropertyMapValue(properties, SERVICE_MAPPING, parent.serviceMapping);
|
serviceMapping = getPropertyMapValue(properties, SERVICE_MAPPING, parent.serviceMapping);
|
||||||
|
|
||||||
|
globalTags = getPropertyMapValue(properties, GLOBAL_TAGS, parent.globalTags);
|
||||||
spanTags = getPropertyMapValue(properties, SPAN_TAGS, parent.spanTags);
|
spanTags = getPropertyMapValue(properties, SPAN_TAGS, parent.spanTags);
|
||||||
|
jmxTags = getPropertyMapValue(properties, JMX_TAGS, parent.jmxTags);
|
||||||
|
|
||||||
headerTags = getPropertyMapValue(properties, HEADER_TAGS, parent.headerTags);
|
headerTags = getPropertyMapValue(properties, HEADER_TAGS, parent.headerTags);
|
||||||
jmxFetchEnabled =
|
jmxFetchEnabled =
|
||||||
getPropertyBooleanValue(properties, JMX_FETCH_ENABLED, parent.jmxFetchEnabled);
|
getPropertyBooleanValue(properties, JMX_FETCH_ENABLED, parent.jmxFetchEnabled);
|
||||||
|
@ -126,6 +146,22 @@ public class Config {
|
||||||
getPropertyIntegerValue(properties, JMX_FETCH_STATSD_PORT, parent.jmxFetchStatsdPort);
|
getPropertyIntegerValue(properties, JMX_FETCH_STATSD_PORT, parent.jmxFetchStatsdPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getMergedSpanTags() {
|
||||||
|
// DO not include runtimeId into span tags: we only want that added to the root span
|
||||||
|
final Map<String, String> result = newHashMap(globalTags.size() + spanTags.size());
|
||||||
|
result.putAll(globalTags);
|
||||||
|
result.putAll(spanTags);
|
||||||
|
return Collections.unmodifiableMap(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getMergedJmxTags() {
|
||||||
|
final Map<String, String> result = newHashMap(globalTags.size() + jmxTags.size() + 1);
|
||||||
|
result.putAll(globalTags);
|
||||||
|
result.putAll(jmxTags);
|
||||||
|
result.put(RUNTIME_ID_TAG, runtimeId);
|
||||||
|
return Collections.unmodifiableMap(result);
|
||||||
|
}
|
||||||
|
|
||||||
private static String getSettingFromEnvironment(final String name, final String defaultValue) {
|
private static String getSettingFromEnvironment(final String name, final String defaultValue) {
|
||||||
final String completeName = PREFIX + name;
|
final String completeName = PREFIX + name;
|
||||||
final String value =
|
final String value =
|
||||||
|
@ -195,7 +231,7 @@ public class Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
final String[] tokens = str.split(",", -1);
|
final String[] tokens = str.split(",", -1);
|
||||||
final Map<String, String> map = new HashMap<>(tokens.length + 1, 1f);
|
final Map<String, String> map = newHashMap(tokens.length);
|
||||||
|
|
||||||
for (final String token : tokens) {
|
for (final String token : tokens) {
|
||||||
final String[] keyValue = token.split(":", -1);
|
final String[] keyValue = token.split(":", -1);
|
||||||
|
@ -212,6 +248,10 @@ public class Config {
|
||||||
return Collections.unmodifiableMap(map);
|
return Collections.unmodifiableMap(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Map<String, String> newHashMap(final int size) {
|
||||||
|
return new HashMap<>(size + 1, 1f);
|
||||||
|
}
|
||||||
|
|
||||||
private static List<String> parseList(final String str) {
|
private static List<String> parseList(final String str) {
|
||||||
if (str == null || str.trim().isEmpty()) {
|
if (str == null || str.trim().isEmpty()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
|
|
@ -5,23 +5,7 @@ import org.junit.contrib.java.lang.system.EnvironmentVariables
|
||||||
import org.junit.contrib.java.lang.system.RestoreSystemProperties
|
import org.junit.contrib.java.lang.system.RestoreSystemProperties
|
||||||
import spock.lang.Specification
|
import spock.lang.Specification
|
||||||
|
|
||||||
import static Config.AGENT_HOST
|
import static datadog.trace.api.Config.*
|
||||||
import static Config.AGENT_PORT
|
|
||||||
import static Config.HEADER_TAGS
|
|
||||||
import static Config.PREFIX
|
|
||||||
import static Config.SERVICE_MAPPING
|
|
||||||
import static Config.SERVICE_NAME
|
|
||||||
import static Config.SPAN_TAGS
|
|
||||||
import static Config.WRITER_TYPE
|
|
||||||
import static datadog.trace.api.Config.DEFAULT_JMX_FETCH_STATSD_PORT
|
|
||||||
import static datadog.trace.api.Config.JMX_FETCH_CHECK_PERIOD
|
|
||||||
import static datadog.trace.api.Config.JMX_FETCH_ENABLED
|
|
||||||
import static datadog.trace.api.Config.JMX_FETCH_METRICS_CONFIGS
|
|
||||||
import static datadog.trace.api.Config.JMX_FETCH_REFRESH_BEANS_PERIOD
|
|
||||||
import static datadog.trace.api.Config.JMX_FETCH_STATSD_HOST
|
|
||||||
import static datadog.trace.api.Config.JMX_FETCH_STATSD_PORT
|
|
||||||
import static datadog.trace.api.Config.PRIORITY_SAMPLING
|
|
||||||
import static datadog.trace.api.Config.TRACE_RESOLVER_ENABLED
|
|
||||||
|
|
||||||
class ConfigTest extends Specification {
|
class ConfigTest extends Specification {
|
||||||
@Rule
|
@Rule
|
||||||
|
@ -47,7 +31,8 @@ class ConfigTest extends Specification {
|
||||||
config.prioritySamplingEnabled == false
|
config.prioritySamplingEnabled == false
|
||||||
config.traceResolverEnabled == true
|
config.traceResolverEnabled == true
|
||||||
config.serviceMapping == [:]
|
config.serviceMapping == [:]
|
||||||
config.spanTags == [:]
|
config.mergedSpanTags == [:]
|
||||||
|
config.mergedJmxTags == [(RUNTIME_ID_TAG): config.getRuntimeId()]
|
||||||
config.headerTags == [:]
|
config.headerTags == [:]
|
||||||
config.jmxFetchEnabled == false
|
config.jmxFetchEnabled == false
|
||||||
config.jmxFetchMetricsConfigs == []
|
config.jmxFetchMetricsConfigs == []
|
||||||
|
@ -67,8 +52,10 @@ class ConfigTest extends Specification {
|
||||||
System.setProperty(PREFIX + PRIORITY_SAMPLING, "true")
|
System.setProperty(PREFIX + PRIORITY_SAMPLING, "true")
|
||||||
System.setProperty(PREFIX + TRACE_RESOLVER_ENABLED, "false")
|
System.setProperty(PREFIX + TRACE_RESOLVER_ENABLED, "false")
|
||||||
System.setProperty(PREFIX + SERVICE_MAPPING, "a:1")
|
System.setProperty(PREFIX + SERVICE_MAPPING, "a:1")
|
||||||
System.setProperty(PREFIX + SPAN_TAGS, "b:2")
|
System.setProperty(PREFIX + GLOBAL_TAGS, "b:2")
|
||||||
System.setProperty(PREFIX + HEADER_TAGS, "c:3")
|
System.setProperty(PREFIX + SPAN_TAGS, "c:3")
|
||||||
|
System.setProperty(PREFIX + JMX_TAGS, "d:4")
|
||||||
|
System.setProperty(PREFIX + HEADER_TAGS, "e:5")
|
||||||
System.setProperty(PREFIX + JMX_FETCH_ENABLED, "true")
|
System.setProperty(PREFIX + JMX_FETCH_ENABLED, "true")
|
||||||
System.setProperty(PREFIX + JMX_FETCH_METRICS_CONFIGS, "/foo.yaml,/bar.yaml")
|
System.setProperty(PREFIX + JMX_FETCH_METRICS_CONFIGS, "/foo.yaml,/bar.yaml")
|
||||||
System.setProperty(PREFIX + JMX_FETCH_CHECK_PERIOD, "100")
|
System.setProperty(PREFIX + JMX_FETCH_CHECK_PERIOD, "100")
|
||||||
|
@ -87,8 +74,9 @@ class ConfigTest extends Specification {
|
||||||
config.prioritySamplingEnabled == true
|
config.prioritySamplingEnabled == true
|
||||||
config.traceResolverEnabled == false
|
config.traceResolverEnabled == false
|
||||||
config.serviceMapping == [a: "1"]
|
config.serviceMapping == [a: "1"]
|
||||||
config.spanTags == [b: "2"]
|
config.mergedSpanTags == [b: "2", c: "3"]
|
||||||
config.headerTags == [c: "3"]
|
config.mergedJmxTags == [b: "2", d: "4", (RUNTIME_ID_TAG): config.getRuntimeId()]
|
||||||
|
config.headerTags == [e: "5"]
|
||||||
config.jmxFetchEnabled == true
|
config.jmxFetchEnabled == true
|
||||||
config.jmxFetchMetricsConfigs == ["/foo.yaml", "/bar.yaml"]
|
config.jmxFetchMetricsConfigs == ["/foo.yaml", "/bar.yaml"]
|
||||||
config.jmxFetchCheckPeriod == 100
|
config.jmxFetchCheckPeriod == 100
|
||||||
|
@ -140,8 +128,10 @@ class ConfigTest extends Specification {
|
||||||
properties.setProperty(PRIORITY_SAMPLING, "true")
|
properties.setProperty(PRIORITY_SAMPLING, "true")
|
||||||
properties.setProperty(TRACE_RESOLVER_ENABLED, "false")
|
properties.setProperty(TRACE_RESOLVER_ENABLED, "false")
|
||||||
properties.setProperty(SERVICE_MAPPING, "a:1")
|
properties.setProperty(SERVICE_MAPPING, "a:1")
|
||||||
properties.setProperty(SPAN_TAGS, "b:2")
|
properties.setProperty(GLOBAL_TAGS, "b:2")
|
||||||
properties.setProperty(HEADER_TAGS, "c:3")
|
properties.setProperty(SPAN_TAGS, "c:3")
|
||||||
|
properties.setProperty(JMX_TAGS, "d:4")
|
||||||
|
properties.setProperty(HEADER_TAGS, "e:5")
|
||||||
properties.setProperty(JMX_FETCH_METRICS_CONFIGS, "/foo.yaml,/bar.yaml")
|
properties.setProperty(JMX_FETCH_METRICS_CONFIGS, "/foo.yaml,/bar.yaml")
|
||||||
properties.setProperty(JMX_FETCH_CHECK_PERIOD, "100")
|
properties.setProperty(JMX_FETCH_CHECK_PERIOD, "100")
|
||||||
properties.setProperty(JMX_FETCH_REFRESH_BEANS_PERIOD, "200")
|
properties.setProperty(JMX_FETCH_REFRESH_BEANS_PERIOD, "200")
|
||||||
|
@ -159,8 +149,9 @@ class ConfigTest extends Specification {
|
||||||
config.prioritySamplingEnabled == true
|
config.prioritySamplingEnabled == true
|
||||||
config.traceResolverEnabled == false
|
config.traceResolverEnabled == false
|
||||||
config.serviceMapping == [a: "1"]
|
config.serviceMapping == [a: "1"]
|
||||||
config.spanTags == [b: "2"]
|
config.mergedSpanTags == [b: "2", c: "3"]
|
||||||
config.headerTags == [c: "3"]
|
config.mergedJmxTags == [b: "2", d: "4", (RUNTIME_ID_TAG): config.getRuntimeId()]
|
||||||
|
config.headerTags == [e: "5"]
|
||||||
config.jmxFetchMetricsConfigs == ["/foo.yaml", "/bar.yaml"]
|
config.jmxFetchMetricsConfigs == ["/foo.yaml", "/bar.yaml"]
|
||||||
config.jmxFetchCheckPeriod == 100
|
config.jmxFetchCheckPeriod == 100
|
||||||
config.jmxFetchRefreshBeansPeriod == 200
|
config.jmxFetchRefreshBeansPeriod == 200
|
||||||
|
|
|
@ -52,6 +52,8 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
||||||
/** Scope manager is in charge of managing the scopes from which spans are created */
|
/** Scope manager is in charge of managing the scopes from which spans are created */
|
||||||
final ContextualScopeManager scopeManager = new ContextualScopeManager();
|
final ContextualScopeManager scopeManager = new ContextualScopeManager();
|
||||||
|
|
||||||
|
/** Value for runtime-id tag */
|
||||||
|
private final String runtimeId;
|
||||||
/** A set of tags that are added to every span */
|
/** A set of tags that are added to every span */
|
||||||
private final Map<String, String> defaultSpanTags;
|
private final Map<String, String> defaultSpanTags;
|
||||||
/** A configured mapping of service names to update with new values */
|
/** A configured mapping of service names to update with new values */
|
||||||
|
@ -95,17 +97,24 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
||||||
serviceName,
|
serviceName,
|
||||||
Writer.Builder.forConfig(config),
|
Writer.Builder.forConfig(config),
|
||||||
Sampler.Builder.forConfig(config),
|
Sampler.Builder.forConfig(config),
|
||||||
config.getSpanTags(),
|
config.getRuntimeId(),
|
||||||
|
config.getMergedSpanTags(),
|
||||||
config.getServiceMapping(),
|
config.getServiceMapping(),
|
||||||
config.getHeaderTags());
|
config.getHeaderTags());
|
||||||
log.debug("Using config: {}", config);
|
log.debug("Using config: {}", config);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DDTracer(final String serviceName, final Writer writer, final Sampler sampler) {
|
/** Visible for testing */
|
||||||
|
DDTracer(
|
||||||
|
final String serviceName,
|
||||||
|
final Writer writer,
|
||||||
|
final Sampler sampler,
|
||||||
|
final String runtimeId) {
|
||||||
this(
|
this(
|
||||||
serviceName,
|
serviceName,
|
||||||
writer,
|
writer,
|
||||||
sampler,
|
sampler,
|
||||||
|
runtimeId,
|
||||||
Collections.<String, String>emptyMap(),
|
Collections.<String, String>emptyMap(),
|
||||||
Collections.<String, String>emptyMap(),
|
Collections.<String, String>emptyMap(),
|
||||||
Collections.<String, String>emptyMap());
|
Collections.<String, String>emptyMap());
|
||||||
|
@ -120,7 +129,8 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
||||||
config.getServiceName(),
|
config.getServiceName(),
|
||||||
writer,
|
writer,
|
||||||
Sampler.Builder.forConfig(config),
|
Sampler.Builder.forConfig(config),
|
||||||
config.getSpanTags(),
|
config.getRuntimeId(),
|
||||||
|
config.getMergedSpanTags(),
|
||||||
config.getServiceMapping(),
|
config.getServiceMapping(),
|
||||||
config.getHeaderTags());
|
config.getHeaderTags());
|
||||||
}
|
}
|
||||||
|
@ -129,9 +139,11 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
||||||
final String serviceName,
|
final String serviceName,
|
||||||
final Writer writer,
|
final Writer writer,
|
||||||
final Sampler sampler,
|
final Sampler sampler,
|
||||||
|
final String runtimeId,
|
||||||
final Map<String, String> defaultSpanTags,
|
final Map<String, String> defaultSpanTags,
|
||||||
final Map<String, String> serviceNameMappings,
|
final Map<String, String> serviceNameMappings,
|
||||||
final Map<String, String> taggedHeaders) {
|
final Map<String, String> taggedHeaders) {
|
||||||
|
assert runtimeId != null;
|
||||||
assert defaultSpanTags != null;
|
assert defaultSpanTags != null;
|
||||||
assert serviceNameMappings != null;
|
assert serviceNameMappings != null;
|
||||||
assert taggedHeaders != null;
|
assert taggedHeaders != null;
|
||||||
|
@ -141,6 +153,7 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
||||||
this.writer.start();
|
this.writer.start();
|
||||||
this.sampler = sampler;
|
this.sampler = sampler;
|
||||||
this.defaultSpanTags = defaultSpanTags;
|
this.defaultSpanTags = defaultSpanTags;
|
||||||
|
this.runtimeId = runtimeId;
|
||||||
this.serviceNameMappings = serviceNameMappings;
|
this.serviceNameMappings = serviceNameMappings;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -335,6 +348,8 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
||||||
+ writer
|
+ writer
|
||||||
+ ", sampler="
|
+ ", sampler="
|
||||||
+ sampler
|
+ sampler
|
||||||
|
+ ", runtimeId="
|
||||||
|
+ runtimeId
|
||||||
+ ", defaultSpanTags="
|
+ ", defaultSpanTags="
|
||||||
+ defaultSpanTags
|
+ defaultSpanTags
|
||||||
+ '}';
|
+ '}';
|
||||||
|
@ -361,7 +376,7 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
||||||
private final String operationName;
|
private final String operationName;
|
||||||
|
|
||||||
// Builder attributes
|
// Builder attributes
|
||||||
private Map<String, Object> tags = new HashMap<String, Object>(defaultSpanTags);
|
private final Map<String, Object> tags = new HashMap<String, Object>(defaultSpanTags);
|
||||||
private long timestampMicro;
|
private long timestampMicro;
|
||||||
private SpanContext parent;
|
private SpanContext parent;
|
||||||
private String serviceName;
|
private String serviceName;
|
||||||
|
@ -536,12 +551,8 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
||||||
traceId = ddsc.getTraceId();
|
traceId = ddsc.getTraceId();
|
||||||
parentSpanId = ddsc.getSpanId();
|
parentSpanId = ddsc.getSpanId();
|
||||||
baggage = ddsc.getBaggage();
|
baggage = ddsc.getBaggage();
|
||||||
if (tags.isEmpty() && !ddsc.getTags().isEmpty()) {
|
tags.putAll(ddsc.getTags());
|
||||||
tags = new HashMap<>();
|
tags.put(Config.RUNTIME_ID_TAG, runtimeId);
|
||||||
}
|
|
||||||
if (!ddsc.getTags().isEmpty()) {
|
|
||||||
tags.putAll(ddsc.getTags());
|
|
||||||
}
|
|
||||||
parentTrace = new PendingTrace(DDTracer.this, traceId, serviceNameMappings);
|
parentTrace = new PendingTrace(DDTracer.this, traceId, serviceNameMappings);
|
||||||
samplingPriority = ddsc.getSamplingPriority();
|
samplingPriority = ddsc.getSamplingPriority();
|
||||||
|
|
||||||
|
@ -550,6 +561,7 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
|
||||||
traceId = generateNewId();
|
traceId = generateNewId();
|
||||||
parentSpanId = "0";
|
parentSpanId = "0";
|
||||||
baggage = null;
|
baggage = null;
|
||||||
|
tags.put(Config.RUNTIME_ID_TAG, runtimeId);
|
||||||
parentTrace = new PendingTrace(DDTracer.this, traceId, serviceNameMappings);
|
parentTrace = new PendingTrace(DDTracer.this, traceId, serviceNameMappings);
|
||||||
samplingPriority = PrioritySampling.UNSET;
|
samplingPriority = PrioritySampling.UNSET;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import static org.mockito.Mockito.when
|
||||||
|
|
||||||
class DDSpanBuilderTest extends Specification {
|
class DDSpanBuilderTest extends Specification {
|
||||||
def writer = new ListWriter()
|
def writer = new ListWriter()
|
||||||
|
def config = Config.get()
|
||||||
def tracer = new DDTracer(writer)
|
def tracer = new DDTracer(writer)
|
||||||
|
|
||||||
def "build simple span"() {
|
def "build simple span"() {
|
||||||
|
@ -51,8 +52,9 @@ class DDSpanBuilderTest extends Specification {
|
||||||
|
|
||||||
then:
|
then:
|
||||||
span.getTags() == [
|
span.getTags() == [
|
||||||
(DDTags.THREAD_NAME): Thread.currentThread().getName(),
|
(DDTags.THREAD_NAME) : Thread.currentThread().getName(),
|
||||||
(DDTags.THREAD_ID) : Thread.currentThread().getId(),
|
(DDTags.THREAD_ID) : Thread.currentThread().getId(),
|
||||||
|
(Config.RUNTIME_ID_TAG): config.getRuntimeId()
|
||||||
]
|
]
|
||||||
|
|
||||||
when:
|
when:
|
||||||
|
@ -263,7 +265,7 @@ class DDSpanBuilderTest extends Specification {
|
||||||
span.parentId == extractedContext.spanId
|
span.parentId == extractedContext.spanId
|
||||||
span.samplingPriority == extractedContext.samplingPriority
|
span.samplingPriority == extractedContext.samplingPriority
|
||||||
span.context().baggageItems == extractedContext.baggage
|
span.context().baggageItems == extractedContext.baggage
|
||||||
span.context().@tags == extractedContext.tags
|
span.context().@tags == extractedContext.tags + [(Config.RUNTIME_ID_TAG): config.getRuntimeId()]
|
||||||
|
|
||||||
where:
|
where:
|
||||||
extractedContext | _
|
extractedContext | _
|
||||||
|
@ -274,15 +276,16 @@ class DDSpanBuilderTest extends Specification {
|
||||||
def "global span tags populated on each span"() {
|
def "global span tags populated on each span"() {
|
||||||
setup:
|
setup:
|
||||||
System.setProperty("dd.trace.span.tags", tagString)
|
System.setProperty("dd.trace.span.tags", tagString)
|
||||||
tracer = new DDTracer(new Config(), writer)
|
def config = new Config()
|
||||||
|
tracer = new DDTracer(config, writer)
|
||||||
def span = tracer.buildSpan("op name").withServiceName("foo").start()
|
def span = tracer.buildSpan("op name").withServiceName("foo").start()
|
||||||
tags.putAll([
|
|
||||||
(DDTags.THREAD_NAME): Thread.currentThread().getName(),
|
|
||||||
(DDTags.THREAD_ID) : Thread.currentThread().getId(),
|
|
||||||
])
|
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
span.tags == tags
|
span.tags == tags + [
|
||||||
|
(DDTags.THREAD_NAME) : Thread.currentThread().getName(),
|
||||||
|
(DDTags.THREAD_ID) : Thread.currentThread().getId(),
|
||||||
|
(Config.RUNTIME_ID_TAG): config.getRuntimeId()
|
||||||
|
]
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
System.clearProperty("dd.trace.span.tags")
|
System.clearProperty("dd.trace.span.tags")
|
||||||
|
|
|
@ -11,7 +11,7 @@ import static datadog.trace.api.Config.DEFAULT_SERVICE_NAME
|
||||||
|
|
||||||
class DDSpanTest extends Specification {
|
class DDSpanTest extends Specification {
|
||||||
def writer = new ListWriter()
|
def writer = new ListWriter()
|
||||||
def tracer = new DDTracer(DEFAULT_SERVICE_NAME, writer, new RateByServiceSampler())
|
def tracer = new DDTracer(DEFAULT_SERVICE_NAME, writer, new RateByServiceSampler(), "some-runtime-id")
|
||||||
|
|
||||||
def "getters and setters"() {
|
def "getters and setters"() {
|
||||||
setup:
|
setup:
|
||||||
|
|
|
@ -142,7 +142,8 @@ class TraceInterceptorTest extends Specification {
|
||||||
tags["span.type"] == "modifiedST-null"
|
tags["span.type"] == "modifiedST-null"
|
||||||
tags["thread.name"] != null
|
tags["thread.name"] != null
|
||||||
tags["thread.id"] != null
|
tags["thread.id"] != null
|
||||||
tags.size() == 6
|
tags["runtime-id"] != null
|
||||||
|
tags.size() == 7
|
||||||
}
|
}
|
||||||
|
|
||||||
def "register interceptor through bridge"() {
|
def "register interceptor through bridge"() {
|
||||||
|
|
|
@ -42,7 +42,15 @@ class SpanDecoratorTest extends Specification {
|
||||||
|
|
||||||
def "set service name"() {
|
def "set service name"() {
|
||||||
setup:
|
setup:
|
||||||
tracer = new DDTracer("wrong-service", new LoggingWriter(), new AllSampler(), emptyMap(), mapping, emptyMap())
|
tracer = new DDTracer(
|
||||||
|
"wrong-service",
|
||||||
|
new LoggingWriter(),
|
||||||
|
new AllSampler(),
|
||||||
|
"some-runtime-id",
|
||||||
|
emptyMap(),
|
||||||
|
mapping,
|
||||||
|
emptyMap()
|
||||||
|
)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def span = tracer.buildSpan("some span").withTag(tag, name).start()
|
def span = tracer.buildSpan("some span").withTag(tag, name).start()
|
||||||
|
@ -65,7 +73,15 @@ class SpanDecoratorTest extends Specification {
|
||||||
|
|
||||||
def "default or configured service name can be remapped without setting tag"() {
|
def "default or configured service name can be remapped without setting tag"() {
|
||||||
setup:
|
setup:
|
||||||
tracer = new DDTracer(serviceName, new LoggingWriter(), new AllSampler(), emptyMap(), mapping, emptyMap())
|
tracer = new DDTracer(
|
||||||
|
serviceName,
|
||||||
|
new LoggingWriter(),
|
||||||
|
new AllSampler(),
|
||||||
|
"some-runtime-id",
|
||||||
|
emptyMap(),
|
||||||
|
mapping,
|
||||||
|
emptyMap()
|
||||||
|
)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def span = tracer.buildSpan("some span").start()
|
def span = tracer.buildSpan("some span").start()
|
||||||
|
@ -103,7 +119,15 @@ class SpanDecoratorTest extends Specification {
|
||||||
|
|
||||||
def "set service name from servlet.context with context '#context' for service #serviceName"() {
|
def "set service name from servlet.context with context '#context' for service #serviceName"() {
|
||||||
setup:
|
setup:
|
||||||
tracer = new DDTracer(serviceName, new LoggingWriter(), new AllSampler(), emptyMap(), mapping, emptyMap())
|
tracer = new DDTracer(
|
||||||
|
serviceName,
|
||||||
|
new LoggingWriter(),
|
||||||
|
new AllSampler(),
|
||||||
|
"some-runtime-id",
|
||||||
|
emptyMap(),
|
||||||
|
mapping,
|
||||||
|
emptyMap()
|
||||||
|
)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def span = tracer.buildSpan("some span").start()
|
def span = tracer.buildSpan("some span").start()
|
||||||
|
|
|
@ -64,7 +64,8 @@ class DDTracerTest extends Specification {
|
||||||
System.setProperty(PREFIX + HEADER_TAGS, mapString)
|
System.setProperty(PREFIX + HEADER_TAGS, mapString)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
def tracer = new DDTracer(new Config())
|
def config = new Config()
|
||||||
|
def tracer = new DDTracer(config)
|
||||||
def taggedHeaders = tracer.registry.codecs.values().first().taggedHeaders
|
def taggedHeaders = tracer.registry.codecs.values().first().taggedHeaders
|
||||||
|
|
||||||
then:
|
then:
|
||||||
|
|
Loading…
Reference in New Issue