From 80f7f615e4ab571a73d526c525b0eb5ad7b20225 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Mon, 2 Dec 2019 12:14:44 -0800 Subject: [PATCH] Remove exporter (#25) --- .circleci/config.yml | 47 -- LICENSE-3rdparty.csv | 1 - .../trace/agent/tooling/Constants.java | 3 - .../benchmark-integration/run-perf-test.sh | 29 +- dd-java-agent/benchmark/benchmark.gradle | 2 - .../datadog/trace/agent/DDInfoTest.groovy | 19 - dd-trace-api/dd-trace-api.gradle | 1 - .../main/java/datadog/trace/api/Config.java | 56 +- .../datadog/trace/api/DDTraceApiInfo.java | 32 - .../datadog/trace/api/ConfigTest.groovy | 111 +--- dd-trace-ot/dd-trace-ot.gradle | 11 +- .../datadog/opentracing/ContainerInfo.java | 129 ---- .../main/java/datadog/opentracing/DDSpan.java | 41 +- .../datadog/opentracing/DDSpanContext.java | 3 - .../datadog/opentracing/DDTraceOTInfo.java | 37 -- .../common/util/DaemonThreadFactory.java | 24 - .../trace/common/writer/DDAgentWriter.java | 586 ------------------ .../datadog/trace/common/writer/DDApi.java | 373 ----------- .../trace/common/writer/LoggingWriter.java | 6 +- .../datadog/trace/common/writer/Writer.java | 44 +- .../TunnelingUnixSocket.java | 51 -- .../UnixDomainSocketFactory.java | 58 -- .../opentracing/ContainerInfoTest.groovy | 147 ----- .../DDSpanSerializationTest.groovy | 59 -- .../datadog/opentracing/DDSpanTest.groovy | 2 +- .../groovy/datadog/trace/DDTracerTest.groovy | 63 -- .../trace/api/writer/DDAgentWriterTest.groovy | 575 ----------------- .../datadog/trace/api/writer/DDApiTest.groovy | 243 -------- .../trace/api/writer/SerializationTest.groovy | 61 -- .../groovy/DDApiIntegrationTest.groovy | 170 ----- gradle/dependencies.gradle | 6 - 31 files changed, 20 insertions(+), 2970 deletions(-) delete mode 100644 dd-java-agent/src/test/groovy/datadog/trace/agent/DDInfoTest.groovy delete mode 100644 dd-trace-api/src/main/java/datadog/trace/api/DDTraceApiInfo.java delete mode 100644 dd-trace-ot/src/main/java/datadog/opentracing/ContainerInfo.java delete mode 100644 dd-trace-ot/src/main/java/datadog/opentracing/DDTraceOTInfo.java delete mode 100644 dd-trace-ot/src/main/java/datadog/trace/common/util/DaemonThreadFactory.java delete mode 100644 dd-trace-ot/src/main/java/datadog/trace/common/writer/DDAgentWriter.java delete mode 100644 dd-trace-ot/src/main/java/datadog/trace/common/writer/DDApi.java delete mode 100644 dd-trace-ot/src/main/java/datadog/trace/common/writer/unixdomainsockets/TunnelingUnixSocket.java delete mode 100644 dd-trace-ot/src/main/java/datadog/trace/common/writer/unixdomainsockets/UnixDomainSocketFactory.java delete mode 100644 dd-trace-ot/src/test/groovy/datadog/opentracing/ContainerInfoTest.groovy delete mode 100644 dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanSerializationTest.groovy delete mode 100644 dd-trace-ot/src/test/groovy/datadog/trace/api/writer/DDAgentWriterTest.groovy delete mode 100644 dd-trace-ot/src/test/groovy/datadog/trace/api/writer/DDApiTest.groovy delete mode 100644 dd-trace-ot/src/test/groovy/datadog/trace/api/writer/SerializationTest.groovy delete mode 100644 dd-trace-ot/src/traceAgentTest/groovy/DDApiIntegrationTest.groovy diff --git a/.circleci/config.yml b/.circleci/config.yml index 3942c9d965..ed4096c56c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -142,44 +142,6 @@ jobs: environment: - TEST_TASK: testJava13 - agent_integration_tests: - <<: *defaults - docker: - - image: *default_container - - image: datadog/docker-dd-agent - environment: - - DD_APM_ENABLED=true - - DD_BIND_HOST=0.0.0.0 - - DD_API_KEY=invalid_key_but_this_is_fine - steps: - - checkout - - - attach_workspace: - at: . - - - restore_cache: - <<: *cache_keys - - - run: - name: Run Trace Agent Tests - command: ./gradlew traceAgentTest --build-cache --parallel --stacktrace --no-daemon --max-workers=8 - - - run: - name: Collect Reports - when: on_fail - command: .circleci/collect_reports.sh - - - store_artifacts: - path: ./reports - - - run: - name: Collect Test Results - when: always - command: .circleci/collect_results.sh - - - store_test_results: - path: ./results - check: <<: *defaults @@ -323,13 +285,6 @@ workflows: tags: only: /.*/ - - agent_integration_tests: - requires: - - build - filters: - tags: - only: /.*/ - - check: requires: - build @@ -357,7 +312,6 @@ workflows: - test_zulu11 - test_12 - test_13 - - agent_integration_tests - check filters: branches: @@ -378,7 +332,6 @@ workflows: - test_zulu11 - test_12 - test_13 - - agent_integration_tests - check filters: branches: diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index 664fef01a1..9dc2ec1af5 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -2,7 +2,6 @@ Component,Origin,License,Copyright https://github.com/DataDog/dd-trace-java/blob/dev/dd-trace/src/main/java/com/datadoghq/trace/propagation/Codec.java,Uber,MIT, import,io.opentracing,Apache-2.0,Copyright 2016-2017 The OpenTracing Authors import,org.slf4j,MIT,Copyright (c) 2004-2017 QOS.ch -import,com.fasterxml.jackson,Apache-2.0, import,com.google.auto.service.AutoService,Apache-2.0,"Copyright 2013 Google, Inc." logback.xml,ch.qos.logback,EPL-1.0 OR LGPL-2.1,"Copyright (C) 1999-2015, QOS.ch. All rights reserved." logback.xml,net.logstash.logback,Apache-2.0, diff --git a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/Constants.java b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/Constants.java index 76e5f34273..a26509f3bc 100644 --- a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/Constants.java +++ b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/Constants.java @@ -37,9 +37,6 @@ public final class Constants { "net.bytebuddy", // OT contribs for dd trace resolver "io.opentracing.contrib", - // jackson - "org.msgpack", - "com.fasterxml.jackson", "org.yaml.snakeyaml", // disruptor "com.lmax.disruptor", diff --git a/dd-java-agent/benchmark-integration/run-perf-test.sh b/dd-java-agent/benchmark-integration/run-perf-test.sh index 8b70d7bdb4..e5c55b99f7 100755 --- a/dd-java-agent/benchmark-integration/run-perf-test.sh +++ b/dd-java-agent/benchmark-integration/run-perf-test.sh @@ -7,7 +7,6 @@ server_type=$1 server_package=$2 agent_jars="${@:3}" server_pid="" -agent_pid=$(lsof -i tcp:8126 | awk '$8 == "TCP" { print $2 }') if [[ "$server_package" = "" ]] || [[ "$server_type" != "play-zip" && "$server_type" != "jar" ]]; then echo "usage: ./run-perf-test.sh [play-zip|jar] path-to-server-package path-to-agent1 path-to-agent2..." echo "" @@ -23,14 +22,6 @@ if [[ "$server_package" = "" ]] || [[ "$server_type" != "play-zip" && "$server_t exit 1 fi -if [ "$agent_pid" = "" ]; then - echo "discarding traces" - writer_type="LoggingWriter" -else - echo "sending traces to local trace agent: $agent_pid" - writer_type="DDAgentWriter" -fi - if [ -f perf-test-settings.rc ]; then echo "loading custom settings" cat ./perf-test-settings.rc @@ -51,7 +42,7 @@ function start_server { agent_jar="$1" javaagent_arg="" if [ "$agent_jar" != "" -a -f "$agent_jar" ]; then - javaagent_arg="-javaagent:$agent_jar -Ddatadog.slf4j.simpleLogger.defaultLogLevel=off -Ddd.writer.type=$writer_type -Ddd.service.name=perf-test-app" + javaagent_arg="-javaagent:$agent_jar -Ddatadog.slf4j.simpleLogger.defaultLogLevel=off -Ddd.service.name=perf-test-app" fi if [ "$server_type" = "jar" ]; then @@ -150,13 +141,6 @@ for agent_jar in $agent_jars; do fi - if [ "$agent_pid" = "" ]; then - agent_start_cpu=0 - agent_start_rss=0 - else - agent_start_cpu=$(ps -o 'pid,time' | awk "\$1 == $agent_pid { print \$2 }" | awk -F'[:\.]' '{ print ($1 * 3600) + ($2 * 60) + $3 }') - agent_start_rss=$(ps -o 'pid,rss' | awk "\$1 == $agent_pid { print \$2 }") - fi server_start_cpu=$(ps -o 'pid,time' | awk "\$1 == $server_pid { print \$2 }" | awk -F'[:\.]' '{ print ($1 * 3600) + ($2 * 60) + $3 }') server_start_rss=$(ps -o 'pid,rss' | awk "\$1 == $server_pid { print \$2 }") @@ -177,17 +161,8 @@ for agent_jar in $agent_jars; do rm $test_output_file done - if [ "$agent_pid" = "" ]; then - agent_stop_cpu=0 - agent_stop_rss=0 - else - agent_stop_cpu=$(ps -o 'pid,time' | awk "\$1 == $agent_pid { print \$2 }" | awk -F'[:\.]' '{ print ($1 * 3600) + ($2 * 60) + $3 }') - agent_stop_rss=$(ps -o 'pid,rss' | awk "\$1 == $agent_pid { print \$2 }") - fi server_stop_cpu=$(ps -o 'pid,time' | awk "\$1 == $server_pid { print \$2 }" | awk -F'[:\.]' '{ print ($1 * 3600) + ($2 * 60) + $3 }') - let agent_cpu=$agent_stop_cpu-$agent_start_cpu - let agent_rss=$agent_stop_rss-$agent_start_rss let server_cpu=$server_stop_cpu-$server_start_cpu server_load_increase_rss=$(echo "scale=2; ( $server_total_rss / $server_total_rss_count ) - $server_start_rss" | bc) @@ -197,7 +172,7 @@ for agent_jar in $agent_jars; do server_max_rss=$(awk '/.* maximum resident set size/ { print $1 }' $server_output) rm $server_output - echo "$result_row,$agent_cpu,$server_cpu,$agent_rss,$server_max_rss,$server_start_rss,$server_load_increase_rss" >> $test_csv_file + echo "$result_row,$server_cpu,$server_max_rss,$server_start_rss,$server_load_increase_rss" >> $test_csv_file echo "----/Testing agent $agent_jar----" echo "" done diff --git a/dd-java-agent/benchmark/benchmark.gradle b/dd-java-agent/benchmark/benchmark.gradle index 8d0205b087..eb90b50542 100644 --- a/dd-java-agent/benchmark/benchmark.gradle +++ b/dd-java-agent/benchmark/benchmark.gradle @@ -15,8 +15,6 @@ dependencies { jmh group: 'org.mongodb', name: 'mongodb-driver-async', version: '3.4.2' jmh(group: 'com.amazonaws', name: 'aws-java-sdk', version: '1.11.119') { exclude(module: 'httpclient') - exclude(module: 'jackson-databind') - exclude(module: 'jackson-dataformat-cbor') } jmh group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0' jmh group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.3' diff --git a/dd-java-agent/src/test/groovy/datadog/trace/agent/DDInfoTest.groovy b/dd-java-agent/src/test/groovy/datadog/trace/agent/DDInfoTest.groovy deleted file mode 100644 index 26e465932b..0000000000 --- a/dd-java-agent/src/test/groovy/datadog/trace/agent/DDInfoTest.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package datadog.trace.agent - -import datadog.opentracing.DDTraceOTInfo -import datadog.trace.api.DDTraceApiInfo -import spock.lang.Specification - -class DDInfoTest extends Specification { - def "info accessible from api"() { - expect: - DDTraceApiInfo.VERSION == DDTraceOTInfo.VERSION - - DDTraceApiInfo.VERSION != null - DDTraceApiInfo.VERSION != "" - DDTraceApiInfo.VERSION != "unknown" - DDTraceOTInfo.VERSION != null - DDTraceOTInfo.VERSION != "" - DDTraceOTInfo.VERSION != "unknown" - } -} diff --git a/dd-trace-api/dd-trace-api.gradle b/dd-trace-api/dd-trace-api.gradle index f3ac89b575..9da3bc8846 100644 --- a/dd-trace-api/dd-trace-api.gradle +++ b/dd-trace-api/dd-trace-api.gradle @@ -6,7 +6,6 @@ minimumBranchCoverage = 0.8 // These are tested outside of this module since this module mainly just defines 'API' excludedClassesCoverage += [ 'datadog.trace.api.DDSpanTypes', - 'datadog.trace.api.DDTraceApiInfo', 'datadog.trace.api.GlobalTracer*', 'datadog.trace.api.CorrelationIdentifier', 'datadog.trace.api.DDTags', diff --git a/dd-trace-api/src/main/java/datadog/trace/api/Config.java b/dd-trace-api/src/main/java/datadog/trace/api/Config.java index 8b052b179e..227562256f 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/Config.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/Config.java @@ -46,10 +46,6 @@ public class Config { public static final String TRACE_ENABLED = "trace.enabled"; public static final String INTEGRATIONS_ENABLED = "integrations.enabled"; public static final String WRITER_TYPE = "writer.type"; - public static final String AGENT_HOST = "agent.host"; - public static final String TRACE_AGENT_PORT = "trace.agent.port"; - public static final String AGENT_PORT_LEGACY = "agent.port"; - public static final String AGENT_UNIX_DOMAIN_SOCKET = "trace.agent.unix.domain.socket"; public static final String TRACE_RESOLVER_ENABLED = "trace.resolver.enabled"; public static final String GLOBAL_TAGS = "trace.global.tags"; public static final String SPAN_TAGS = "trace.span.tags"; @@ -70,10 +66,6 @@ public class Config { public static final String RUNTIME_CONTEXT_FIELD_INJECTION = "trace.runtime.context.field.injection"; - public static final String HEALTH_METRICS_ENABLED = "trace.health.metrics.enabled"; - public static final String HEALTH_METRICS_STATSD_HOST = "trace.health.metrics.statsd.host"; - public static final String HEALTH_METRICS_STATSD_PORT = "trace.health.metrics.statsd.port"; - public static final String LOGS_INJECTION_ENABLED = "logs.injection"; public static final String SERVICE_TAG = "service"; @@ -86,13 +78,8 @@ public class Config { private static final boolean DEFAULT_TRACE_ENABLED = true; public static final boolean DEFAULT_INTEGRATIONS_ENABLED = true; - public static final String DD_AGENT_WRITER_TYPE = "DDAgentWriter"; public static final String LOGGING_WRITER_TYPE = "LoggingWriter"; - private static final String DEFAULT_AGENT_WRITER_TYPE = DD_AGENT_WRITER_TYPE; - - public static final String DEFAULT_AGENT_HOST = "localhost"; - public static final int DEFAULT_TRACE_AGENT_PORT = 8126; - public static final String DEFAULT_AGENT_UNIX_DOMAIN_SOCKET = null; + private static final String DEFAULT_WRITER_TYPE = LOGGING_WRITER_TYPE; private static final boolean DEFAULT_RUNTIME_CONTEXT_FIELD_INJECTION = true; @@ -107,9 +94,6 @@ public class Config { private static final boolean DEFAULT_DB_CLIENT_HOST_SPLIT_BY_INSTANCE = false; private static final int DEFAULT_PARTIAL_FLUSH_MIN_SPANS = 1000; - public static final boolean DEFAULT_METRICS_ENABLED = false; - // No default constants for metrics statsd support -- falls back to jmx fetch values - public static final boolean DEFAULT_LOGS_INJECTION_ENABLED = false; private static final String SPLIT_BY_SPACE_OR_COMMA_REGEX = "[,\\s]+"; @@ -133,9 +117,6 @@ public class Config { @Getter private final boolean traceEnabled; @Getter private final boolean integrationsEnabled; @Getter private final String writerType; - @Getter private final String agentHost; - @Getter private final int agentPort; - @Getter private final String agentUnixDomainSocket; @Getter private final boolean traceResolverEnabled; private final Map globalTags; private final Map spanTags; @@ -150,10 +131,6 @@ public class Config { @Getter private final Integer partialFlushMinSpans; @Getter private final boolean runtimeContextFieldInjection; - @Getter private final boolean healthMetricsEnabled; - @Getter private final String healthMetricsStatsdHost; - @Getter private final Integer healthMetricsStatsdPort; - @Getter private final boolean logsInjectionEnabled; @Getter private final boolean reportHostName; @@ -180,14 +157,7 @@ public class Config { traceEnabled = getBooleanSettingFromEnvironment(TRACE_ENABLED, DEFAULT_TRACE_ENABLED); integrationsEnabled = getBooleanSettingFromEnvironment(INTEGRATIONS_ENABLED, DEFAULT_INTEGRATIONS_ENABLED); - writerType = getSettingFromEnvironment(WRITER_TYPE, DEFAULT_AGENT_WRITER_TYPE); - agentHost = getSettingFromEnvironment(AGENT_HOST, DEFAULT_AGENT_HOST); - agentPort = - getIntegerSettingFromEnvironment( - TRACE_AGENT_PORT, - getIntegerSettingFromEnvironment(AGENT_PORT_LEGACY, DEFAULT_TRACE_AGENT_PORT)); - agentUnixDomainSocket = - getSettingFromEnvironment(AGENT_UNIX_DOMAIN_SOCKET, DEFAULT_AGENT_UNIX_DOMAIN_SOCKET); + writerType = getSettingFromEnvironment(WRITER_TYPE, DEFAULT_WRITER_TYPE); traceResolverEnabled = getBooleanSettingFromEnvironment(TRACE_RESOLVER_ENABLED, DEFAULT_TRACE_RESOLVER_ENABLED); @@ -228,12 +198,6 @@ public class Config { getBooleanSettingFromEnvironment( RUNTIME_CONTEXT_FIELD_INJECTION, DEFAULT_RUNTIME_CONTEXT_FIELD_INJECTION); - // Writer.Builder createMonitor will use the values of the JMX fetch & agent to fill-in defaults - healthMetricsEnabled = - getBooleanSettingFromEnvironment(HEALTH_METRICS_ENABLED, DEFAULT_METRICS_ENABLED); - healthMetricsStatsdHost = getSettingFromEnvironment(HEALTH_METRICS_STATSD_HOST, null); - healthMetricsStatsdPort = getIntegerSettingFromEnvironment(HEALTH_METRICS_STATSD_PORT, null); - logsInjectionEnabled = getBooleanSettingFromEnvironment(LOGS_INJECTION_ENABLED, DEFAULT_LOGS_INJECTION_ENABLED); @@ -262,14 +226,6 @@ public class Config { integrationsEnabled = getPropertyBooleanValue(properties, INTEGRATIONS_ENABLED, parent.integrationsEnabled); writerType = properties.getProperty(WRITER_TYPE, parent.writerType); - agentHost = properties.getProperty(AGENT_HOST, parent.agentHost); - agentPort = - getPropertyIntegerValue( - properties, - TRACE_AGENT_PORT, - getPropertyIntegerValue(properties, AGENT_PORT_LEGACY, parent.agentPort)); - agentUnixDomainSocket = - properties.getProperty(AGENT_UNIX_DOMAIN_SOCKET, parent.agentUnixDomainSocket); traceResolverEnabled = getPropertyBooleanValue(properties, TRACE_RESOLVER_ENABLED, parent.traceResolverEnabled); @@ -310,14 +266,6 @@ public class Config { getPropertyBooleanValue( properties, RUNTIME_CONTEXT_FIELD_INJECTION, parent.runtimeContextFieldInjection); - healthMetricsEnabled = - getPropertyBooleanValue(properties, HEALTH_METRICS_ENABLED, DEFAULT_METRICS_ENABLED); - healthMetricsStatsdHost = - properties.getProperty(HEALTH_METRICS_STATSD_HOST, parent.healthMetricsStatsdHost); - healthMetricsStatsdPort = - getPropertyIntegerValue( - properties, HEALTH_METRICS_STATSD_PORT, parent.healthMetricsStatsdPort); - logsInjectionEnabled = getBooleanSettingFromEnvironment(LOGS_INJECTION_ENABLED, DEFAULT_LOGS_INJECTION_ENABLED); diff --git a/dd-trace-api/src/main/java/datadog/trace/api/DDTraceApiInfo.java b/dd-trace-api/src/main/java/datadog/trace/api/DDTraceApiInfo.java deleted file mode 100644 index a090e6fd56..0000000000 --- a/dd-trace-api/src/main/java/datadog/trace/api/DDTraceApiInfo.java +++ /dev/null @@ -1,32 +0,0 @@ -package datadog.trace.api; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class DDTraceApiInfo { - public static final String VERSION; - - static { - String v; - try (final BufferedReader br = - new BufferedReader( - new InputStreamReader( - DDTraceApiInfo.class.getResourceAsStream("/dd-trace-api.version"), "UTF-8"))) { - final StringBuilder sb = new StringBuilder(); - - for (int c = br.read(); c != -1; c = br.read()) sb.append((char) c); - - v = sb.toString().trim(); - } catch (final Exception e) { - v = "unknown"; - } - VERSION = v; - log.info("dd-trace-api - version: {}", v); - } - - public static void main(final String... args) { - System.out.println(VERSION); - } -} diff --git a/dd-trace-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy b/dd-trace-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy index b11d882220..2e49bdfd8d 100644 --- a/dd-trace-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy +++ b/dd-trace-api/src/test/groovy/datadog/trace/api/ConfigTest.groovy @@ -5,15 +5,9 @@ import org.junit.Rule import org.junit.contrib.java.lang.system.EnvironmentVariables import org.junit.contrib.java.lang.system.RestoreSystemProperties -import static datadog.trace.api.Config.AGENT_HOST -import static datadog.trace.api.Config.AGENT_PORT_LEGACY -import static datadog.trace.api.Config.AGENT_UNIX_DOMAIN_SOCKET import static datadog.trace.api.Config.CONFIGURATION_FILE import static datadog.trace.api.Config.DB_CLIENT_HOST_SPLIT_BY_INSTANCE import static datadog.trace.api.Config.GLOBAL_TAGS -import static datadog.trace.api.Config.HEALTH_METRICS_ENABLED -import static datadog.trace.api.Config.HEALTH_METRICS_STATSD_HOST -import static datadog.trace.api.Config.HEALTH_METRICS_STATSD_PORT import static datadog.trace.api.Config.HTTP_CLIENT_ERROR_STATUSES import static datadog.trace.api.Config.HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN import static datadog.trace.api.Config.HTTP_SERVER_ERROR_STATUSES @@ -25,7 +19,6 @@ import static datadog.trace.api.Config.RUNTIME_ID_TAG import static datadog.trace.api.Config.SERVICE_NAME import static datadog.trace.api.Config.SERVICE_TAG import static datadog.trace.api.Config.SPAN_TAGS -import static datadog.trace.api.Config.TRACE_AGENT_PORT import static datadog.trace.api.Config.TRACE_ENABLED import static datadog.trace.api.Config.TRACE_REPORT_HOSTNAME import static datadog.trace.api.Config.TRACE_RESOLVER_ENABLED @@ -41,8 +34,6 @@ class ConfigTest extends DDSpecification { private static final DD_TRACE_ENABLED_ENV = "DD_TRACE_ENABLED" private static final DD_WRITER_TYPE_ENV = "DD_WRITER_TYPE" private static final DD_SPAN_TAGS_ENV = "DD_SPAN_TAGS" - private static final DD_TRACE_AGENT_PORT_ENV = "DD_TRACE_AGENT_PORT" - private static final DD_AGENT_PORT_LEGACY_ENV = "DD_AGENT_PORT" private static final DD_TRACE_REPORT_HOSTNAME = "DD_TRACE_REPORT_HOSTNAME" def "verify defaults"() { @@ -52,10 +43,7 @@ class ConfigTest extends DDSpecification { then: config.serviceName == "unnamed-java-app" config.traceEnabled == true - config.writerType == "DDAgentWriter" - config.agentHost == "localhost" - config.agentPort == 8126 - config.agentUnixDomainSocket == null + config.writerType == "LoggingWriter" config.traceResolverEnabled == true config.mergedSpanTags == [:] config.mergedJmxTags == [(RUNTIME_ID_TAG): config.getRuntimeId(), (SERVICE_TAG): config.serviceName] @@ -66,9 +54,6 @@ class ConfigTest extends DDSpecification { config.partialFlushMinSpans == 1000 config.reportHostName == false config.runtimeContextFieldInjection == true - config.healthMetricsEnabled == false - config.healthMetricsStatsdHost == null - config.healthMetricsStatsdPort == null config.toString().contains("unnamed-java-app") where: @@ -85,10 +70,6 @@ class ConfigTest extends DDSpecification { prop.setProperty(SERVICE_NAME, "something else") prop.setProperty(TRACE_ENABLED, "false") prop.setProperty(WRITER_TYPE, "LoggingWriter") - prop.setProperty(AGENT_HOST, "somehost") - prop.setProperty(TRACE_AGENT_PORT, "123") - prop.setProperty(AGENT_UNIX_DOMAIN_SOCKET, "somepath") - prop.setProperty(AGENT_PORT_LEGACY, "456") prop.setProperty(TRACE_RESOLVER_ENABLED, "false") prop.setProperty(GLOBAL_TAGS, "b:2") prop.setProperty(SPAN_TAGS, "c:3") @@ -100,9 +81,6 @@ class ConfigTest extends DDSpecification { prop.setProperty(PARTIAL_FLUSH_MIN_SPANS, "15") prop.setProperty(TRACE_REPORT_HOSTNAME, "true") prop.setProperty(RUNTIME_CONTEXT_FIELD_INJECTION, "false") - prop.setProperty(HEALTH_METRICS_ENABLED, "true") - prop.setProperty(HEALTH_METRICS_STATSD_HOST, "metrics statsd host") - prop.setProperty(HEALTH_METRICS_STATSD_PORT, "654") when: Config config = Config.get(prop) @@ -111,9 +89,6 @@ class ConfigTest extends DDSpecification { config.serviceName == "something else" config.traceEnabled == false config.writerType == "LoggingWriter" - config.agentHost == "somehost" - config.agentPort == 123 - config.agentUnixDomainSocket == "somepath" config.traceResolverEnabled == false config.mergedSpanTags == [b: "2", c: "3"] config.mergedJmxTags == [b: "2", d: "4", (RUNTIME_ID_TAG): config.getRuntimeId(), (SERVICE_TAG): config.serviceName] @@ -124,9 +99,6 @@ class ConfigTest extends DDSpecification { config.partialFlushMinSpans == 15 config.reportHostName == true config.runtimeContextFieldInjection == false - config.healthMetricsEnabled == true - config.healthMetricsStatsdHost == "metrics statsd host" - config.healthMetricsStatsdPort == 654 } def "specify overrides via system properties"() { @@ -134,10 +106,6 @@ class ConfigTest extends DDSpecification { System.setProperty(PREFIX + SERVICE_NAME, "something else") System.setProperty(PREFIX + TRACE_ENABLED, "false") System.setProperty(PREFIX + WRITER_TYPE, "LoggingWriter") - System.setProperty(PREFIX + AGENT_HOST, "somehost") - System.setProperty(PREFIX + TRACE_AGENT_PORT, "123") - System.setProperty(PREFIX + AGENT_UNIX_DOMAIN_SOCKET, "somepath") - System.setProperty(PREFIX + AGENT_PORT_LEGACY, "456") System.setProperty(PREFIX + TRACE_RESOLVER_ENABLED, "false") System.setProperty(PREFIX + GLOBAL_TAGS, "b:2") System.setProperty(PREFIX + SPAN_TAGS, "c:3") @@ -149,9 +117,6 @@ class ConfigTest extends DDSpecification { System.setProperty(PREFIX + PARTIAL_FLUSH_MIN_SPANS, "25") System.setProperty(PREFIX + TRACE_REPORT_HOSTNAME, "true") System.setProperty(PREFIX + RUNTIME_CONTEXT_FIELD_INJECTION, "false") - System.setProperty(PREFIX + HEALTH_METRICS_ENABLED, "true") - System.setProperty(PREFIX + HEALTH_METRICS_STATSD_HOST, "metrics statsd host") - System.setProperty(PREFIX + HEALTH_METRICS_STATSD_PORT, "654") when: Config config = new Config() @@ -160,9 +125,6 @@ class ConfigTest extends DDSpecification { config.serviceName == "something else" config.traceEnabled == false config.writerType == "LoggingWriter" - config.agentHost == "somehost" - config.agentPort == 123 - config.agentUnixDomainSocket == "somepath" config.traceResolverEnabled == false config.mergedSpanTags == [b: "2", c: "3"] config.mergedJmxTags == [b: "2", d: "4", (RUNTIME_ID_TAG): config.getRuntimeId(), (SERVICE_TAG): config.serviceName] @@ -173,9 +135,6 @@ class ConfigTest extends DDSpecification { config.partialFlushMinSpans == 25 config.reportHostName == true config.runtimeContextFieldInjection == false - config.healthMetricsEnabled == true - config.healthMetricsStatsdHost == "metrics statsd host" - config.healthMetricsStatsdPort == 654 } def "specify overrides via env vars"() { @@ -199,21 +158,16 @@ class ConfigTest extends DDSpecification { setup: environmentVariables.set(DD_SERVICE_NAME_ENV, "still something else") environmentVariables.set(DD_WRITER_TYPE_ENV, "LoggingWriter") - environmentVariables.set(DD_TRACE_AGENT_PORT_ENV, "777") System.setProperty(PREFIX + SERVICE_NAME, "what we actually want") - System.setProperty(PREFIX + WRITER_TYPE, "DDAgentWriter") - System.setProperty(PREFIX + AGENT_HOST, "somewhere") - System.setProperty(PREFIX + TRACE_AGENT_PORT, "123") + System.setProperty(PREFIX + WRITER_TYPE, "LoggingWriter") when: def config = new Config() then: config.serviceName == "what we actually want" - config.writerType == "DDAgentWriter" - config.agentHost == "somewhere" - config.agentPort == 123 + config.writerType == "LoggingWriter" } def "default when configured incorrectly"() { @@ -221,9 +175,6 @@ class ConfigTest extends DDSpecification { System.setProperty(PREFIX + SERVICE_NAME, " ") System.setProperty(PREFIX + TRACE_ENABLED, " ") System.setProperty(PREFIX + WRITER_TYPE, " ") - System.setProperty(PREFIX + AGENT_HOST, " ") - System.setProperty(PREFIX + TRACE_AGENT_PORT, " ") - System.setProperty(PREFIX + AGENT_PORT_LEGACY, "invalid") System.setProperty(PREFIX + TRACE_RESOLVER_ENABLED, " ") System.setProperty(PREFIX + SPAN_TAGS, "invalid") System.setProperty(PREFIX + HTTP_SERVER_ERROR_STATUSES, "1111") @@ -238,8 +189,6 @@ class ConfigTest extends DDSpecification { config.serviceName == " " config.traceEnabled == true config.writerType == " " - config.agentHost == " " - config.agentPort == 8126 config.traceResolverEnabled == true config.mergedSpanTags == [:] config.httpServerErrorStatuses == (500..599).toSet() @@ -248,57 +197,12 @@ class ConfigTest extends DDSpecification { config.dbClientSplitByInstance == false } - def "sys props and env vars overrides for trace_agent_port and agent_port_legacy as expected"() { - setup: - if (overridePortEnvVar) { - environmentVariables.set(DD_TRACE_AGENT_PORT_ENV, "777") - } - if (overrideLegacyPortEnvVar) { - environmentVariables.set(DD_AGENT_PORT_LEGACY_ENV, "888") - } - - if (overridePort) { - System.setProperty(PREFIX + TRACE_AGENT_PORT, "123") - } - if (overrideLegacyPort) { - System.setProperty(PREFIX + AGENT_PORT_LEGACY, "456") - } - - when: - def config = new Config() - - then: - config.agentPort == expectedPort - - where: - overridePort | overrideLegacyPort | overridePortEnvVar | overrideLegacyPortEnvVar | expectedPort - true | true | false | false | 123 - true | false | false | false | 123 - false | true | false | false | 456 - false | false | false | false | 8126 - true | true | true | false | 123 - true | false | true | false | 123 - false | true | true | false | 777 // env var gets picked up instead. - false | false | true | false | 777 // env var gets picked up instead. - true | true | false | true | 123 - true | false | false | true | 123 - false | true | false | true | 456 - false | false | false | true | 888 // legacy env var gets picked up instead. - true | true | true | true | 123 - true | false | true | true | 123 - false | true | true | true | 777 // env var gets picked up instead. - false | false | true | true | 777 // env var gets picked up instead. - } - def "sys props override properties"() { setup: Properties properties = new Properties() properties.setProperty(SERVICE_NAME, "something else") properties.setProperty(TRACE_ENABLED, "false") properties.setProperty(WRITER_TYPE, "LoggingWriter") - properties.setProperty(AGENT_HOST, "somehost") - properties.setProperty(TRACE_AGENT_PORT, "123") - properties.setProperty(AGENT_UNIX_DOMAIN_SOCKET, "somepath") properties.setProperty(TRACE_RESOLVER_ENABLED, "false") properties.setProperty(GLOBAL_TAGS, "b:2") properties.setProperty(SPAN_TAGS, "c:3") @@ -316,9 +220,6 @@ class ConfigTest extends DDSpecification { config.serviceName == "something else" config.traceEnabled == false config.writerType == "LoggingWriter" - config.agentHost == "somehost" - config.agentPort == 123 - config.agentUnixDomainSocket == "somepath" config.traceResolverEnabled == false config.mergedSpanTags == [b: "2", c: "3"] config.mergedJmxTags == [b: "2", d: "4", (RUNTIME_ID_TAG): config.getRuntimeId(), (SERVICE_TAG): config.serviceName] @@ -335,7 +236,7 @@ class ConfigTest extends DDSpecification { then: config.serviceName == "unnamed-java-app" - config.writerType == "DDAgentWriter" + config.writerType == "LoggingWriter" } def "override empty properties"() { @@ -347,7 +248,7 @@ class ConfigTest extends DDSpecification { then: config.serviceName == "unnamed-java-app" - config.writerType == "DDAgentWriter" + config.writerType == "LoggingWriter" } def "override non empty properties"() { @@ -360,7 +261,7 @@ class ConfigTest extends DDSpecification { then: config.serviceName == "unnamed-java-app" - config.writerType == "DDAgentWriter" + config.writerType == "LoggingWriter" } def "verify integration config"() { diff --git a/dd-trace-ot/dd-trace-ot.gradle b/dd-trace-ot/dd-trace-ot.gradle index ec315a2963..47388d5266 100644 --- a/dd-trace-ot/dd-trace-ot.gradle +++ b/dd-trace-ot/dd-trace-ot.gradle @@ -11,10 +11,7 @@ minimumBranchCoverage = 0.5 minimumInstructionCoverage = 0.5 excludedClassesCoverage += [ 'datadog.trace.common.writer.ListWriter', - 'datadog.trace.common.writer.LoggingWriter', - // This code is copied from okHttp samples and we have integration tests to verify that it works. - 'datadog.trace.common.writer.unixdomainsockets.TunnelingUnixSocket', - 'datadog.trace.common.writer.unixdomainsockets.UnixDomainSocketFactory' + 'datadog.trace.common.writer.LoggingWriter' ] apply plugin: 'org.unbroken-dome.test-sets' @@ -22,7 +19,6 @@ apply plugin: 'org.unbroken-dome.test-sets' testSets { ot31CompatabilityTest ot33CompatabilityTest - traceAgentTest } dependencies { @@ -33,9 +29,6 @@ dependencies { compile deps.opentracing compile group: 'io.opentracing.contrib', name: 'opentracing-tracerresolver', version: '0.1.0' - compile group: 'com.datadoghq', name: 'java-dogstatsd-client', version: '2.1.1' - - compile deps.jackson compile deps.slf4j compile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.11.0' // Last version to support Java7 compile group: 'com.github.jnr', name: 'jnr-unixsocket', version: '0.23' @@ -49,8 +42,6 @@ dependencies { testCompile project(':utils:gc-utils') testCompile group: 'com.github.stefanbirkner', name: 'system-rules', version: '1.17.1' - traceAgentTestCompile deps.testcontainers - ot31CompatabilityTestCompile group: 'io.opentracing', name: 'opentracing-api', version: '0.31.0' ot31CompatabilityTestCompile group: 'io.opentracing', name: 'opentracing-util', version: '0.31.0' ot31CompatabilityTestCompile group: 'io.opentracing', name: 'opentracing-noop', version: '0.31.0' diff --git a/dd-trace-ot/src/main/java/datadog/opentracing/ContainerInfo.java b/dd-trace-ot/src/main/java/datadog/opentracing/ContainerInfo.java deleted file mode 100644 index e3d7ef892d..0000000000 --- a/dd-trace-ot/src/main/java/datadog/opentracing/ContainerInfo.java +++ /dev/null @@ -1,129 +0,0 @@ -package datadog.opentracing; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; - -/** - * Parses container information from /proc/self/cgroup. Implementation based largely on - * Qard/container-info - */ -@Getter -@Setter -@Slf4j -public class ContainerInfo { - private static final Path CGROUP_DEFAULT_PROCFILE = Paths.get("/proc/self/cgroup"); - private static final String UUID_REGEX = - "[0-9a-f]{8}[-_][0-9a-f]{4}[-_][0-9a-f]{4}[-_][0-9a-f]{4}[-_][0-9a-f]{12}"; - private static final String CONTAINER_REGEX = "[0-9a-f]{64}"; - private static final Pattern LINE_PATTERN = Pattern.compile("(\\d+):([^:]*):(.+)$"); - private static final Pattern POD_PATTERN = - Pattern.compile("(?:.+)?pod(" + UUID_REGEX + ")(?:.slice)?$"); - private static final Pattern CONTAINER_PATTERN = - Pattern.compile("(?:.+)?(" + UUID_REGEX + "|" + CONTAINER_REGEX + ")(?:.scope)?$"); - - private static final ContainerInfo INSTANCE; - - public String containerId; - public String podId; - public List cGroups = new ArrayList<>(); - - static { - ContainerInfo containerInfo = new ContainerInfo(); - if (ContainerInfo.isRunningInContainer()) { - try { - containerInfo = ContainerInfo.fromDefaultProcFile(); - } catch (final IOException | ParseException e) { - log.error("Unable to parse proc file"); - } - } - - INSTANCE = containerInfo; - } - - @Getter - @Setter - public static class CGroupInfo { - public int id; - public String path; - public List controllers; - public String containerId; - public String podId; - } - - public static ContainerInfo get() { - return INSTANCE; - } - - public static boolean isRunningInContainer() { - return Files.isReadable(CGROUP_DEFAULT_PROCFILE) - && CGROUP_DEFAULT_PROCFILE.toFile().length() > 0; - } - - public static ContainerInfo fromDefaultProcFile() throws IOException, ParseException { - final String content = new String(Files.readAllBytes(CGROUP_DEFAULT_PROCFILE)); - return parse(content); - } - - public static ContainerInfo parse(final String cgroupsContent) throws ParseException { - final ContainerInfo containerInfo = new ContainerInfo(); - - final String[] lines = cgroupsContent.split("\n"); - for (final String line : lines) { - final CGroupInfo cGroupInfo = parseLine(line); - - containerInfo.getCGroups().add(cGroupInfo); - - if (cGroupInfo.getPodId() != null) { - containerInfo.setPodId(cGroupInfo.getPodId()); - } - - if (cGroupInfo.getContainerId() != null) { - containerInfo.setContainerId(cGroupInfo.getContainerId()); - } - } - - return containerInfo; - } - - static CGroupInfo parseLine(final String line) throws ParseException { - final Matcher matcher = LINE_PATTERN.matcher(line); - - if (!matcher.matches()) { - throw new ParseException("Unable to match cgroup", 0); - } - - final CGroupInfo cGroupInfo = new CGroupInfo(); - cGroupInfo.setId(Integer.parseInt(matcher.group(1))); - cGroupInfo.setControllers(Arrays.asList(matcher.group(2).split(","))); - - final String path = matcher.group(3); - final String[] pathParts = path.split("/"); - - cGroupInfo.setPath(path); - - if (pathParts.length >= 1) { - final Matcher containerIdMatcher = CONTAINER_PATTERN.matcher(pathParts[pathParts.length - 1]); - final String containerId = containerIdMatcher.matches() ? containerIdMatcher.group(1) : null; - cGroupInfo.setContainerId(containerId); - } - - if (pathParts.length >= 2) { - final Matcher podIdMatcher = POD_PATTERN.matcher(pathParts[pathParts.length - 2]); - final String podId = podIdMatcher.matches() ? podIdMatcher.group(1) : null; - cGroupInfo.setPodId(podId); - } - - return cGroupInfo; - } -} diff --git a/dd-trace-ot/src/main/java/datadog/opentracing/DDSpan.java b/dd-trace-ot/src/main/java/datadog/opentracing/DDSpan.java index 0e2df4df91..cc327a4220 100644 --- a/dd-trace-ot/src/main/java/datadog/opentracing/DDSpan.java +++ b/dd-trace-ot/src/main/java/datadog/opentracing/DDSpan.java @@ -2,8 +2,6 @@ package datadog.opentracing; import static io.opentracing.log.Fields.ERROR_OBJECT; -import com.fasterxml.jackson.annotation.JsonGetter; -import com.fasterxml.jackson.annotation.JsonIgnore; import datadog.trace.api.DDTags; import datadog.trace.common.util.Clock; import io.opentracing.Span; @@ -12,7 +10,6 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.lang.ref.WeakReference; import java.math.BigInteger; -import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; @@ -74,7 +71,6 @@ public class DDSpan implements Span { context.getTrace().registerSpan(this); } - @JsonIgnore public boolean isFinished() { return durationNano.get() != 0; } @@ -116,18 +112,15 @@ public class DDSpan implements Span { * * @return true if root, false otherwise */ - @JsonIgnore public final boolean isRootSpan() { return BigInteger.ZERO.equals(context.getParentId()); } @Deprecated - @JsonIgnore public DDSpan getRootSpan() { return getLocalRootSpan(); } - @JsonIgnore public DDSpan getLocalRootSpan() { return context().getTrace().getRootSpan(); } @@ -273,93 +266,61 @@ public class DDSpan implements Span { return this; } - // Getters and JSON serialisation instructions - - /** - * Stringified tags - * - * @return stringified tags - */ - @JsonGetter - public Map getMeta() { - final Map meta = new HashMap<>(); - for (final Map.Entry entry : getTags().entrySet()) { - meta.put(entry.getKey(), String.valueOf(entry.getValue())); - } - return meta; - } + // Getters /** * Span metrics. * * @return metrics for this span */ - @JsonGetter public Map getMetrics() { return context.getMetrics(); } - @JsonGetter("start") public long getStartTime() { return startTimeNano > 0 ? startTimeNano : TimeUnit.MICROSECONDS.toNanos(startTimeMicro); } - @JsonGetter("duration") public long getDurationNano() { return durationNano.get(); } - @JsonGetter("service") public String getServiceName() { return context.getServiceName(); } - @JsonGetter("trace_id") public BigInteger getTraceId() { return context.getTraceId(); } - @JsonGetter("span_id") public BigInteger getSpanId() { return context.getSpanId(); } - @JsonGetter("parent_id") public BigInteger getParentId() { return context.getParentId(); } - @JsonGetter("resource") public String getResourceName() { return context.getResourceName(); } - @JsonGetter("name") public String getOperationName() { return context.getOperationName(); } - @JsonIgnore public String getSpanType() { return context.getSpanType(); } - @JsonIgnore public Map getTags() { return context().getTags(); } - @JsonGetter - public String getType() { - return context.getSpanType(); - } - - @JsonIgnore public Boolean isError() { return context.getErrorFlag(); } - @JsonGetter public int getError() { return context.getErrorFlag() ? 1 : 0; } diff --git a/dd-trace-ot/src/main/java/datadog/opentracing/DDSpanContext.java b/dd-trace-ot/src/main/java/datadog/opentracing/DDSpanContext.java index dae3e57fa7..af1529696d 100644 --- a/dd-trace-ot/src/main/java/datadog/opentracing/DDSpanContext.java +++ b/dd-trace-ot/src/main/java/datadog/opentracing/DDSpanContext.java @@ -1,6 +1,5 @@ package datadog.opentracing; -import com.fasterxml.jackson.annotation.JsonIgnore; import datadog.opentracing.decorators.AbstractDecorator; import datadog.trace.api.DDTags; import java.math.BigInteger; @@ -165,12 +164,10 @@ public class DDSpanContext implements io.opentracing.SpanContext { return Collections.emptyList(); } - @JsonIgnore public PendingTrace getTrace() { return trace; } - @JsonIgnore public DDTracer getTracer() { return tracer; } diff --git a/dd-trace-ot/src/main/java/datadog/opentracing/DDTraceOTInfo.java b/dd-trace-ot/src/main/java/datadog/opentracing/DDTraceOTInfo.java deleted file mode 100644 index 464e7d4a56..0000000000 --- a/dd-trace-ot/src/main/java/datadog/opentracing/DDTraceOTInfo.java +++ /dev/null @@ -1,37 +0,0 @@ -package datadog.opentracing; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class DDTraceOTInfo { - - public static final String JAVA_VERSION = System.getProperty("java.version", "unknown"); - public static final String JAVA_VM_NAME = System.getProperty("java.vm.name", "unknown"); - public static final String JAVA_VM_VENDOR = System.getProperty("java.vm.vendor", "unknown"); - - public static final String VERSION; - - static { - String v; - try (final BufferedReader br = - new BufferedReader( - new InputStreamReader( - DDTraceOTInfo.class.getResourceAsStream("/dd-trace-ot.version"), "UTF-8"))) { - final StringBuilder sb = new StringBuilder(); - - for (int c = br.read(); c != -1; c = br.read()) sb.append((char) c); - - v = sb.toString().trim(); - } catch (final Exception e) { - v = "unknown"; - } - VERSION = v; - log.info("dd-trace - version: {}", v); - } - - public static void main(final String... args) { - System.out.println(VERSION); - } -} diff --git a/dd-trace-ot/src/main/java/datadog/trace/common/util/DaemonThreadFactory.java b/dd-trace-ot/src/main/java/datadog/trace/common/util/DaemonThreadFactory.java deleted file mode 100644 index 25d08887ce..0000000000 --- a/dd-trace-ot/src/main/java/datadog/trace/common/util/DaemonThreadFactory.java +++ /dev/null @@ -1,24 +0,0 @@ -package datadog.trace.common.util; - -import java.util.concurrent.ThreadFactory; - -/** A {@link ThreadFactory} implementation that starts all {@link Thread} as daemons. */ -public final class DaemonThreadFactory implements ThreadFactory { - private final String threadName; - - /** - * Constructs a new {@code DaemonThreadFactory}. - * - * @param threadName used to prefix all thread names. - */ - public DaemonThreadFactory(final String threadName) { - this.threadName = threadName; - } - - @Override - public Thread newThread(final Runnable r) { - final Thread thread = new Thread(r, threadName); - thread.setDaemon(true); - return thread; - } -} diff --git a/dd-trace-ot/src/main/java/datadog/trace/common/writer/DDAgentWriter.java b/dd-trace-ot/src/main/java/datadog/trace/common/writer/DDAgentWriter.java deleted file mode 100644 index 0e43736e7d..0000000000 --- a/dd-trace-ot/src/main/java/datadog/trace/common/writer/DDAgentWriter.java +++ /dev/null @@ -1,586 +0,0 @@ -package datadog.trace.common.writer; - -import static datadog.trace.api.Config.DEFAULT_AGENT_HOST; -import static datadog.trace.api.Config.DEFAULT_AGENT_UNIX_DOMAIN_SOCKET; -import static datadog.trace.api.Config.DEFAULT_TRACE_AGENT_PORT; -import static java.util.concurrent.TimeUnit.SECONDS; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.lmax.disruptor.EventFactory; -import com.lmax.disruptor.EventHandler; -import com.lmax.disruptor.EventTranslator; -import com.lmax.disruptor.EventTranslatorOneArg; -import com.lmax.disruptor.SleepingWaitStrategy; -import com.lmax.disruptor.dsl.Disruptor; -import com.lmax.disruptor.dsl.ProducerType; -import com.timgroup.statsd.NonBlockingStatsDClient; -import com.timgroup.statsd.StatsDClient; -import datadog.opentracing.DDSpan; -import datadog.opentracing.DDTraceOTInfo; -import datadog.trace.common.util.DaemonThreadFactory; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.Phaser; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import lombok.extern.slf4j.Slf4j; - -/** - * This writer buffers traces and sends them to the provided DDApi instance. - * - *

Written traces are passed off to a disruptor so as to avoid blocking the application's thread. - * If a flood of traces arrives that exceeds the disruptor ring size, the traces exceeding the - * threshold will be counted. - */ -@Slf4j -public class DDAgentWriter implements Writer { - private static final int DISRUPTOR_BUFFER_SIZE = 8192; - private static final int FLUSH_PAYLOAD_BYTES = 5_000_000; // 5 MB - private static final int FLUSH_PAYLOAD_DELAY = 1; // 1/second - - private static final EventTranslatorOneArg>, List> TRANSLATOR = - new EventTranslatorOneArg>, List>() { - @Override - public void translateTo( - final Event> event, final long sequence, final List trace) { - event.data = trace; - } - }; - private static final EventTranslator>> FLUSH_TRANSLATOR = - new EventTranslator>>() { - @Override - public void translateTo(final Event> event, final long sequence) { - event.shouldFlush = true; - } - }; - - private static final ThreadFactory DISRUPTOR_THREAD_FACTORY = - new DaemonThreadFactory("dd-trace-disruptor"); - private static final ThreadFactory SCHEDULED_FLUSH_THREAD_FACTORY = - new DaemonThreadFactory("dd-trace-writer"); - - private final Runnable flushTask = new FlushTask(); - private final DDApi api; - private final int flushFrequencySeconds; - private final Disruptor>> disruptor; - private final ScheduledExecutorService scheduledWriterExecutor; - private final AtomicInteger traceCount = new AtomicInteger(0); - private final AtomicReference> flushSchedule = new AtomicReference<>(); - private final Phaser apiPhaser; - private volatile boolean running = false; - - private final Monitor monitor; - - public DDAgentWriter() { - this( - new DDApi(DEFAULT_AGENT_HOST, DEFAULT_TRACE_AGENT_PORT, DEFAULT_AGENT_UNIX_DOMAIN_SOCKET), - new NoopMonitor()); - } - - public DDAgentWriter(final DDApi api, final Monitor monitor) { - this(api, monitor, DISRUPTOR_BUFFER_SIZE, FLUSH_PAYLOAD_DELAY); - } - - /** Old signature (pre-Monitor) used in tests */ - private DDAgentWriter(final DDApi api) { - this(api, new NoopMonitor()); - } - - /** - * Used in the tests. - * - * @param api - * @param disruptorSize Rounded up to next power of 2 - * @param flushFrequencySeconds value < 1 disables scheduled flushes - */ - private DDAgentWriter(final DDApi api, final int disruptorSize, final int flushFrequencySeconds) { - this(api, new NoopMonitor(), disruptorSize, flushFrequencySeconds); - } - - private DDAgentWriter( - final DDApi api, - final Monitor monitor, - final int disruptorSize, - final int flushFrequencySeconds) { - this.api = api; - this.monitor = monitor; - - disruptor = - new Disruptor<>( - new DisruptorEventFactory>(), - Math.max(2, Integer.highestOneBit(disruptorSize - 1) << 1), // Next power of 2 - DISRUPTOR_THREAD_FACTORY, - ProducerType.MULTI, - new SleepingWaitStrategy(0, TimeUnit.MILLISECONDS.toNanos(5))); - disruptor.handleEventsWith(new TraceConsumer()); - - this.flushFrequencySeconds = flushFrequencySeconds; - scheduledWriterExecutor = Executors.newScheduledThreadPool(1, SCHEDULED_FLUSH_THREAD_FACTORY); - - apiPhaser = new Phaser(); // Ensure API calls are completed when flushing - apiPhaser.register(); // Register on behalf of the scheduled executor thread. - } - - // Exposing some statistics for consumption by monitors - public final long getDisruptorCapacity() { - return disruptor.getRingBuffer().getBufferSize(); - } - - public final long getDisruptorUtilizedCapacity() { - return getDisruptorCapacity() - getDisruptorRemainingCapacity(); - } - - public final long getDisruptorRemainingCapacity() { - return disruptor.getRingBuffer().remainingCapacity(); - } - - @Override - public void write(final List trace) { - // We can't add events after shutdown otherwise it will never complete shutting down. - if (running) { - final boolean published = disruptor.getRingBuffer().tryPublishEvent(TRANSLATOR, trace); - - if (published) { - monitor.onPublish(DDAgentWriter.this, trace); - } else { - // We're discarding the trace, but we still want to count it. - traceCount.incrementAndGet(); - log.debug("Trace written to overfilled buffer. Counted but dropping trace: {}", trace); - - monitor.onFailedPublish(this, trace); - } - } else { - log.debug("Trace written after shutdown. Ignoring trace: {}", trace); - - monitor.onFailedPublish(this, trace); - } - } - - @Override - public void incrementTraceCount() { - traceCount.incrementAndGet(); - } - - public DDApi getApi() { - return api; - } - - @Override - public void start() { - disruptor.start(); - running = true; - scheduleFlush(); - - monitor.onStart(this); - } - - @Override - public void close() { - running = false; - - boolean flushSuccess = true; - - // We have to shutdown scheduled executor first to make sure no flush events issued after - // disruptor has been shutdown. - // Otherwise those events will never be processed and flush call will wait forever. - scheduledWriterExecutor.shutdown(); - try { - scheduledWriterExecutor.awaitTermination(flushFrequencySeconds, SECONDS); - } catch (final InterruptedException e) { - log.warn("Waiting for flush executor shutdown interrupted.", e); - - flushSuccess = false; - } - flushSuccess |= flush(); - disruptor.shutdown(); - - monitor.onShutdown(this, flushSuccess); - } - - /** This method will block until the flush is complete. */ - public boolean flush() { - if (running) { - log.info("Flushing any remaining traces."); - // Register with the phaser so we can block until the flush completion. - apiPhaser.register(); - disruptor.publishEvent(FLUSH_TRANSLATOR); - try { - // Allow thread to be interrupted. - apiPhaser.awaitAdvanceInterruptibly(apiPhaser.arriveAndDeregister()); - - return true; - } catch (final InterruptedException e) { - log.warn("Waiting for flush interrupted.", e); - - return false; - } - } else { - return false; - } - } - - @Override - public String toString() { - // DQH - I don't particularly like the instanceof check, - // but I decided it was preferable to adding an isNoop method onto - // Monitor or checking the result of Monitor#toString() to determine - // if something is *probably* the NoopMonitor. - - String str = "DDAgentWriter { api=" + api; - if (!(monitor instanceof NoopMonitor)) { - str += ", monitor=" + monitor; - } - str += " }"; - - return str; - } - - private void scheduleFlush() { - if (flushFrequencySeconds > 0 && !scheduledWriterExecutor.isShutdown()) { - final ScheduledFuture previous = - flushSchedule.getAndSet( - scheduledWriterExecutor.schedule(flushTask, flushFrequencySeconds, SECONDS)); - - final boolean previousIncomplete = (previous != null); - if (previousIncomplete) { - previous.cancel(true); - } - - monitor.onScheduleFlush(this, previousIncomplete); - } - } - - private class FlushTask implements Runnable { - @Override - public void run() { - // Don't call flush() because it would block the thread also used for sending the traces. - disruptor.publishEvent(FLUSH_TRANSLATOR); - } - } - - /** This class is intentionally not threadsafe. */ - private class TraceConsumer implements EventHandler>> { - private List serializedTraces = new ArrayList<>(); - private int payloadSize = 0; - - @Override - public void onEvent( - final Event> event, final long sequence, final boolean endOfBatch) { - final List trace = event.data; - event.data = null; // clear the event for reuse. - if (trace != null) { - traceCount.incrementAndGet(); - try { - final byte[] serializedTrace = api.serializeTrace(trace); - payloadSize += serializedTrace.length; - serializedTraces.add(serializedTrace); - - monitor.onSerialize(DDAgentWriter.this, trace, serializedTrace); - } catch (final JsonProcessingException e) { - log.warn("Error serializing trace", e); - - monitor.onFailedSerialize(DDAgentWriter.this, trace, e); - } catch (final Throwable e) { - log.debug("Error while serializing trace", e); - - monitor.onFailedSerialize(DDAgentWriter.this, trace, e); - } - } - if (event.shouldFlush || payloadSize >= FLUSH_PAYLOAD_BYTES) { - reportTraces(); - event.shouldFlush = false; - } - } - - private void reportTraces() { - try { - if (serializedTraces.isEmpty()) { - apiPhaser.arrive(); // Allow flush to return - return; - // scheduleFlush called in finally block. - } - final List toSend = serializedTraces; - serializedTraces = new ArrayList<>(toSend.size()); - // ^ Initialize with similar size to reduce arraycopy churn. - - final int representativeCount = traceCount.getAndSet(0); - final int sizeInBytes = payloadSize; - - // Run the actual IO task on a different thread to avoid blocking the consumer. - scheduledWriterExecutor.execute( - new Runnable() { - @Override - public void run() { - try { - final DDApi.Response response = - api.sendSerializedTraces(representativeCount, sizeInBytes, toSend); - - if (response.success()) { - log.debug("Successfully sent {} traces to the API", toSend.size()); - - monitor.onSend(DDAgentWriter.this, representativeCount, sizeInBytes, response); - } else { - log.debug( - "Failed to send {} traces (representing {}) of size {} bytes to the API", - toSend.size(), - representativeCount, - sizeInBytes); - - monitor.onFailedSend( - DDAgentWriter.this, representativeCount, sizeInBytes, response); - } - } catch (final Throwable e) { - log.debug("Failed to send traces to the API: {}", e.getMessage()); - - // DQH - 10/2019 - DDApi should wrap most exceptions itself, so this really - // shouldn't occur. - // However, just to be safe to start, create a failed Response to handle any - // spurious Throwable-s. - monitor.onFailedSend( - DDAgentWriter.this, - representativeCount, - sizeInBytes, - DDApi.Response.failed(e)); - } finally { - apiPhaser.arrive(); // Flush completed. - } - } - }); - } finally { - payloadSize = 0; - scheduleFlush(); - } - } - } - - private static class Event { - private volatile boolean shouldFlush = false; - private volatile T data = null; - } - - private static class DisruptorEventFactory implements EventFactory> { - @Override - public Event newInstance() { - return new Event<>(); - } - } - - /** - * Callback interface for monitoring the health of the DDAgentWriter. Provides hooks for major - * lifecycle events... - * - *

    - *
  • start - *
  • shutdown - *
  • publishing to disruptor - *
  • serializing - *
  • sending to agent - *
- */ - public interface Monitor { - void onStart(final DDAgentWriter agentWriter); - - void onShutdown(final DDAgentWriter agentWriter, final boolean flushSuccess); - - void onPublish(final DDAgentWriter agentWriter, final List trace); - - void onFailedPublish(final DDAgentWriter agentWriter, final List trace); - - void onScheduleFlush(final DDAgentWriter agentWriter, final boolean previousIncomplete); - - void onSerialize( - final DDAgentWriter agentWriter, final List trace, final byte[] serializedTrace); - - void onFailedSerialize( - final DDAgentWriter agentWriter, final List trace, final Throwable optionalCause); - - void onSend( - final DDAgentWriter agentWriter, - final int representativeCount, - final int sizeInBytes, - final DDApi.Response response); - - void onFailedSend( - final DDAgentWriter agentWriter, - final int representativeCount, - final int sizeInBytes, - final DDApi.Response response); - } - - public static final class NoopMonitor implements Monitor { - @Override - public void onStart(final DDAgentWriter agentWriter) {} - - @Override - public void onShutdown(final DDAgentWriter agentWriter, final boolean flushSuccess) {} - - @Override - public void onPublish(final DDAgentWriter agentWriter, final List trace) {} - - @Override - public void onFailedPublish(final DDAgentWriter agentWriter, final List trace) {} - - @Override - public void onScheduleFlush( - final DDAgentWriter agentWriter, final boolean previousIncomplete) {} - - @Override - public void onSerialize( - final DDAgentWriter agentWriter, final List trace, final byte[] serializedTrace) {} - - @Override - public void onFailedSerialize( - final DDAgentWriter agentWriter, final List trace, final Throwable optionalCause) {} - - @Override - public void onSend( - final DDAgentWriter agentWriter, - final int representativeCount, - final int sizeInBytes, - final DDApi.Response response) {} - - @Override - public void onFailedSend( - final DDAgentWriter agentWriter, - final int representativeCount, - final int sizeInBytes, - final DDApi.Response response) {} - - @Override - public String toString() { - return "NoOp"; - } - } - - public static final class StatsDMonitor implements Monitor { - public static final String PREFIX = "datadog.tracer"; - - public static final String LANG_TAG = "lang"; - public static final String LANG_VERSION_TAG = "lang_version"; - public static final String LANG_INTERPRETER_TAG = "lang_interpreter"; - public static final String LANG_INTERPRETER_VENDOR_TAG = "lang_interpreter_vendor"; - public static final String TRACER_VERSION_TAG = "tracer_version"; - - private final String hostInfo; - private final StatsDClient statsd; - - // DQH - Made a conscious choice to not take a Config object here. - // Letting the creating of the Monitor take the Config, - // so it can decide which Monitor variant to create. - public StatsDMonitor(final String host, final int port) { - hostInfo = host + ":" + port; - statsd = new NonBlockingStatsDClient(PREFIX, host, port, getDefaultTags()); - } - - // Currently, intended for testing - private StatsDMonitor(final StatsDClient statsd) { - hostInfo = null; - this.statsd = statsd; - } - - protected static final String[] getDefaultTags() { - return new String[] { - tag(LANG_TAG, "java"), - tag(LANG_VERSION_TAG, DDTraceOTInfo.JAVA_VERSION), - tag(LANG_INTERPRETER_TAG, DDTraceOTInfo.JAVA_VM_NAME), - tag(LANG_INTERPRETER_VENDOR_TAG, DDTraceOTInfo.JAVA_VM_VENDOR), - tag(TRACER_VERSION_TAG, DDTraceOTInfo.VERSION) - }; - } - - private static final String tag(final String tagPrefix, final String tagValue) { - return tagPrefix + ":" + tagValue; - } - - @Override - public void onStart(final DDAgentWriter agentWriter) { - statsd.recordGaugeValue("queue.max_length", agentWriter.getDisruptorCapacity()); - } - - @Override - public void onShutdown(final DDAgentWriter agentWriter, final boolean flushSuccess) {} - - @Override - public void onPublish(final DDAgentWriter agentWriter, final List trace) { - statsd.incrementCounter("queue.accepted"); - statsd.count("queue.accepted_lengths", trace.size()); - } - - @Override - public void onFailedPublish(final DDAgentWriter agentWriter, final List trace) { - statsd.incrementCounter("queue.dropped"); - } - - @Override - public void onScheduleFlush(final DDAgentWriter agentWriter, final boolean previousIncomplete) { - // not recorded - } - - @Override - public void onSerialize( - final DDAgentWriter agentWriter, final List trace, final byte[] serializedTrace) { - // DQH - Because of Java tracer's 2 phase acceptance and serialization scheme, this doesn't - // map precisely - statsd.count("queue.accepted_size", serializedTrace.length); - } - - @Override - public void onFailedSerialize( - final DDAgentWriter agentWriter, final List trace, final Throwable optionalCause) { - // TODO - DQH - make a new stat for serialization failure -- or maybe count this towards - // api.errors??? - } - - @Override - public void onSend( - final DDAgentWriter agentWriter, - final int representativeCount, - final int sizeInBytes, - final DDApi.Response response) { - onSendAttempt(agentWriter, representativeCount, sizeInBytes, response); - } - - @Override - public void onFailedSend( - final DDAgentWriter agentWriter, - final int representativeCount, - final int sizeInBytes, - final DDApi.Response response) { - onSendAttempt(agentWriter, representativeCount, sizeInBytes, response); - } - - private void onSendAttempt( - final DDAgentWriter agentWriter, - final int representativeCount, - final int sizeInBytes, - final DDApi.Response response) { - statsd.incrementCounter("api.requests"); - statsd.recordGaugeValue("queue.length", representativeCount); - // TODO: missing queue.spans (# of spans being sent) - statsd.recordGaugeValue("queue.size", sizeInBytes); - - if (response.exception() != null) { - // covers communication errors -- both not receiving a response or - // receiving malformed response (even when otherwise successful) - statsd.incrementCounter("api.errors"); - } - - if (response.status() != null) { - statsd.incrementCounter("api.responses", "status: " + response.status()); - } - } - - public String toString() { - if (hostInfo == null) { - return "StatsD"; - } else { - return "StatsD { host=" + hostInfo + " }"; - } - } - } -} diff --git a/dd-trace-ot/src/main/java/datadog/trace/common/writer/DDApi.java b/dd-trace-ot/src/main/java/datadog/trace/common/writer/DDApi.java deleted file mode 100644 index 164089f3c5..0000000000 --- a/dd-trace-ot/src/main/java/datadog/trace/common/writer/DDApi.java +++ /dev/null @@ -1,373 +0,0 @@ -package datadog.trace.common.writer; - -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import datadog.opentracing.ContainerInfo; -import datadog.opentracing.DDSpan; -import datadog.opentracing.DDTraceOTInfo; -import datadog.trace.common.writer.unixdomainsockets.UnixDomainSocketFactory; -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.TimeUnit; -import lombok.extern.slf4j.Slf4j; -import okhttp3.HttpUrl; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; -import okio.BufferedSink; -import org.msgpack.core.MessagePack; -import org.msgpack.core.MessagePacker; -import org.msgpack.jackson.dataformat.MessagePackFactory; - -/** The API pointing to a DD agent */ -@Slf4j -public class DDApi { - private static final String DATADOG_META_LANG = "Datadog-Meta-Lang"; - private static final String DATADOG_META_LANG_VERSION = "Datadog-Meta-Lang-Version"; - private static final String DATADOG_META_LANG_INTERPRETER = "Datadog-Meta-Lang-Interpreter"; - private static final String DATADOG_META_LANG_INTERPRETER_VENDOR = - "Datadog-Meta-Lang-Interpreter-Vendor"; - private static final String DATADOG_META_TRACER_VERSION = "Datadog-Meta-Tracer-Version"; - private static final String DATADOG_CONTAINER_ID = "Datadog-Container-ID"; - private static final String X_DATADOG_TRACE_COUNT = "X-Datadog-Trace-Count"; - - private static final int HTTP_TIMEOUT = 1; // 1 second for conenct/read/write operations - private static final String TRACES_ENDPOINT_V3 = "v0.3/traces"; - private static final String TRACES_ENDPOINT_V4 = "v0.4/traces"; - private static final long MILLISECONDS_BETWEEN_ERROR_LOG = TimeUnit.MINUTES.toMillis(5); - - private final List responseListeners = new ArrayList<>(); - - private volatile long nextAllowedLogTime = 0; - - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(new MessagePackFactory()); - private static final MediaType MSGPACK = MediaType.get("application/msgpack"); - - private final OkHttpClient httpClient; - private final HttpUrl tracesUrl; - - public DDApi(final String host, final int port, final String unixDomainSocketPath) { - this( - host, - port, - traceEndpointAvailable(getUrl(host, port, TRACES_ENDPOINT_V4), unixDomainSocketPath), - unixDomainSocketPath); - } - - DDApi( - final String host, - final int port, - final boolean v4EndpointsAvailable, - final String unixDomainSocketPath) { - httpClient = buildHttpClient(unixDomainSocketPath); - - if (v4EndpointsAvailable) { - tracesUrl = getUrl(host, port, TRACES_ENDPOINT_V4); - } else { - log.debug("API v0.4 endpoints not available. Downgrading to v0.3"); - tracesUrl = getUrl(host, port, TRACES_ENDPOINT_V3); - } - } - - public void addResponseListener(final ResponseListener listener) { - if (!responseListeners.contains(listener)) { - responseListeners.add(listener); - } - } - - /** - * Send traces to the DD agent - * - * @param traces the traces to be sent - * @return a Response object -- encapsulating success of communication, sending, and result - * parsing - */ - public Response sendTraces(final List> traces) { - final List serializedTraces = new ArrayList<>(traces.size()); - int sizeInBytes = 0; - for (final List trace : traces) { - try { - final byte[] serializedTrace = serializeTrace(trace); - sizeInBytes += serializedTrace.length; - serializedTraces.add(serializedTrace); - } catch (final JsonProcessingException e) { - log.warn("Error serializing trace", e); - - // TODO: DQH - Incorporate the failed serialization into the Response object??? - } - } - - return sendSerializedTraces(serializedTraces.size(), sizeInBytes, serializedTraces); - } - - byte[] serializeTrace(final List trace) throws JsonProcessingException { - return OBJECT_MAPPER.writeValueAsBytes(trace); - } - - Response sendSerializedTraces( - final int representativeCount, final Integer sizeInBytes, final List traces) { - try { - final RequestBody body = - new RequestBody() { - @Override - public MediaType contentType() { - return MSGPACK; - } - - @Override - public long contentLength() { - final int traceCount = traces.size(); - // Need to allocate additional to handle MessagePacker.packArrayHeader - if (traceCount < (1 << 4)) { - return sizeInBytes + 1; // byte - } else if (traceCount < (1 << 16)) { - return sizeInBytes + 3; // byte + short - } else { - return sizeInBytes + 5; // byte + int - } - } - - @Override - public void writeTo(final BufferedSink sink) throws IOException { - final OutputStream out = sink.outputStream(); - final MessagePacker packer = MessagePack.newDefaultPacker(out); - packer.packArrayHeader(traces.size()); - for (final byte[] trace : traces) { - packer.writePayload(trace); - } - packer.close(); - out.close(); - } - }; - final Request request = - prepareRequest(tracesUrl) - .addHeader(X_DATADOG_TRACE_COUNT, String.valueOf(representativeCount)) - .put(body) - .build(); - - try (final okhttp3.Response response = httpClient.newCall(request).execute()) { - if (response.code() != 200) { - if (log.isDebugEnabled()) { - log.debug( - "Error while sending {} of {} traces to the DD agent. Status: {}, Response: {}, Body: {}", - traces.size(), - representativeCount, - response.code(), - response.message(), - response.body().string()); - } else if (nextAllowedLogTime < System.currentTimeMillis()) { - nextAllowedLogTime = System.currentTimeMillis() + MILLISECONDS_BETWEEN_ERROR_LOG; - log.warn( - "Error while sending {} of {} traces to the DD agent. Status: {} {} (going silent for {} minutes)", - traces.size(), - representativeCount, - response.code(), - response.message(), - TimeUnit.MILLISECONDS.toMinutes(MILLISECONDS_BETWEEN_ERROR_LOG)); - } - return Response.failed(response.code()); - } - - log.debug( - "Successfully sent {} of {} traces to the DD agent.", - traces.size(), - representativeCount); - - final String responseString = response.body().string().trim(); - try { - if (!"".equals(responseString) && !"OK".equalsIgnoreCase(responseString)) { - final JsonNode parsedResponse = OBJECT_MAPPER.readTree(responseString); - final String endpoint = tracesUrl.toString(); - - for (final ResponseListener listener : responseListeners) { - listener.onResponse(endpoint, parsedResponse); - } - return Response.success(response.code(), parsedResponse); - } - - return Response.success(response.code()); - } catch (final JsonParseException e) { - log.debug("Failed to parse DD agent response: " + responseString, e); - - return Response.success(response.code(), e); - } - } - } catch (final IOException e) { - if (log.isDebugEnabled()) { - log.debug( - "Error while sending " - + traces.size() - + " of " - + representativeCount - + " traces to the DD agent.", - e); - } else if (nextAllowedLogTime < System.currentTimeMillis()) { - nextAllowedLogTime = System.currentTimeMillis() + MILLISECONDS_BETWEEN_ERROR_LOG; - log.warn( - "Error while sending {} of {} traces to the DD agent. {}: {} (going silent for {} minutes)", - traces.size(), - representativeCount, - e.getClass().getName(), - e.getMessage(), - TimeUnit.MILLISECONDS.toMinutes(MILLISECONDS_BETWEEN_ERROR_LOG)); - } - return Response.failed(e); - } - } - - private static boolean traceEndpointAvailable( - final HttpUrl url, final String unixDomainSocketPath) { - return endpointAvailable(url, unixDomainSocketPath, Collections.emptyList(), true); - } - - private static boolean endpointAvailable( - final HttpUrl url, - final String unixDomainSocketPath, - final Object data, - final boolean retry) { - try { - final OkHttpClient client = buildHttpClient(unixDomainSocketPath); - final RequestBody body = RequestBody.create(MSGPACK, OBJECT_MAPPER.writeValueAsBytes(data)); - final Request request = prepareRequest(url).put(body).build(); - - try (final okhttp3.Response response = client.newCall(request).execute()) { - return response.code() == 200; - } - } catch (final IOException e) { - if (retry) { - return endpointAvailable(url, unixDomainSocketPath, data, false); - } - } - return false; - } - - private static OkHttpClient buildHttpClient(final String unixDomainSocketPath) { - OkHttpClient.Builder builder = new OkHttpClient.Builder(); - if (unixDomainSocketPath != null) { - builder = builder.socketFactory(new UnixDomainSocketFactory(new File(unixDomainSocketPath))); - } - return builder - .connectTimeout(HTTP_TIMEOUT, TimeUnit.SECONDS) - .writeTimeout(HTTP_TIMEOUT, TimeUnit.SECONDS) - .readTimeout(HTTP_TIMEOUT, TimeUnit.SECONDS) - .build(); - } - - private static HttpUrl getUrl(final String host, final int port, final String endPoint) { - return new HttpUrl.Builder() - .scheme("http") - .host(host) - .port(port) - .addEncodedPathSegments(endPoint) - .build(); - } - - private static Request.Builder prepareRequest(final HttpUrl url) { - final Request.Builder builder = - new Request.Builder() - .url(url) - .addHeader(DATADOG_META_LANG, "java") - .addHeader(DATADOG_META_LANG_VERSION, DDTraceOTInfo.JAVA_VERSION) - .addHeader(DATADOG_META_LANG_INTERPRETER, DDTraceOTInfo.JAVA_VM_NAME) - .addHeader(DATADOG_META_LANG_INTERPRETER_VENDOR, DDTraceOTInfo.JAVA_VM_VENDOR) - .addHeader(DATADOG_META_TRACER_VERSION, DDTraceOTInfo.VERSION); - - final String containerId = ContainerInfo.get().getContainerId(); - if (containerId == null) { - return builder; - } else { - return builder.addHeader(DATADOG_CONTAINER_ID, containerId); - } - } - - @Override - public String toString() { - return "DDApi { tracesUrl=" + tracesUrl + " }"; - } - - /** - * Encapsulates an attempted response from the Datadog agent. - * - *

If communication fails or times out, the Response will NOT be successful and will lack - * status code, but will have an exception. - * - *

If an communication occurs, the Response will have a status code and will be marked as - * success or fail in accordance with the code. - * - *

NOTE: A successful communication may still contain an exception if there was a problem - * parsing the response from the Datadog agent. - */ - public static final class Response { - /** Factory method for a successful request with a trivial response body */ - public static final Response success(final int status) { - return new Response(true, status, null, null); - } - - /** Factory method for a successful request with a well-formed JSON response body */ - public static final Response success(final int status, final JsonNode json) { - return new Response(true, status, json, null); - } - - /** Factory method for a successful request will a malformed response body */ - public static final Response success(final int status, final Throwable exception) { - return new Response(true, status, null, exception); - } - - /** Factory method for a request that receive an error status in response */ - public static final Response failed(final int status) { - return new Response(false, status, null, null); - } - - /** Factory method for a failed communication attempt */ - public static final Response failed(final Throwable exception) { - return new Response(false, null, null, exception); - } - - private final boolean success; - private final Integer status; - private final JsonNode json; - private final Throwable exception; - - private Response( - final boolean success, - final Integer status, - final JsonNode json, - final Throwable exception) { - this.success = success; - this.status = status; - this.json = json; - this.exception = exception; - } - - public final boolean success() { - return this.success; - } - - // TODO: DQH - In Java 8, switch to OptionalInteger - public final Integer status() { - return this.status; - } - - public final JsonNode json() { - return this.json; - } - - // TODO: DQH - In Java 8, switch to Optional? - public final Throwable exception() { - return this.exception; - } - } - - public interface ResponseListener { - /** Invoked after the api receives a response from the core agent. */ - void onResponse(String endpoint, JsonNode responseJson); - } -} diff --git a/dd-trace-ot/src/main/java/datadog/trace/common/writer/LoggingWriter.java b/dd-trace-ot/src/main/java/datadog/trace/common/writer/LoggingWriter.java index cb95d07a72..4f98b8acfd 100644 --- a/dd-trace-ot/src/main/java/datadog/trace/common/writer/LoggingWriter.java +++ b/dd-trace-ot/src/main/java/datadog/trace/common/writer/LoggingWriter.java @@ -1,19 +1,17 @@ package datadog.trace.common.writer; -import com.fasterxml.jackson.databind.ObjectMapper; import datadog.opentracing.DDSpan; import java.util.List; import lombok.extern.slf4j.Slf4j; @Slf4j public class LoggingWriter implements Writer { - private final ObjectMapper serializer = new ObjectMapper(); @Override public void write(final List trace) { - if (log.isInfoEnabled()) { + if (log.isInfoEnabled() && !trace.isEmpty()) { try { - log.info("write(trace): {}", serializer.writeValueAsString(trace)); + log.info("write(trace): {}", trace.get(0).getTraceId()); } catch (final Exception e) { log.error("error writing(trace): {}", trace); } diff --git a/dd-trace-ot/src/main/java/datadog/trace/common/writer/Writer.java b/dd-trace-ot/src/main/java/datadog/trace/common/writer/Writer.java index 86de685d75..3d0466569f 100644 --- a/dd-trace-ot/src/main/java/datadog/trace/common/writer/Writer.java +++ b/dd-trace-ot/src/main/java/datadog/trace/common/writer/Writer.java @@ -4,7 +4,6 @@ import datadog.opentracing.DDSpan; import datadog.trace.api.Config; import java.io.Closeable; import java.util.List; -import java.util.Properties; import lombok.extern.slf4j.Slf4j; /** A writer is responsible to send collected spans to some place */ @@ -38,56 +37,23 @@ public interface Writer extends Closeable { if (config != null) { final String configuredType = config.getWriterType(); - if (Config.DD_AGENT_WRITER_TYPE.equals(configuredType)) { - writer = createAgentWriter(config); - } else if (Config.LOGGING_WRITER_TYPE.equals(configuredType)) { + if (Config.LOGGING_WRITER_TYPE.equals(configuredType)) { writer = new LoggingWriter(); } else { log.warn( - "Writer type not configured correctly: Type {} not recognized. Defaulting to DDAgentWriter.", + "Writer type not configured correctly: Type {} not recognized. Defaulting to LoggingWriter.", configuredType); - writer = createAgentWriter(config); + writer = new LoggingWriter(); } } else { log.warn( - "Writer type not configured correctly: No config provided! Defaulting to DDAgentWriter."); - writer = new DDAgentWriter(); + "Writer type not configured correctly: No config provided! Defaulting to LoggingWriter."); + writer = new LoggingWriter(); } return writer; } - public static Writer forConfig(final Properties config) { - return forConfig(Config.get(config)); - } - - private static Writer createAgentWriter(final Config config) { - return new DDAgentWriter(createApi(config), createMonitor(config)); - } - - private static final DDApi createApi(final Config config) { - return new DDApi( - config.getAgentHost(), config.getAgentPort(), config.getAgentUnixDomainSocket()); - } - - private static final DDAgentWriter.Monitor createMonitor(final Config config) { - if (!config.isHealthMetricsEnabled()) { - return new DDAgentWriter.NoopMonitor(); - } else { - String host = config.getHealthMetricsStatsdHost(); - if (host == null) { - host = config.getAgentHost(); - } - - Integer port = config.getHealthMetricsStatsdPort(); - if (port == null) { - return new DDAgentWriter.NoopMonitor(); - } - - return new DDAgentWriter.StatsDMonitor(host, port); - } - } - private Builder() {} } } diff --git a/dd-trace-ot/src/main/java/datadog/trace/common/writer/unixdomainsockets/TunnelingUnixSocket.java b/dd-trace-ot/src/main/java/datadog/trace/common/writer/unixdomainsockets/TunnelingUnixSocket.java deleted file mode 100644 index fb8d6de73f..0000000000 --- a/dd-trace-ot/src/main/java/datadog/trace/common/writer/unixdomainsockets/TunnelingUnixSocket.java +++ /dev/null @@ -1,51 +0,0 @@ -package datadog.trace.common.writer.unixdomainsockets; - -import java.io.File; -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import jnr.unixsocket.UnixSocket; -import jnr.unixsocket.UnixSocketAddress; -import jnr.unixsocket.UnixSocketChannel; - -/** - * Subtype UNIX socket for a higher-fidelity impersonation of TCP sockets. This is named "tunneling" - * because it assumes the ultimate destination has a hostname and port. - * - *

Copied from okHttp - * examples. - */ -final class TunnelingUnixSocket extends UnixSocket { - private final File path; - private InetSocketAddress inetSocketAddress; - - TunnelingUnixSocket(final File path, final UnixSocketChannel channel) { - super(channel); - this.path = path; - } - - TunnelingUnixSocket( - final File path, final UnixSocketChannel channel, final InetSocketAddress address) { - this(path, channel); - inetSocketAddress = address; - } - - @Override - public void connect(final SocketAddress endpoint) throws IOException { - inetSocketAddress = (InetSocketAddress) endpoint; - super.connect(new UnixSocketAddress(path), 0); - } - - @Override - public void connect(final SocketAddress endpoint, final int timeout) throws IOException { - inetSocketAddress = (InetSocketAddress) endpoint; - super.connect(new UnixSocketAddress(path), timeout); - } - - @Override - public InetAddress getInetAddress() { - return inetSocketAddress.getAddress(); - } -} diff --git a/dd-trace-ot/src/main/java/datadog/trace/common/writer/unixdomainsockets/UnixDomainSocketFactory.java b/dd-trace-ot/src/main/java/datadog/trace/common/writer/unixdomainsockets/UnixDomainSocketFactory.java deleted file mode 100644 index 0b9204e84e..0000000000 --- a/dd-trace-ot/src/main/java/datadog/trace/common/writer/unixdomainsockets/UnixDomainSocketFactory.java +++ /dev/null @@ -1,58 +0,0 @@ -package datadog.trace.common.writer.unixdomainsockets; - -import java.io.File; -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import javax.net.SocketFactory; -import jnr.unixsocket.UnixSocketChannel; - -/** - * Impersonate TCP-style SocketFactory over UNIX domain sockets. - * - *

Copied from okHttp - * examples. - */ -public final class UnixDomainSocketFactory extends SocketFactory { - private final File path; - - public UnixDomainSocketFactory(final File path) { - this.path = path; - } - - @Override - public Socket createSocket() throws IOException { - final UnixSocketChannel channel = UnixSocketChannel.open(); - return new TunnelingUnixSocket(path, channel); - } - - @Override - public Socket createSocket(final String host, final int port) throws IOException { - final Socket result = createSocket(); - result.connect(new InetSocketAddress(host, port)); - return result; - } - - @Override - public Socket createSocket( - final String host, final int port, final InetAddress localHost, final int localPort) - throws IOException { - return createSocket(host, port); - } - - @Override - public Socket createSocket(final InetAddress host, final int port) throws IOException { - final Socket result = createSocket(); - result.connect(new InetSocketAddress(host, port)); - return result; - } - - @Override - public Socket createSocket( - final InetAddress host, final int port, final InetAddress localAddress, final int localPort) - throws IOException { - return createSocket(host, port); - } -} diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/ContainerInfoTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/ContainerInfoTest.groovy deleted file mode 100644 index 047eb583d5..0000000000 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/ContainerInfoTest.groovy +++ /dev/null @@ -1,147 +0,0 @@ -package datadog.opentracing - -import datadog.trace.util.test.DDSpecification -import spock.lang.Unroll - -class ContainerInfoTest extends DDSpecification { - - @Unroll - def "CGroupInfo is parsed from individual lines"() { - when: - ContainerInfo.CGroupInfo cGroupInfo = ContainerInfo.parseLine(line) - - then: - cGroupInfo.getId() == id - cGroupInfo.getPath() == path - cGroupInfo.getControllers() == controllers - cGroupInfo.getContainerId() == containerId - cGroupInfo.podId == podId - - // Examples from container tagging rfc and Qard/container-info - where: - id | controllers | path | containerId | podId | line - - // Docker examples - 13 | ["name=systemd"] | "/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | "3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | null | "13:name=systemd:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" - 12 | ["pids"] | "/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | "3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | null | "12:pids:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" - 11 | ["hugetlb"] | "/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | "3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | null | "11:hugetlb:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" - 10 | ["net_prio"] | "/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | "3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | null | "10:net_prio:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" - 9 | ["perf_event"] | "/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | "3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | null | "9:perf_event:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" - 8 | ["net_cls"] | "/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | "3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | null | "8:net_cls:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" - 7 | ["freezer"] | "/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | "3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | null | "7:freezer:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" - 6 | ["devices"] | "/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | "3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | null | "6:devices:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" - 5 | ["memory"] | "/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | "3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | null | "5:memory:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" - 4 | ["blkio"] | "/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | "3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | null | "4:blkio:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" - 3 | ["cpuacct"] | "/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | "3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | null | "3:cpuacct:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" - 2 | ["cpu"] | "/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | "3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | null | "2:cpu:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" - 1 | ["cpuset"] | "/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | "3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | null | "1:cpuset:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" - - // Kubernates examples - 11 | ["perf_event"] | "/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3d274242-8ee0-11e9-a8a6-1e68d864ef1a" | "11:perf_event:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" - 10 | ["pids"] | "/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3d274242-8ee0-11e9-a8a6-1e68d864ef1a" | "10:pids:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" - 9 | ["memory"] | "/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3d274242-8ee0-11e9-a8a6-1e68d864ef1a" | "9:memory:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" - 8 | ["cpu", "cpuacct"] | "/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3d274242-8ee0-11e9-a8a6-1e68d864ef1a" | "8:cpu,cpuacct:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" - 7 | ["blkio"] | "/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3d274242-8ee0-11e9-a8a6-1e68d864ef1a" | "7:blkio:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" - 6 | ["cpuset"] | "/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3d274242-8ee0-11e9-a8a6-1e68d864ef1a" | "6:cpuset:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" - 5 | ["devices"] | "/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3d274242-8ee0-11e9-a8a6-1e68d864ef1a" | "5:devices:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" - 4 | ["freezer"] | "/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3d274242-8ee0-11e9-a8a6-1e68d864ef1a" | "4:freezer:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" - 3 | ["net_cls", "net_prio"] | "/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3d274242-8ee0-11e9-a8a6-1e68d864ef1a" | "3:net_cls,net_prio:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" - 2 | ["hugetlb"] | "/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3d274242-8ee0-11e9-a8a6-1e68d864ef1a" | "2:hugetlb:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" - 1 | ["name=systemd"] | "/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3d274242-8ee0-11e9-a8a6-1e68d864ef1a" | "1:name=systemd:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" - - //ECS examples - 9 | ["perf_event"] | "/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | "38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | null | "9:perf_event:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" - 8 | ["memory"] | "/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | "38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | null | "8:memory:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" - 7 | ["hugetlb"] | "/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | "38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | null | "7:hugetlb:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" - 6 | ["freezer"] | "/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | "38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | null | "6:freezer:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" - 5 | ["devices"] | "/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | "38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | null | "5:devices:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" - 4 | ["cpuset"] | "/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | "38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | null | "4:cpuset:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" - 3 | ["cpuacct"] | "/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | "38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | null | "3:cpuacct:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" - 2 | ["cpu"] | "/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | "38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | null | "2:cpu:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" - 1 | ["blkio"] | "/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | "38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | null | "1:blkio:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" - - //Fargate Examples - 11 | ["hugetlb"] | "/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | "432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | null | "11:hugetlb:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" - 10 | ["pids"] | "/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | "432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | null | "10:pids:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" - 9 | ["cpuset"] | "/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | "432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | null | "9:cpuset:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" - 8 | ["net_cls", "net_prio"] | "/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | "432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | null | "8:net_cls,net_prio:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" - 7 | ["cpu", "cpuacct"] | "/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | "432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | null | "7:cpu,cpuacct:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" - 6 | ["perf_event"] | "/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | "432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | null | "6:perf_event:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" - 5 | ["freezer"] | "/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | "432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | null | "5:freezer:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" - 4 | ["devices"] | "/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | "432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | null | "4:devices:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" - 3 | ["blkio"] | "/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | "432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | null | "3:blkio:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" - 2 | ["memory"] | "/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | "432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | null | "2:memory:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" - 1 | ["name=systemd"] | "/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | "432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | null | "1:name=systemd:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" - - //Reference impl examples - 1 | ["name=systemd"] | "/system.slice/docker-cde7c2bab394630a42d73dc610b9c57415dced996106665d427f6d0566594411.scope" | "cde7c2bab394630a42d73dc610b9c57415dced996106665d427f6d0566594411" | null | "1:name=systemd:/system.slice/docker-cde7c2bab394630a42d73dc610b9c57415dced996106665d427f6d0566594411.scope" - 1 | ["name=systemd"] | "/docker/051e2ee0bce99116029a13df4a9e943137f19f957f38ac02d6bad96f9b700f76/not_hex" | null | null | "1:name=systemd:/docker/051e2ee0bce99116029a13df4a9e943137f19f957f38ac02d6bad96f9b700f76/not_hex" - 1 | ["name=systemd"] | "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod90d81341_92de_11e7_8cf2_507b9d4141fa.slice/crio-2227daf62df6694645fee5df53c1f91271546a9560e8600a525690ae252b7f63.scope" | "2227daf62df6694645fee5df53c1f91271546a9560e8600a525690ae252b7f63" | "90d81341_92de_11e7_8cf2_507b9d4141fa" | "1:name=systemd:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod90d81341_92de_11e7_8cf2_507b9d4141fa.slice/crio-2227daf62df6694645fee5df53c1f91271546a9560e8600a525690ae252b7f63.scope" - - } - - @Unroll - def "Container info parsed from file content"() { - when: - ContainerInfo containerInfo = ContainerInfo.parse(content) - - then: - containerInfo.getContainerId() == containerId - containerInfo.getPodId() == podId - containerInfo.getCGroups().size() == size - - where: - containerId | podId | size | content - // Docker - "3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860" | null | 13 | """13:name=systemd:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860 -12:pids:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860 -11:hugetlb:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860 -10:net_prio:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860 -9:perf_event:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860 -8:net_cls:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860 -7:freezer:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860 -6:devices:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860 -5:memory:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860 -4:blkio:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860 -3:cpuacct:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860 -2:cpu:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860 -1:cpuset:/docker/3726184226f5d3147c25fdeab5b60097e378e8a720503a5e19ecfdf29f869860""" - - // Kubernetes - "3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1" | "3d274242-8ee0-11e9-a8a6-1e68d864ef1a" | 11 | """11:perf_event:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1 -10:pids:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1 -9:memory:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1 -8:cpu,cpuacct:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1 -7:blkio:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1 -6:cpuset:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1 -5:devices:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1 -4:freezer:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1 -3:net_cls,net_prio:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1 -2:hugetlb:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1 -1:name=systemd:/kubepods/besteffort/pod3d274242-8ee0-11e9-a8a6-1e68d864ef1a/3e74d3fd9db4c9dd921ae05c2502fb984d0cde1b36e581b13f79c639da4518a1""" - - // ECS - "38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce" | null | 9 | """9:perf_event:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce -8:memory:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce -7:hugetlb:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce -6:freezer:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce -5:devices:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce -4:cpuset:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce -3:cpuacct:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce -2:cpu:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce -1:blkio:/ecs/haissam-ecs-classic/5a0d5ceddf6c44c1928d367a815d890f/38fac3e99302b3622be089dd41e7ccf38aff368a86cc339972075136ee2710ce""" - - // Fargate - "432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da" | null | 11 | """11:hugetlb:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da -10:pids:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da -9:cpuset:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da -8:net_cls,net_prio:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da -7:cpu,cpuacct:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da -6:perf_event:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da -5:freezer:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da -4:devices:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da -3:blkio:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da -2:memory:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da -1:name=systemd:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da""" - } -} diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanSerializationTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanSerializationTest.groovy deleted file mode 100644 index 7ba5143667..0000000000 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanSerializationTest.groovy +++ /dev/null @@ -1,59 +0,0 @@ -package datadog.opentracing - -import com.fasterxml.jackson.databind.ObjectMapper -import datadog.trace.common.writer.ListWriter -import datadog.trace.util.test.DDSpecification -import org.msgpack.core.MessagePack -import org.msgpack.core.buffer.ArrayBufferInput -import org.msgpack.jackson.dataformat.MessagePackFactory -import org.msgpack.value.ValueType - -class DDSpanSerializationTest extends DDSpecification { - - def "serialize trace/span with id #value as int"() { - setup: - def objectMapper = new ObjectMapper(new MessagePackFactory()) - def writer = new ListWriter() - def tracer = new DDTracer(writer) - def context = new DDSpanContext( - value, - value, - 0G, - "fakeService", - "fakeOperation", - "fakeResource", - false, - "fakeType", - Collections.emptyMap(), - new PendingTrace(tracer, 1G), - tracer) - def span = new DDSpan(0, context) - byte[] bytes = objectMapper.writeValueAsBytes(span) - def unpacker = MessagePack.newDefaultUnpacker(new ArrayBufferInput(bytes)) - int size = unpacker.unpackMapHeader() - - expect: - for (int i = 0; i < size; i++) { - String key = unpacker.unpackString() - - switch (key) { - case "trace_id": - case "span_id": - assert unpacker.nextFormat.valueType == ValueType.INTEGER - assert unpacker.unpackBigInteger() == value - break - default: - unpacker.unpackValue() - } - } - - where: - value | _ - 0G | _ - 1G | _ - 8223372036854775807G | _ - BigInteger.valueOf(Long.MAX_VALUE).subtract(1G) | _ - BigInteger.valueOf(Long.MAX_VALUE).add(1G) | _ - 2G.pow(64).subtract(1G) | _ - } -} diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy index d8e00f309c..1c3a2cb1e7 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy @@ -50,7 +50,7 @@ class DDSpanTest extends DDSpecification { when: span.setSpanType("type") then: - span.getType() == "type" + span.getSpanType() == "type" } def "resource name equals operation name if null"() { diff --git a/dd-trace-ot/src/test/groovy/datadog/trace/DDTracerTest.groovy b/dd-trace-ot/src/test/groovy/datadog/trace/DDTracerTest.groovy index b6e44013c0..423921e5ef 100644 --- a/dd-trace-ot/src/test/groovy/datadog/trace/DDTracerTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/trace/DDTracerTest.groovy @@ -3,7 +3,6 @@ package datadog.trace import datadog.opentracing.DDTracer import datadog.opentracing.propagation.DatadogHttpCodec import datadog.trace.api.Config -import datadog.trace.common.writer.DDAgentWriter import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.LoggingWriter import datadog.trace.util.test.DDSpecification @@ -12,8 +11,6 @@ import org.junit.contrib.java.lang.system.EnvironmentVariables import org.junit.contrib.java.lang.system.RestoreSystemProperties import static datadog.trace.api.Config.DEFAULT_SERVICE_NAME -import static datadog.trace.api.Config.HEALTH_METRICS_ENABLED -import static datadog.trace.api.Config.HEALTH_METRICS_STATSD_PORT import static datadog.trace.api.Config.PREFIX import static datadog.trace.api.Config.SPAN_TAGS import static datadog.trace.api.Config.WRITER_TYPE @@ -41,12 +38,6 @@ class DDTracerTest extends DDSpecification { then: tracer.serviceName == "unnamed-java-app" - tracer.writer instanceof DDAgentWriter - ((DDAgentWriter) tracer.writer).api.tracesUrl.host() == "localhost" - ((DDAgentWriter) tracer.writer).api.tracesUrl.port() == 8126 - ((DDAgentWriter) tracer.writer).api.tracesUrl.encodedPath() == "/v0.3/traces" || - ((DDAgentWriter) tracer.writer).api.tracesUrl.encodedPath() == "/v0.4/traces" - tracer.writer.monitor instanceof DDAgentWriter.NoopMonitor tracer.spanContextDecorators.size() == 12 @@ -54,20 +45,6 @@ class DDTracerTest extends DDSpecification { tracer.extractor instanceof DatadogHttpCodec.Extractor } - def "verify enabling health monitor"() { - setup: - System.setProperty(PREFIX + HEALTH_METRICS_ENABLED, "true") - System.setProperty(PREFIX + HEALTH_METRICS_STATSD_PORT, "8125") - - when: - def tracer = new DDTracer(new Config()) - - then: - tracer.writer.monitor instanceof DDAgentWriter.StatsDMonitor - tracer.writer.monitor.hostInfo == "localhost:8125" - } - - def "verify overriding writer"() { setup: System.setProperty(PREFIX + WRITER_TYPE, "LoggingWriter") @@ -96,46 +73,6 @@ class DDTracerTest extends DDSpecification { "a:b,c:d,e:" | [a: "b", c: "d"] } - def "verify overriding host"() { - when: - System.setProperty(PREFIX + key, value) - def tracer = new DDTracer(new Config()) - - then: - tracer.writer instanceof DDAgentWriter - ((DDAgentWriter) tracer.writer).api.tracesUrl.host() == value - ((DDAgentWriter) tracer.writer).api.tracesUrl.port() == 8126 - - where: - key | value - "agent.host" | "somethingelse" - } - - def "verify overriding port"() { - when: - System.setProperty(PREFIX + key, value) - def tracer = new DDTracer(new Config()) - - then: - tracer.writer instanceof DDAgentWriter - ((DDAgentWriter) tracer.writer).api.tracesUrl.host() == "localhost" - ((DDAgentWriter) tracer.writer).api.tracesUrl.port() == Integer.valueOf(value) - - where: - key | value - "agent.port" | "777" - "trace.agent.port" | "9999" - } - - def "Writer is instance of LoggingWriter when property set"() { - when: - System.setProperty(PREFIX + "writer.type", "LoggingWriter") - def tracer = new DDTracer(new Config()) - - then: - tracer.writer instanceof LoggingWriter - } - def "verify writer constructor"() { setup: def writer = new ListWriter() diff --git a/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/DDAgentWriterTest.groovy b/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/DDAgentWriterTest.groovy deleted file mode 100644 index 5cea8d37e9..0000000000 --- a/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/DDAgentWriterTest.groovy +++ /dev/null @@ -1,575 +0,0 @@ -package datadog.trace.api.writer - -import com.timgroup.statsd.StatsDClient -import datadog.opentracing.DDSpan -import datadog.opentracing.DDSpanContext -import datadog.opentracing.DDTracer -import datadog.opentracing.PendingTrace -import datadog.trace.common.writer.DDAgentWriter -import datadog.trace.common.writer.DDApi -import datadog.trace.util.test.DDSpecification -import spock.lang.Timeout - -import java.util.concurrent.TimeUnit -import java.util.concurrent.atomic.AtomicInteger - -import static datadog.opentracing.SpanFactory.newSpanOf -import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer -import static datadog.trace.common.writer.DDAgentWriter.DISRUPTOR_BUFFER_SIZE - -@Timeout(20) -class DDAgentWriterTest extends DDSpecification { - - def api = Mock(DDApi) - - def "test happy path"() { - setup: - def writer = new DDAgentWriter(api, 2, -1) - writer.start() - - when: - writer.write(trace) - writer.write(trace) - writer.flush() - - then: - 2 * api.serializeTrace(_) >> { trace -> callRealMethod() } - 1 * api.sendSerializedTraces(2, _, { it.size() == 2 }) - 0 * _ - - cleanup: - writer.close() - - where: - trace = [newSpanOf(0, "fixed-thread-name")] - } - - def "test flood of traces"() { - setup: - def writer = new DDAgentWriter(api, disruptorSize, -1) - writer.start() - - when: - (1..traceCount).each { - writer.write(trace) - } - writer.flush() - - then: - _ * api.serializeTrace(_) >> { trace -> callRealMethod() } - 1 * api.sendSerializedTraces(traceCount, _, { it.size() < traceCount }) - 0 * _ - - cleanup: - writer.close() - - where: - trace = [newSpanOf(0, "fixed-thread-name")] - disruptorSize = 2 - traceCount = 100 // Shouldn't trigger payload, but bigger than the disruptor size. - } - - def "test flush by size"() { - setup: - def writer = new DDAgentWriter(api, DISRUPTOR_BUFFER_SIZE, -1) - def phaser = writer.apiPhaser - writer.start() - phaser.register() - - when: - (1..6).each { - writer.write(trace) - } - // Wait for 2 flushes of 3 by size - phaser.awaitAdvanceInterruptibly(phaser.arrive()) - phaser.awaitAdvanceInterruptibly(phaser.arriveAndDeregister()) - - then: - 6 * api.serializeTrace(_) >> { trace -> callRealMethod() } - 2 * api.sendSerializedTraces(3, _, { it.size() == 3 }) - - when: - (1..2).each { - writer.write(trace) - } - // Flush the remaining 2 - writer.flush() - - then: - 2 * api.serializeTrace(_) >> { trace -> callRealMethod() } - 1 * api.sendSerializedTraces(2, _, { it.size() == 2 }) - 0 * _ - - cleanup: - writer.close() - - where: - span = [newSpanOf(0, "fixed-thread-name")] - trace = (0..10000).collect { span } - } - - def "test flush by time"() { - setup: - def writer = new DDAgentWriter(api) - def phaser = writer.apiPhaser - phaser.register() - writer.start() - writer.flush() - - when: - (1..5).each { - writer.write(trace) - } - phaser.awaitAdvanceInterruptibly(phaser.arriveAndDeregister()) - - then: - 5 * api.serializeTrace(_) >> { trace -> callRealMethod() } - 1 * api.sendSerializedTraces(5, _, { it.size() == 5 }) - 0 * _ - - cleanup: - writer.close() - - where: - span = [newSpanOf(0, "fixed-thread-name")] - trace = (1..10).collect { span } - } - - def "test default buffer size"() { - setup: - def writer = new DDAgentWriter(api, DISRUPTOR_BUFFER_SIZE, -1) - writer.start() - - when: - (0..maxedPayloadTraceCount).each { - writer.write(minimalTrace) - def start = System.nanoTime() - // (consumer processes a trace in about 20 microseconds - while (System.nanoTime() - start < TimeUnit.MICROSECONDS.toNanos(100)) { - // Busywait because we don't want to fill up the ring buffer - } - } - writer.flush() - - then: - (maxedPayloadTraceCount + 1) * api.serializeTrace(_) >> { trace -> callRealMethod() } - 1 * api.sendSerializedTraces(maxedPayloadTraceCount, _, { it.size() == maxedPayloadTraceCount }) - - cleanup: - writer.close() - - where: - minimalContext = new DDSpanContext( - 1G, - 1G, - 0G, - "", - "", - "", - false, - "", - Collections.emptyMap(), - Mock(PendingTrace), - Mock(DDTracer)) - minimalSpan = new DDSpan(0, minimalContext) - minimalTrace = [minimalSpan] - traceSize = DDApi.OBJECT_MAPPER.writeValueAsBytes(minimalTrace).length - maxedPayloadTraceCount = ((int) (DDAgentWriter.FLUSH_PAYLOAD_BYTES / traceSize)) + 1 - } - - def "check that are no interactions after close"() { - - setup: - def writer = new DDAgentWriter(api) - writer.start() - - when: - writer.close() - writer.write([]) - writer.flush() - - then: - 0 * _ - writer.traceCount.get() == 0 - } - - def createMinimalTrace() { - def minimalContext = new DDSpanContext( - 1G, - 1G, - 0G, - "", - "", - "", - false, - "", - Collections.emptyMap(), - Mock(PendingTrace), - Mock(DDTracer)) - def minimalSpan = new DDSpan(0, minimalContext) - def minimalTrace = [minimalSpan] - - return minimalTrace - } - - def "monitor happy path"() { - setup: - def minimalTrace = createMinimalTrace() - - // DQH -- need to set-up a dummy agent for the final send callback to work - def agent = httpServer { - handlers { - put("v0.4/traces") { - response.status(200).send() - } - } - } - def api = new DDApi("localhost", agent.address.port, null) - def monitor = Mock(DDAgentWriter.Monitor) - def writer = new DDAgentWriter(api, monitor) - - when: - writer.start() - - then: - 1 * monitor.onStart(writer) - - when: - writer.write(minimalTrace) - writer.flush() - - then: - 1 * monitor.onPublish(writer, minimalTrace) - 1 * monitor.onSerialize(writer, minimalTrace, _) - 1 * monitor.onScheduleFlush(writer, _) - 1 * monitor.onSend(writer, 1, _, { response -> response.success() && response.status() == 200 }) - - when: - writer.close() - - then: - 1 * monitor.onShutdown(writer, true) - - cleanup: - agent.close() - } - - def "monitor agent returns error"() { - setup: - def minimalTrace = createMinimalTrace() - - // DQH -- need to set-up a dummy agent for the final send callback to work - def first = true - def agent = httpServer { - handlers { - put("v0.4/traces") { - // DQH - DDApi sniffs for end point existence, so respond with 200 the first time - if (first) { - response.status(200).send() - first = false - } else { - response.status(500).send() - } - } - } - } - def api = new DDApi("localhost", agent.address.port, null) - def monitor = Mock(DDAgentWriter.Monitor) - def writer = new DDAgentWriter(api, monitor) - - when: - writer.start() - - then: - 1 * monitor.onStart(writer) - - when: - writer.write(minimalTrace) - writer.flush() - - then: - 1 * monitor.onPublish(writer, minimalTrace) - 1 * monitor.onSerialize(writer, minimalTrace, _) - 1 * monitor.onScheduleFlush(writer, _) - 1 * monitor.onFailedSend(writer, 1, _, { response -> !response.success() && response.status() == 500 }) - - when: - writer.close() - - then: - 1 * monitor.onShutdown(writer, true) - - cleanup: - agent.close() - } - - def "unreachable agent test"() { - setup: - def minimalTrace = createMinimalTrace() - - def api = new DDApi("localhost", 8192, null) { - DDApi.Response sendSerializedTraces( - int representativeCount, - Integer sizeInBytes, - List traces) { - // simulating a communication failure to a server - return DDApi.Response.failed(new IOException("comm error")) - } - } - def monitor = Mock(DDAgentWriter.Monitor) - def writer = new DDAgentWriter(api, monitor) - - when: - writer.start() - - then: - 1 * monitor.onStart(writer) - - when: - writer.write(minimalTrace) - writer.flush() - - then: - 1 * monitor.onPublish(writer, minimalTrace) - 1 * monitor.onSerialize(writer, minimalTrace, _) - 1 * monitor.onScheduleFlush(writer, _) - 1 * monitor.onFailedSend(writer, 1, _, { response -> !response.success() && response.status() == null }) - - when: - writer.close() - - then: - 1 * monitor.onShutdown(writer, true) - } - - def "slow response test"() { - def numPublished = 0 - def numFailedPublish = 0 - - setup: - def minimalTrace = createMinimalTrace() - - // Need to set-up a dummy agent for the final send callback to work - def first = true - def agent = httpServer { - handlers { - put("v0.4/traces") { - // DDApi sniffs for end point existence, so respond quickly the first time - // then slowly thereafter - - if (!first) { - // Long enough to stall the pipeline, but not long enough to fail - Thread.sleep(2_500) - } - response.status(200).send() - first = false - } - } - } - def api = new DDApi("localhost", agent.address.port, null) - - // This test focuses just on failed publish, so not verifying every callback - def monitor = Stub(DDAgentWriter.Monitor) - monitor.onPublish(_, _) >> { - numPublished += 1 - } - monitor.onFailedPublish(_, _) >> { - numFailedPublish += 1 - } - - def bufferSize = 32 - def writer = new DDAgentWriter(api, monitor, bufferSize, DDAgentWriter.FLUSH_PAYLOAD_DELAY) - writer.start() - - when: - // write & flush a single trace -- the slow agent response will cause - // additional writes to back-up the sending queue - writer.write(minimalTrace) - writer.flush() - - then: - numPublished == 1 - numFailedPublish == 0 - - when: - // send many traces to flood the sender queue... - (1..20).each { - writer.write(minimalTrace) - } - - then: - // might spill back into the Disruptor slightly, but sender queue is currently unbounded - numPublished == 1 + 20 - numFailedPublish == 0 - - when: - // now, fill-up the disruptor buffer as well - (1..bufferSize * 2).each { - writer.write(minimalTrace) - } - - then: - // Disruptor still doesn't reject because the sender queue is unbounded - (numPublished + numFailedPublish) == (1 + 20 + bufferSize * 2) - numFailedPublish >= 0 - - cleanup: - writer.close() - agent.close() - } - - def "multi threaded"() { - def numPublished = new AtomicInteger(0) - def numFailedPublish = new AtomicInteger(0) - def numRepSent = new AtomicInteger(0) - - setup: - def minimalTrace = createMinimalTrace() - - // Need to set-up a dummy agent for the final send callback to work - def agent = httpServer { - handlers { - put("v0.4/traces") { - response.status(200).send() - } - } - } - def api = new DDApi("localhost", agent.address.port, null) - - // This test focuses just on failed publish, so not verifying every callback - def monitor = Stub(DDAgentWriter.Monitor) - monitor.onPublish(_, _) >> { - numPublished.incrementAndGet() - } - monitor.onFailedPublish(_, _) >> { - numFailedPublish.incrementAndGet() - } - monitor.onSend(_, _, _, _) >> { writer, repCount, sizeInBytes, response -> - numRepSent.addAndGet(repCount) - } - - def writer = new DDAgentWriter(api, monitor) - writer.start() - - when: - def producer = { - (1..100).each { - writer.write(minimalTrace) - } - } as Runnable - - def t1 = new Thread(producer) - t1.start() - - def t2 = new Thread(producer) - t2.start() - - t1.join() - t2.join() - - writer.flush() - - then: - def totalTraces = 100 + 100 - numPublished.get() == totalTraces - numRepSent.get() == totalTraces - - cleanup: - writer.close() - agent.close() - } - - def "statsd success"() { - def numTracesAccepted = 0 - def numRequests = 0 - def numResponses = 0 - - setup: - def minimalTrace = createMinimalTrace() - - // Need to set-up a dummy agent for the final send callback to work - def agent = httpServer { - handlers { - put("v0.4/traces") { - response.status(200).send() - } - } - } - def api = new DDApi("localhost", agent.address.port, null) - - def statsd = Stub(StatsDClient) - statsd.incrementCounter("queue.accepted") >> { stat -> - numTracesAccepted += 1 - } - statsd.incrementCounter("api.requests") >> { stat -> - numRequests += 1 - } - statsd.incrementCounter("api.responses", _) >> { stat, tags -> - numResponses += 1 - } - - def monitor = new DDAgentWriter.StatsDMonitor(statsd) - def writer = new DDAgentWriter(api, monitor) - writer.start() - - when: - writer.write(minimalTrace) - writer.flush() - - then: - numTracesAccepted == 1 - numRequests == 1 - numResponses == 1 - - cleanup: - agent.close() - writer.close() - } - - def "statsd comm failure"() { - def numRequests = 0 - def numResponses = 0 - def numErrors = 0 - - setup: - def minimalTrace = createMinimalTrace() - - // DQH -- need to set-up a dummy agent for the final send callback to work - def api = new DDApi("localhost", 8192, null) { - DDApi.Response sendSerializedTraces( - int representativeCount, - Integer sizeInBytes, - List traces) { - // simulating a communication failure to a server - return DDApi.Response.failed(new IOException("comm error")) - } - } - - def statsd = Stub(StatsDClient) - statsd.incrementCounter("api.requests") >> { stat -> - numRequests += 1 - } - statsd.incrementCounter("api.responses", _) >> { stat, tags -> - numResponses += 1 - } - statsd.incrementCounter("api.errors", _) >> { stat -> - numErrors += 1 - } - - def monitor = new DDAgentWriter.StatsDMonitor(statsd) - def writer = new DDAgentWriter(api, monitor) - writer.start() - - when: - writer.write(minimalTrace) - writer.flush() - - then: - numRequests == 1 - numResponses == 0 - numErrors == 1 - - cleanup: - writer.close() - } -} diff --git a/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/DDApiTest.groovy b/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/DDApiTest.groovy deleted file mode 100644 index 17c8388cd6..0000000000 --- a/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/DDApiTest.groovy +++ /dev/null @@ -1,243 +0,0 @@ -package datadog.trace.api.writer - -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.JsonNode -import datadog.opentracing.SpanFactory -import datadog.trace.common.writer.DDApi -import datadog.trace.common.writer.DDApi.ResponseListener -import datadog.trace.util.test.DDSpecification - -import java.util.concurrent.atomic.AtomicLong -import java.util.concurrent.atomic.AtomicReference - -import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer - -class DDApiTest extends DDSpecification { - static mapper = DDApi.OBJECT_MAPPER - - def "sending an empty list of traces returns no errors"() { - setup: - def agent = httpServer { - handlers { - put("v0.4/traces") { - if (request.contentType != "application/msgpack") { - response.status(400).send("wrong type: $request.contentType") - } else if (request.contentLength <= 0) { - response.status(400).send("no content") - } else { - response.status(200).send() - } - } - } - } - def client = new DDApi("localhost", agent.address.port, null) - - expect: - client.tracesUrl.toString() == "http://localhost:${agent.address.port}/v0.4/traces" - def response = client.sendTraces([]) - response.success() - response.status() == 200 - - cleanup: - agent.close() - } - - def "non-200 response"() { - setup: - def agent = httpServer { - handlers { - put("v0.4/traces") { - response.status(404).send() - } - } - } - def client = new DDApi("localhost", agent.address.port, null) - - expect: - client.tracesUrl.toString() == "http://localhost:${agent.address.port}/v0.3/traces" - - def response = client.sendTraces([]) - !response.success() - response.status() == 404 - - cleanup: - agent.close() - } - - def "content is sent as MSGPACK"() { - setup: - def agent = httpServer { - handlers { - put("v0.4/traces") { - response.send() - } - } - } - def client = new DDApi("localhost", agent.address.port, null) - - expect: - client.tracesUrl.toString() == "http://localhost:${agent.address.port}/v0.4/traces" - client.sendTraces(traces).success() - agent.lastRequest.contentType == "application/msgpack" - agent.lastRequest.headers.get("Datadog-Meta-Lang") == "java" - agent.lastRequest.headers.get("Datadog-Meta-Lang-Version") == System.getProperty("java.version", "unknown") - agent.lastRequest.headers.get("Datadog-Meta-Tracer-Version") == "Stubbed-Test-Version" - agent.lastRequest.headers.get("X-Datadog-Trace-Count") == "${traces.size()}" - convertList(agent.lastRequest.body) == expectedRequestBody - - cleanup: - agent.close() - - // Populate thread info dynamically as it is different when run via gradle vs idea. - where: - traces | expectedRequestBody - [] | [] - [[SpanFactory.newSpanOf(1L).setTag("service.name", "my-service")]] | [[new TreeMap<>([ - "duration" : 0, - "error" : 0, - "meta" : ["thread.name": Thread.currentThread().getName(), "thread.id": "${Thread.currentThread().id}"], - "metrics" : [:], - "name" : "fakeOperation", - "parent_id": 0, - "resource" : "fakeResource", - "service" : "my-service", - "span_id" : 1, - "start" : 1000, - "trace_id" : 1, - "type" : "fakeType" - ])]] - [[SpanFactory.newSpanOf(100L).setTag("resource.name", "my-resource")]] | [[new TreeMap<>([ - "duration" : 0, - "error" : 0, - "meta" : ["thread.name": Thread.currentThread().getName(), "thread.id": "${Thread.currentThread().id}"], - "metrics" : [:], - "name" : "fakeOperation", - "parent_id": 0, - "resource" : "my-resource", - "service" : "fakeService", - "span_id" : 1, - "start" : 100000, - "trace_id" : 1, - "type" : "fakeType" - ])]] - } - - def "Api ResponseListeners see 200 responses"() { - setup: - def agentResponse = new AtomicReference(null) - ResponseListener responseListener = { String endpoint, JsonNode responseJson -> - agentResponse.set(responseJson.toString()) - } - def agent = httpServer { - handlers { - put("v0.4/traces") { - def status = request.contentLength > 0 ? 200 : 500 - response.status(status).send('{"hello":"test"}') - } - } - } - def client = new DDApi("localhost", agent.address.port, null) - client.addResponseListener(responseListener) - - when: - client.sendTraces([[], [], []]) - then: - agentResponse.get() == '{"hello":"test"}' - agent.lastRequest.headers.get("Datadog-Meta-Lang") == "java" - agent.lastRequest.headers.get("Datadog-Meta-Lang-Version") == System.getProperty("java.version", "unknown") - agent.lastRequest.headers.get("Datadog-Meta-Tracer-Version") == "Stubbed-Test-Version" - agent.lastRequest.headers.get("X-Datadog-Trace-Count") == "3" // false data shows the value provided via traceCounter. - - cleanup: - agent.close() - } - - def "Api Downgrades to v3 if v0.4 not available"() { - setup: - def v3Agent = httpServer { - handlers { - put("v0.3/traces") { - def status = request.contentLength > 0 ? 200 : 500 - response.status(status).send() - } - } - } - def client = new DDApi("localhost", v3Agent.address.port, null) - - expect: - client.tracesUrl.toString() == "http://localhost:${v3Agent.address.port}/v0.3/traces" - client.sendTraces([]).success() - - cleanup: - v3Agent.close() - } - - def "Api Downgrades to v3 if timeout exceeded (#delayTrace, #badPort)"() { - // This test is unfortunately only exercising the read timeout, not the connect timeout. - setup: - def agent = httpServer { - handlers { - put("v0.3/traces") { - def status = request.contentLength > 0 ? 200 : 500 - response.status(status).send() - } - put("v0.4/traces") { - Thread.sleep(delayTrace) - def status = request.contentLength > 0 ? 200 : 500 - response.status(status).send() - } - } - } - def port = badPort ? 999 : agent.address.port - def client = new DDApi("localhost", port, null) - - expect: - client.tracesUrl.toString() == "http://localhost:${port}/$endpointVersion/traces" - - cleanup: - agent.close() - - where: - endpointVersion | delayTrace | badPort - "v0.4" | 0 | false - "v0.3" | 0 | true - "v0.4" | 500 | false - "v0.3" | 30000 | false - } - - def "verify content length"() { - setup: - def receivedContentLength = new AtomicLong() - def agent = httpServer { - handlers { - put("v0.4/traces") { - receivedContentLength.set(request.contentLength) - response.status(200).send() - } - } - } - def client = new DDApi("localhost", agent.address.port, null) - - when: - def success = client.sendTraces(traces).success() - then: - success - receivedContentLength.get() == expectedLength - - cleanup: - agent.close() - - where: - expectedLength | traces - 1 | [] - 3 | [[], []] - 16 | (1..15).collect { [] } - 19 | (1..16).collect { [] } - 65538 | (1..((1 << 16) - 1)).collect { [] } - 65541 | (1..(1 << 16)).collect { [] } - } - - static List>> convertList(byte[] bytes) { - return mapper.readValue(bytes, new TypeReference>>>() {}) - } -} diff --git a/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/SerializationTest.groovy b/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/SerializationTest.groovy deleted file mode 100644 index fde8855175..0000000000 --- a/dd-trace-ot/src/test/groovy/datadog/trace/api/writer/SerializationTest.groovy +++ /dev/null @@ -1,61 +0,0 @@ -package datadog.trace.api.writer - -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.ObjectMapper -import datadog.trace.util.test.DDSpecification -import org.msgpack.core.MessagePack -import org.msgpack.jackson.dataformat.MessagePackFactory -import spock.lang.Shared - -import static java.util.Collections.singletonMap - -class SerializationTest extends DDSpecification { - @Shared - def jsonMapper = new ObjectMapper() - @Shared - def mpMapper = new ObjectMapper(new MessagePackFactory()) - - - def "test json mapper serialization"() { - setup: - def map = ["key1": "val1"] - def serializedMap = mapper.writeValueAsBytes(map) - def serializedList = "[${new String(serializedMap)}]".getBytes() - - when: - def result = mapper.readValue(serializedList, new TypeReference>>() {}) - - then: - result == [map] - new String(serializedList) == '[{"key1":"val1"}]' - - where: - mapper = jsonMapper - } - - def "test msgpack mapper serialization"() { - setup: - def serializedMaps = input.collect { - mapper.writeValueAsBytes(it) - } - - def packer = MessagePack.newDefaultBufferPacker() - packer.packArrayHeader(serializedMaps.size()) - serializedMaps.each { - packer.writePayload(it) - } - def serializedList = packer.toByteArray() - - when: - def result = mapper.readValue(serializedList, new TypeReference>>() {}) - - then: - result == input - - where: - mapper = mpMapper - - // GStrings get odd results in the serializer. - input = (1..1).collect { singletonMap("key$it".toString(), "val$it".toString()) } - } -} diff --git a/dd-trace-ot/src/traceAgentTest/groovy/DDApiIntegrationTest.groovy b/dd-trace-ot/src/traceAgentTest/groovy/DDApiIntegrationTest.groovy deleted file mode 100644 index 8e42686e76..0000000000 --- a/dd-trace-ot/src/traceAgentTest/groovy/DDApiIntegrationTest.groovy +++ /dev/null @@ -1,170 +0,0 @@ -import com.fasterxml.jackson.databind.JsonNode -import datadog.opentracing.DDSpan -import datadog.opentracing.DDSpanContext -import datadog.opentracing.DDTracer -import datadog.opentracing.PendingTrace -import datadog.trace.common.writer.DDApi -import datadog.trace.common.writer.ListWriter -import datadog.trace.util.test.DDSpecification -import org.testcontainers.containers.GenericContainer -import org.testcontainers.containers.startupcheck.MinimumDurationRunningStartupCheckStrategy -import spock.lang.Requires -import spock.lang.Shared - -import java.time.Duration -import java.util.concurrent.TimeUnit -import java.util.concurrent.atomic.AtomicReference - -class DDApiIntegrationTest { - // Do not run tests locally on Java7 since testcontainers are not compatible with Java7 - // It is fine to run on CI because CI provides rabbitmq externally, not through testcontainers - @Requires({ "true" == System.getenv("CI") || jvm.java8Compatible }) - static class DDApiIntegrationV4Test extends DDSpecification { - static final WRITER = new ListWriter() - static final TRACER = new DDTracer(WRITER) - static final CONTEXT = new DDSpanContext( - 1G, - 1G, - 0G, - "fakeService", - "fakeOperation", - "fakeResource", - null, - Collections.emptyMap(), - false, - "fakeType", - Collections.emptyMap(), - new PendingTrace(TRACER, 1G), - TRACER) - - // Looks like okHttp needs to resolve this, even for connection over socket - static final SOMEHOST = "datadoghq.com" - static final SOMEPORT = 123 - - /* - Note: type here has to stay undefined, otherwise tests will fail in CI in Java 7 because - 'testcontainers' are built for Java 8 and Java 7 cannot load this class. - */ - @Shared - def agentContainer - @Shared - def agentContainerHost = "localhost" - @Shared - def agentContainerPort = 8126 - @Shared - Process process - @Shared - File socketPath - - def api - def unixDomainSocketApi - - def endpoint = new AtomicReference(null) - def agentResponse = new AtomicReference(null) - - DDApi.ResponseListener responseListener = { String receivedEndpoint, JsonNode responseJson -> - endpoint.set(receivedEndpoint) - agentResponse.set(responseJson.toString()) - } - - def setupSpec() { - - /* - CI will provide us with rabbitmq container running along side our build. - When building locally, however, we need to take matters into our own hands - and we use 'testcontainers' for this. - */ - if ("true" != System.getenv("CI")) { - agentContainer = new GenericContainer("datadog/docker-dd-agent:latest") - .withEnv(["DD_APM_ENABLED": "true", - "DD_BIND_HOST" : "0.0.0.0", - "DD_API_KEY" : "invalid_key_but_this_is_fine", - "DD_LOGS_STDOUT": "yes"]) - .withExposedPorts(datadog.trace.api.Config.DEFAULT_TRACE_AGENT_PORT) - .withStartupTimeout(Duration.ofSeconds(120)) - // Apparently we need to sleep for a bit so agent's response `{"service:,env:":1}` in rate_by_service. - // This is clearly a race-condition and maybe we should av oid verifying complete response - .withStartupCheckStrategy(new MinimumDurationRunningStartupCheckStrategy(Duration.ofSeconds(10))) - // .withLogConsumer { output -> - // print output.utf8String - // } - agentContainer.start() - agentContainerHost = agentContainer.containerIpAddress - agentContainerPort = agentContainer.getMappedPort(datadog.trace.api.Config.DEFAULT_TRACE_AGENT_PORT) - } - - File tmpDir = File.createTempDir() - tmpDir.deleteOnExit() - socketPath = new File(tmpDir, "socket") - process = Runtime.getRuntime().exec("socat UNIX-LISTEN:${socketPath},reuseaddr,fork TCP-CONNECT:${agentContainerHost}:${agentContainerPort}") - } - - def cleanupSpec() { - if (agentContainer) { - agentContainer.stop() - } - process.destroy() - } - - def setup() { - api = new DDApi(agentContainerHost, agentContainerPort, v4(), null) - api.addResponseListener(responseListener) - - unixDomainSocketApi = new DDApi(SOMEHOST, SOMEPORT, v4(), socketPath.toString()) - unixDomainSocketApi.addResponseListener(responseListener) - } - - boolean v4() { - return true - } - - def "Sending traces succeeds (test #test)"() { - expect: - api.sendTraces(traces) - if (v4()) { - assert endpoint.get() == "http://${agentContainerHost}:${agentContainerPort}/v0.4/traces" - assert agentResponse.get() == '{"rate_by_service":{"service:,env:":1}}' - } - - where: - traces | test - [] | 1 - [[], []] | 2 - [[new DDSpan(1, CONTEXT)]] | 3 - [[new DDSpan(TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis()), CONTEXT)]] | 4 - (1..15).collect { [] } | 5 - (1..16).collect { [] } | 6 - // Larger traces take more than 1 second to send to the agent and get a timeout exception: -// (1..((1 << 16) - 1)).collect { [] } | 7 -// (1..(1 << 16)).collect { [] } | 8 - } - - def "Sending traces to unix domain socket succeeds (test #test)"() { - expect: - unixDomainSocketApi.sendTraces(traces) - if (v4()) { - assert endpoint.get() == "http://${SOMEHOST}:${SOMEPORT}/v0.4/traces" - assert agentResponse.get() == '{"rate_by_service":{"service:,env:":1}}' - } - - where: - traces | test - [] | 1 - [[], []] | 2 - [[new DDSpan(1, CONTEXT)]] | 3 - [[new DDSpan(TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis()), CONTEXT)]] | 4 - } - } - - @Requires({ "true" == System.getenv("CI") || jvm.java8Compatible }) - static class DDApiIntegrationV3Test extends DDApiIntegrationV4Test { - boolean v4() { - return false - } - - def cleanup() { - assert endpoint.get() == null - assert agentResponse.get() == null - } - } -} diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 656bd10f0a..5770c22103 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -8,8 +8,6 @@ ext { slf4j : "1.7.29", guava : "20.0", // Last version to support Java 7 - jackson : "2.10.0", // https://nvd.nist.gov/vuln/detail/CVE-2019-16942 et al - spock : "1.3-groovy-$spockGroovyVer", groovy : groovyVer, logback : "1.2.3", @@ -33,10 +31,6 @@ ext { // General slf4j : "org.slf4j:slf4j-api:${versions.slf4j}", guava : "com.google.guava:guava:$versions.guava", - jackson : [ - dependencies.create(group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: versions.jackson), - dependencies.create(group: 'org.msgpack', name: 'jackson-dataformat-msgpack', version: '0.8.18'), - ], bytebuddy : dependencies.create(group: 'net.bytebuddy', name: 'byte-buddy', version: "${versions.bytebuddy}"), bytebuddyagent : dependencies.create(group: 'net.bytebuddy', name: 'byte-buddy-agent', version: "${versions.bytebuddy}"), autoservice : [