From 2b5c3e64285af2311280c7e81debb43fa85fabbe Mon Sep 17 00:00:00 2001 From: Caleb Gilmour Date: Fri, 12 Oct 2018 04:17:03 +0000 Subject: [PATCH 01/15] tracing: add datadog extension Signed-off-by: Caleb Gilmour --- api/envoy/config/trace/v2/trace.proto | 8 + bazel/external/BUILD | 1 + bazel/repositories.bzl | 12 ++ bazel/repository_locations.bzl | 8 + source/extensions/extensions_build_config.bzl | 1 + source/extensions/tracers/datadog/BUILD | 37 ++++ source/extensions/tracers/datadog/config.cc | 48 +++++ source/extensions/tracers/datadog/config.h | 33 ++++ .../tracers/datadog/datadog_tracer_impl.cc | 125 +++++++++++++ .../tracers/datadog/datadog_tracer_impl.h | 131 ++++++++++++++ source/extensions/tracers/well_known_names.h | 2 + test/extensions/tracers/datadog/BUILD | 48 +++++ .../extensions/tracers/datadog/config_test.cc | 43 +++++ .../datadog/datadog_tracer_impl_test.cc | 169 ++++++++++++++++++ 14 files changed, 666 insertions(+) create mode 100644 source/extensions/tracers/datadog/BUILD create mode 100644 source/extensions/tracers/datadog/config.cc create mode 100644 source/extensions/tracers/datadog/config.h create mode 100644 source/extensions/tracers/datadog/datadog_tracer_impl.cc create mode 100644 source/extensions/tracers/datadog/datadog_tracer_impl.h create mode 100644 test/extensions/tracers/datadog/BUILD create mode 100644 test/extensions/tracers/datadog/config_test.cc create mode 100644 test/extensions/tracers/datadog/datadog_tracer_impl_test.cc diff --git a/api/envoy/config/trace/v2/trace.proto b/api/envoy/config/trace/v2/trace.proto index 376948bb3084b..a7c543e8837b4 100644 --- a/api/envoy/config/trace/v2/trace.proto +++ b/api/envoy/config/trace/v2/trace.proto @@ -80,6 +80,14 @@ message DynamicOtConfig { google.protobuf.Struct config = 2; } +// Configuration for the Datadog tracer. +message DatadogConfig { + // The cluster to use for submitting traces to the Datadog agent. + string collector_cluster = 1 [(validate.rules).string.min_bytes = 1]; + string service_name = 2 [(validate.rules).string.min_bytes = 1]; + bool priority_sampling = 3; +} + // Configuration structure. message TraceServiceConfig { // The upstream gRPC cluster that hosts the metrics service. diff --git a/bazel/external/BUILD b/bazel/external/BUILD index 63a81dd5e12b1..f2111ab6b8843 100644 --- a/bazel/external/BUILD +++ b/bazel/external/BUILD @@ -6,6 +6,7 @@ cc_library( deps = [ "@com_google_googletest//:gtest", "@com_lightstep_tracer_cpp//:lightstep_tracer", + "@com_github_datadog_dd_opentracing_cpp//:dd_opentracing_cpp", "@io_opentracing_cpp//:opentracing", ], ) diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index a62bde82cc821..b594207ff1fce 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -311,6 +311,7 @@ def envoy_dependencies(path = "@envoy_deps//", skip_targets = []): _com_github_google_libprotobuf_mutator() _io_opentracing_cpp() _com_lightstep_tracer_cpp() + _com_github_datadog_dd_opentracing_cpp() _com_github_grpc_grpc() _com_github_google_jwt_verify() _com_github_nanopb_nanopb() @@ -432,6 +433,17 @@ def _com_lightstep_tracer_cpp(): actual = "@com_lightstep_tracer_cpp//:lightstep_tracer", ) +def _com_github_datadog_dd_opentracing_cpp(): + _repository_impl("com_github_datadog_dd_opentracing_cpp") + _repository_impl( + name = "com_github_msgpack_msgpack_c", + build_file = "@com_github_datadog_dd_opentracing_cpp//:bazel/external/msgpack.BUILD", + ) + native.bind( + name = "dd_opentracing_cpp", + actual = "@com_github_datadog_dd_opentracing_cpp//:dd_opentracing_cpp", + ) + def _com_github_tencent_rapidjson(): _repository_impl( name = "com_github_tencent_rapidjson", diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index 047f443a738eb..c6645b3e9fc36 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -82,6 +82,14 @@ REPOSITORY_LOCATIONS = dict( commit = "d6f78d948c53f3b400bb46996eb3084359914f9b", remote = "https://github.com/google/googleapis", ), + com_github_datadog_dd_opentracing_cpp = dict( + commit = "92d7ee11f61361ca23e00b48d328fb4e494534c4", # v0.3.1 + remote = "https://github.com/DataDog/dd-opentracing-cpp", + ), + com_github_msgpack_msgpack_c = dict( + commit = "83a82e3eb512b18d4149cabb7eb43c7e8bc081af", + remote = "https://github.com/msgpack/msgpack-c", # v3.1.1 + ), com_github_google_jwt_verify = dict( commit = "66792a057ec54e4b75c6a2eeda4e98220bd12a9a", # 2018-08-17 remote = "https://github.com/google/jwt_verify_lib", diff --git a/source/extensions/extensions_build_config.bzl b/source/extensions/extensions_build_config.bzl index d18bfd70061a5..08e14ffe98e57 100644 --- a/source/extensions/extensions_build_config.bzl +++ b/source/extensions/extensions_build_config.bzl @@ -100,6 +100,7 @@ EXTENSIONS = { "envoy.tracers.dynamic_ot": "//source/extensions/tracers/dynamic_ot:config", "envoy.tracers.lightstep": "//source/extensions/tracers/lightstep:config", + "envoy.tracers.datadog": "//source/extensions/tracers/datadog:config", "envoy.tracers.zipkin": "//source/extensions/tracers/zipkin:config", # diff --git a/source/extensions/tracers/datadog/BUILD b/source/extensions/tracers/datadog/BUILD new file mode 100644 index 0000000000000..e4ac3d95ba415 --- /dev/null +++ b/source/extensions/tracers/datadog/BUILD @@ -0,0 +1,37 @@ +licenses(["notice"]) # Apache 2 + +# Trace driver for Datadog (https://datadoghq.com/) + +load( + "//bazel:envoy_build_system.bzl", + "envoy_cc_library", + "envoy_package", +) + +envoy_package() + +envoy_cc_library( + name = "datadog_tracer_lib", + srcs = [ + "datadog_tracer_impl.cc", + ], + hdrs = [ + "datadog_tracer_impl.h", + ], + external_deps = ["dd_opentracing_cpp"], + deps = [ + "//source/common/tracing:http_tracer_lib", + "//source/extensions/tracers/common/ot:opentracing_driver_lib", + ], +) + +envoy_cc_library( + name = "config", + srcs = ["config.cc"], + hdrs = ["config.h"], + deps = [ + ":datadog_tracer_lib", + "//source/extensions/tracers:well_known_names", + "//source/server:configuration_lib", + ], +) diff --git a/source/extensions/tracers/datadog/config.cc b/source/extensions/tracers/datadog/config.cc new file mode 100644 index 0000000000000..2062f94d6958d --- /dev/null +++ b/source/extensions/tracers/datadog/config.cc @@ -0,0 +1,48 @@ +#include "extensions/tracers/datadog/config.h" + +#include "envoy/registry/registry.h" + +#include "common/common/utility.h" +#include "common/tracing/http_tracer_impl.h" + +#include "extensions/tracers/datadog/datadog_tracer_impl.h" +#include "extensions/tracers/well_known_names.h" + +#include "datadog/opentracing.h" + +namespace Envoy { +namespace Extensions { +namespace Tracers { +namespace Datadog { + +Tracing::HttpTracerPtr +DatadogTracerFactory::createHttpTracer(const envoy::config::trace::v2::Tracing& configuration, + Server::Instance& server) { + + ProtobufTypes::MessagePtr config_ptr = createEmptyConfigProto(); + + if (configuration.http().has_config()) { + MessageUtil::jsonConvert(configuration.http().config(), *config_ptr); + } + + const auto& datadog_config = + dynamic_cast(*config_ptr); + + Tracing::DriverPtr datadog_driver{new Driver{datadog_config, server.clusterManager(), + server.stats(), server.threadLocal(), + server.runtime()}}; + return std::make_unique(std::move(datadog_driver), server.localInfo()); +} + +std::string DatadogTracerFactory::name() { return TracerNames::get().Datadog; } + +/** + * Static registration for the Datadog tracer. @see RegisterFactory. + */ +static Registry::RegisterFactory + register_; + +} // namespace Datadog +} // namespace Tracers +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/tracers/datadog/config.h b/source/extensions/tracers/datadog/config.h new file mode 100644 index 0000000000000..a257faf8c6f94 --- /dev/null +++ b/source/extensions/tracers/datadog/config.h @@ -0,0 +1,33 @@ +#pragma once + +#include + +#include "envoy/server/instance.h" + +#include "server/configuration_impl.h" + +namespace Envoy { +namespace Extensions { +namespace Tracers { +namespace Datadog { + +/** + * Config registration for the Datadog tracer. @see TracerFactory. + */ +class DatadogTracerFactory : public Server::Configuration::TracerFactory { +public: + // TracerFactory + Tracing::HttpTracerPtr createHttpTracer(const envoy::config::trace::v2::Tracing& configuration, + Server::Instance& server) override; + + ProtobufTypes::MessagePtr createEmptyConfigProto() override { + return std::make_unique(); + } + + std::string name() override; +}; + +} // namespace Datadog +} // namespace Tracers +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/tracers/datadog/datadog_tracer_impl.cc b/source/extensions/tracers/datadog/datadog_tracer_impl.cc new file mode 100644 index 0000000000000..c68bcd3823d72 --- /dev/null +++ b/source/extensions/tracers/datadog/datadog_tracer_impl.cc @@ -0,0 +1,125 @@ +#include "extensions/tracers/datadog/datadog_tracer_impl.h" + +#include "common/common/enum_to_int.h" +#include "common/common/fmt.h" +#include "common/common/utility.h" +#include "common/http/headers.h" +#include "common/http/message_impl.h" +#include "common/http/utility.h" +#include "common/tracing/http_tracer_impl.h" + +namespace Envoy { +namespace Extensions { +namespace Tracers { +namespace Datadog { + +Driver::TlsTracer::TlsTracer(const std::shared_ptr& tracer, + TraceReporterPtr&& reporter, Driver& driver) + : tracer_(tracer), reporter_(std::move(reporter)), driver_(driver) {} + +Driver::Driver(const envoy::config::trace::v2::DatadogConfig& datadog_config, + Upstream::ClusterManager& cluster_manager, Stats::Store& stats, + ThreadLocal::SlotAllocator& tls, Runtime::Loader& runtime) + : OpenTracingDriver{stats}, + cm_(cluster_manager), tracer_stats_{DATADOG_TRACER_STATS( + POOL_COUNTER_PREFIX(stats, "tracing.datadog."))}, + tls_(tls.allocateSlot()), runtime_(runtime) { + + Upstream::ThreadLocalCluster* cluster = cm_.get(datadog_config.collector_cluster()); + if (!cluster) { + throw EnvoyException(fmt::format("{} collector cluster is not defined on cluster manager level", + datadog_config.collector_cluster())); + } + cluster_ = cluster->info(); + + tracer_options_.operation_name_override = "envoy.proxy"; + if (datadog_config.service_name().size() > 0) { + tracer_options_.service = datadog_config.service_name(); + } else { + tracer_options_.service = "envoy"; + } + tracer_options_.priority_sampling = datadog_config.priority_sampling(); + + tls_->set([this](Event::Dispatcher& dispatcher) -> ThreadLocal::ThreadLocalObjectSharedPtr { + auto tp = datadog::opentracing::makeTracerAndEncoder(tracer_options_); + auto tracer = std::get<0>(tp); + auto encoder = std::get<1>(tp); + TraceReporterPtr reporter(new TraceReporter(encoder, *this, dispatcher)); + return ThreadLocal::ThreadLocalObjectSharedPtr{ + new TlsTracer(tracer, std::move(reporter), *this)}; + }); +} + +opentracing::Tracer& Driver::tracer() { return *tls_->getTyped().tracer_; } + +TraceReporter::TraceReporter(TraceEncoderPtr encoder, Driver& driver, Event::Dispatcher& dispatcher) + : driver_(driver), encoder_(encoder) { + flush_timer_ = dispatcher.createTimer([this]() -> void { + driver_.tracerStats().timer_flushed_.inc(); + flushTraces(); + enableTimer(); + }); + + enableTimer(); +} + +void TraceReporter::enableTimer() { + const uint64_t flush_interval = + driver_.runtime().snapshot().getInteger("tracing.datadog.flush_interval_ms", 1000U); + flush_timer_->enableTimer(std::chrono::milliseconds(flush_interval)); +} + +void TraceReporter::flushTraces() { + auto pendingTraces = encoder_->pendingTraces(); + ENVOY_LOG(debug, "flushing traces: {} traces", pendingTraces); + if (pendingTraces) { + driver_.tracerStats().traces_sent_.add(pendingTraces); + + Http::MessagePtr message(new Http::RequestMessageImpl()); + message->headers().insertMethod().value().setReference(Http::Headers::get().MethodValues.Post); + message->headers().insertPath().value(encoder_->path()); + message->headers().insertHost().value(driver_.cluster()->name()); + for (auto& h : encoder_->headers()) { + ENVOY_LOG(debug, "Adding header {}: {}", h.first, h.second); + message->headers().addCopy(Http::LowerCaseString(h.first), h.second); + } + + Buffer::InstancePtr body(new Buffer::OwnedImpl()); + body->add(encoder_->payload()); + message->body() = std::move(body); + ENVOY_LOG(debug, "submitting {} trace(s) to {} with payload {}", pendingTraces, + encoder_->path(), encoder_->payload().size()); + + const uint64_t timeout = + driver_.runtime().snapshot().getInteger("tracing.datadog.request_timeout", 1000U); + driver_.clusterManager() + .httpAsyncClientForCluster(driver_.cluster()->name()) + .send(std::move(message), *this, std::chrono::milliseconds(timeout)); + + encoder_->clearTraces(); + } +} + +void TraceReporter::onFailure(Http::AsyncClient::FailureReason) { + ENVOY_LOG(debug, "failure submitting traces to datadog agent"); + driver_.tracerStats().reports_failed_.inc(); +} + +void TraceReporter::onSuccess(Http::MessagePtr&& http_response) { + uint64_t responseStatus = Http::Utility::getResponseStatus(http_response->headers()); + if (responseStatus != enumToInt(Http::Code::OK)) { + ENVOY_LOG(debug, "unexpected HTTP response code from datadog agent: {}", responseStatus); + driver_.tracerStats().reports_dropped_.inc(); + if (driver_.tracerOptions().priority_sampling) { + encoder_->handleResponse(http_response->body()->toString()); + } + } else { + ENVOY_LOG(debug, "traces successfully submitted to datadog agent"); + driver_.tracerStats().reports_sent_.inc(); + } +} + +} // namespace Datadog +} // namespace Tracers +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/tracers/datadog/datadog_tracer_impl.h b/source/extensions/tracers/datadog/datadog_tracer_impl.h new file mode 100644 index 0000000000000..20395f24e7e11 --- /dev/null +++ b/source/extensions/tracers/datadog/datadog_tracer_impl.h @@ -0,0 +1,131 @@ +#pragma once + +#include + +#include "envoy/local_info/local_info.h" +#include "envoy/runtime/runtime.h" +#include "envoy/thread_local/thread_local.h" +#include "envoy/tracing/http_tracer.h" +#include "envoy/upstream/cluster_manager.h" + +#include "common/http/header_map_impl.h" +#include "common/json/json_loader.h" + +#include "extensions/tracers/common/ot/opentracing_driver_impl.h" + +namespace Envoy { +namespace Extensions { +namespace Tracers { +namespace Datadog { + +#define DATADOG_TRACER_STATS(COUNTER) \ + COUNTER(traces_sent) \ + COUNTER(timer_flushed) \ + COUNTER(reports_sent) \ + COUNTER(reports_dropped) \ + COUNTER(reports_failed) + +struct DatadogTracerStats { + DATADOG_TRACER_STATS(GENERATE_COUNTER_STRUCT) +}; + +class TraceReporter; +typedef std::unique_ptr TraceReporterPtr; +typedef std::shared_ptr TraceEncoderPtr; + +/** + * Class for a Datadog-specific Driver. + */ +class Driver : public Common::Ot::OpenTracingDriver { +public: + /** + * Constructor. It adds itself and a newly-created Datadog::Tracer object to a thread-local store. + */ + Driver(const envoy::config::trace::v2::DatadogConfig& datadog_config, + Upstream::ClusterManager& cluster_manager, Stats::Store& stats, + ThreadLocal::SlotAllocator& tls, Runtime::Loader& runtime); + + // Tracer::OpenTracingDriver + opentracing::Tracer& tracer() override; + PropagationMode propagationMode() const override { + return Common::Ot::OpenTracingDriver::PropagationMode::TracerNative; + } + + // Getters to return the DatadogDriver's key members. + Upstream::ClusterManager& clusterManager() { return cm_; } + Upstream::ClusterInfoConstSharedPtr cluster() { return cluster_; } + Runtime::Loader& runtime() { return runtime_; } + DatadogTracerStats& tracerStats() { return tracer_stats_; } + const datadog::opentracing::TracerOptions& tracerOptions() { return tracer_options_; } + +private: + /** + * Thread-local store containing DatadogDriver and Datadog::Tracer objects. + */ + struct TlsTracer : ThreadLocal::ThreadLocalObject { + TlsTracer(const std::shared_ptr& tracer, TraceReporterPtr&& reporter, + Driver& driver); + + std::shared_ptr tracer_; + TraceReporterPtr reporter_; + Driver& driver_; + }; + + Upstream::ClusterManager& cm_; + Upstream::ClusterInfoConstSharedPtr cluster_; + DatadogTracerStats tracer_stats_; + datadog::opentracing::TracerOptions tracer_options_; + ThreadLocal::SlotPtr tls_; + Runtime::Loader& runtime_; +}; + +/** + * This class wraps the encoder provided with the tracer at initialization + * and uses Http::AsyncClient to send completed traces to the Datadog Agent. + * + * The cluster to use for submitting traces to the agent is controlled with + * the setting tracing.datadog.collector_cluster, which is mandatory and must + * refer to a cluster in the active configuration. + * + * An internal timer is used to control how often traces are submitted. + * If zero traces have completed in the interval between timer events, + * no action is taken. + * The timer interval can be controlled with the setting + * tracing.datadog.flush_interval_ms, and defaults to 2000ms. + */ +class TraceReporter : public Http::AsyncClient::Callbacks, + protected Logger::Loggable { +public: + /** + * Constructor. + * + * @param encoder Provides methods to retrieve data for publishing traces. + * @param driver The driver to be associated with the reporter. + * @param dispatcher Controls the timer used to flush buffered traces. + */ + TraceReporter(TraceEncoderPtr encoder, Driver& driver, Event::Dispatcher& dispatcher); + + // Http::AsyncClient::Callbacks. + void onSuccess(Http::MessagePtr&&) override; + void onFailure(Http::AsyncClient::FailureReason) override; + +private: + /** + * Enables the trace-flushing timer. + */ + void enableTimer(); + + /** + * Removes all traces from the trace buffer and sends them to a Datadog Agent using + * Http::AsyncClient. + */ + void flushTraces(); + + Driver& driver_; + Event::TimerPtr flush_timer_; + TraceEncoderPtr encoder_; +}; +} // namespace Datadog +} // namespace Tracers +} // namespace Extensions +} // namespace Envoy diff --git a/source/extensions/tracers/well_known_names.h b/source/extensions/tracers/well_known_names.h index d545eecedad97..43f1181d572d9 100644 --- a/source/extensions/tracers/well_known_names.h +++ b/source/extensions/tracers/well_known_names.h @@ -18,6 +18,8 @@ class TracerNameValues { const std::string Zipkin = "envoy.zipkin"; // Dynamic tracer const std::string DynamicOt = "envoy.dynamic.ot"; + // Datadog tracer + const std::string Datadog = "envoy.tracers.datadog"; }; typedef ConstSingleton TracerNames; diff --git a/test/extensions/tracers/datadog/BUILD b/test/extensions/tracers/datadog/BUILD new file mode 100644 index 0000000000000..714c3091bad41 --- /dev/null +++ b/test/extensions/tracers/datadog/BUILD @@ -0,0 +1,48 @@ +licenses(["notice"]) # Apache 2 + +load( + "//bazel:envoy_build_system.bzl", + "envoy_package", +) +load( + "//test/extensions:extensions_build_system.bzl", + "envoy_extension_cc_test", +) + +envoy_package() + +envoy_extension_cc_test( + name = "datadog_tracer_impl_test", + srcs = [ + "datadog_tracer_impl_test.cc", + ], + extension_name = "envoy.tracers.datadog", + deps = [ + "//source/common/common:base64_lib", + "//source/common/http:header_map_lib", + "//source/common/http:headers_lib", + "//source/common/http:message_lib", + "//source/common/runtime:runtime_lib", + "//source/common/runtime:uuid_util_lib", + "//source/extensions/tracers/datadog:datadog_tracer_lib", + "//test/mocks/http:http_mocks", + "//test/mocks/local_info:local_info_mocks", + "//test/mocks/runtime:runtime_mocks", + "//test/mocks/stats:stats_mocks", + "//test/mocks/thread_local:thread_local_mocks", + "//test/mocks/tracing:tracing_mocks", + "//test/mocks/upstream:upstream_mocks", + "//test/test_common:utility_lib", + ], +) + +envoy_extension_cc_test( + name = "config_test", + srcs = ["config_test.cc"], + extension_name = "envoy.tracers.datadog", + deps = [ + "//source/extensions/tracers/datadog:config", + "//test/mocks/server:server_mocks", + "//test/test_common:utility_lib", + ], +) diff --git a/test/extensions/tracers/datadog/config_test.cc b/test/extensions/tracers/datadog/config_test.cc new file mode 100644 index 0000000000000..7a5bec96dac5f --- /dev/null +++ b/test/extensions/tracers/datadog/config_test.cc @@ -0,0 +1,43 @@ +#include "extensions/tracers/datadog/config.h" + +#include "test/mocks/server/mocks.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using testing::_; +using testing::NiceMock; +using testing::Return; + +namespace Envoy { +namespace Extensions { +namespace Tracers { +namespace Datadog { + +TEST(DatadogTracerConfigTest, DatadogHttpTracer) { + NiceMock server; + EXPECT_CALL(server.cluster_manager_, get("fake_cluster")) + .WillRepeatedly(Return(&server.cluster_manager_.thread_local_cluster_)); + ON_CALL(*server.cluster_manager_.thread_local_cluster_.cluster_.info_, features()) + .WillByDefault(Return(Upstream::ClusterInfo::Features::HTTP2)); + + const std::string yaml_string = R"EOF( + http: + name: envoy.tracers.datadog + config: + collector_cluster: fake_cluster + service_name: fake_file + priority_sampling: true + )EOF"; + envoy::config::trace::v2::Tracing configuration; + MessageUtil::loadFromYaml(yaml_string, configuration); + + DatadogTracerFactory factory; + Tracing::HttpTracerPtr datadog_tracer = factory.createHttpTracer(configuration, server); + EXPECT_NE(nullptr, datadog_tracer); +} + +} // namespace Datadog +} // namespace Tracers +} // namespace Extensions +} // namespace Envoy diff --git a/test/extensions/tracers/datadog/datadog_tracer_impl_test.cc b/test/extensions/tracers/datadog/datadog_tracer_impl_test.cc new file mode 100644 index 0000000000000..0f5b1b75312fb --- /dev/null +++ b/test/extensions/tracers/datadog/datadog_tracer_impl_test.cc @@ -0,0 +1,169 @@ +#include +#include +#include +#include + +#include "common/common/base64.h" +#include "common/http/header_map_impl.h" +#include "common/http/headers.h" +#include "common/http/message_impl.h" +#include "common/runtime/runtime_impl.h" +#include "common/runtime/uuid_util.h" +#include "common/tracing/http_tracer_impl.h" + +#include "extensions/tracers/datadog/datadog_tracer_impl.h" + +#include "test/mocks/http/mocks.h" +#include "test/mocks/local_info/mocks.h" +#include "test/mocks/runtime/mocks.h" +#include "test/mocks/stats/mocks.h" +#include "test/mocks/thread_local/mocks.h" +#include "test/mocks/tracing/mocks.h" +#include "test/mocks/upstream/mocks.h" +#include "test/test_common/printers.h" +#include "test/test_common/utility.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using testing::_; +using testing::AtLeast; +using testing::Invoke; +using testing::NiceMock; +using testing::Return; +using testing::ReturnRef; +using testing::Test; + +namespace Envoy { +namespace Extensions { +namespace Tracers { +namespace Datadog { + +class DatadogDriverTest : public Test { +public: + void setup(envoy::config::trace::v2::DatadogConfig& datadog_config, bool init_timer) { + ON_CALL(cm_, httpAsyncClientForCluster("fake_cluster")) + .WillByDefault(ReturnRef(cm_.async_client_)); + + if (init_timer) { + timer_ = new NiceMock(&tls_.dispatcher_); + EXPECT_CALL(*timer_, enableTimer(std::chrono::milliseconds(1000))); + } + + driver_.reset(new Driver{datadog_config, cm_, stats_, tls_, runtime_}); + } + + void setupValidDriver() { + EXPECT_CALL(cm_, get("fake_cluster")).WillRepeatedly(Return(&cm_.thread_local_cluster_)); + ON_CALL(*cm_.thread_local_cluster_.cluster_.info_, features()) + .WillByDefault(Return(Upstream::ClusterInfo::Features::HTTP2)); + + const std::string yaml_string = R"EOF( + collector_cluster: fake_cluster + )EOF"; + envoy::config::trace::v2::DatadogConfig datadog_config; + MessageUtil::loadFromYaml(yaml_string, datadog_config); + + setup(datadog_config, true); + } + + const std::string operation_name_{"test"}; + Http::TestHeaderMapImpl request_headers_{ + {":path", "/"}, {":method", "GET"}, {"x-request-id", "foo"}}; + const Http::TestHeaderMapImpl response_headers_{{":status", "500"}}; + SystemTime start_time_; + + NiceMock tls_; + std::unique_ptr driver_; + NiceMock* timer_; + Stats::IsolatedStoreImpl stats_; + NiceMock cm_; + NiceMock random_; + NiceMock runtime_; + NiceMock local_info_; + + NiceMock config_; +}; + +TEST_F(DatadogDriverTest, InitializeDriver) { + { + envoy::config::trace::v2::DatadogConfig datadog_config; + + EXPECT_THROW(setup(datadog_config, false), EnvoyException); + } + + { + // Valid config but not valid cluster. + EXPECT_CALL(cm_, get("fake_cluster")).WillOnce(Return(nullptr)); + + const std::string yaml_string = R"EOF( + collector_cluster: fake_cluster + )EOF"; + envoy::config::trace::v2::DatadogConfig datadog_config; + MessageUtil::loadFromYaml(yaml_string, datadog_config); + + EXPECT_THROW(setup(datadog_config, false), EnvoyException); + } + + { + EXPECT_CALL(cm_, get("fake_cluster")).WillRepeatedly(Return(&cm_.thread_local_cluster_)); + ON_CALL(*cm_.thread_local_cluster_.cluster_.info_, features()) + .WillByDefault(Return(Upstream::ClusterInfo::Features::HTTP2)); + + const std::string yaml_string = R"EOF( + collector_cluster: fake_cluster + )EOF"; + envoy::config::trace::v2::DatadogConfig datadog_config; + MessageUtil::loadFromYaml(yaml_string, datadog_config); + + setup(datadog_config, true); + } +} + +TEST_F(DatadogDriverTest, FlushSpansTimer) { + setupValidDriver(); + + Http::MockAsyncClientRequest request(&cm_.async_client_); + Http::AsyncClient::Callbacks* callback; + const absl::optional timeout(std::chrono::seconds(1)); + EXPECT_CALL(cm_.async_client_, send_(_, _, timeout)) + .WillOnce(Invoke( + [&](Http::MessagePtr& message, Http::AsyncClient::Callbacks& callbacks, + const absl::optional&) -> Http::AsyncClient::Request* { + callback = &callbacks; + + EXPECT_STREQ("fake_cluster", message->headers().Host()->value().c_str()); + EXPECT_STREQ("application/msgpack", message->headers().ContentType()->value().c_str()); + + return &request; + })); + + Tracing::SpanPtr span = driver_->startSpan(config_, request_headers_, operation_name_, + start_time_, {Tracing::Reason::Sampling, true}); + span->finishSpan(); + + // Timer should be re-enabled. + EXPECT_CALL(*timer_, enableTimer(std::chrono::milliseconds(1000))); + EXPECT_CALL(runtime_.snapshot_, getInteger("tracing.datadog.request_timeout", 1000U)) + .WillOnce(Return(1000U)); + EXPECT_CALL(runtime_.snapshot_, getInteger("tracing.datadog.flush_interval_ms", 1000U)) + .WillOnce(Return(1000U)); + + timer_->callback_(); + + EXPECT_EQ(1U, stats_.counter("tracing.datadog.timer_flushed").value()); + EXPECT_EQ(1U, stats_.counter("tracing.datadog.traces_sent").value()); + + Http::MessagePtr msg(new Http::ResponseMessageImpl( + Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + callback->onSuccess(std::move(msg)); + + EXPECT_EQ(1U, stats_.counter("tracing.datadog.reports_sent").value()); + EXPECT_EQ(0U, stats_.counter("tracing.datadog.reports_dropped").value()); + EXPECT_EQ(0U, stats_.counter("tracing.datadog.reports_failed").value()); +} + +} // namespace Datadog +} // namespace Tracers +} // namespace Extensions +} // namespace Envoy From 569bbc28070092e321e9742bd888fcaea161e39f Mon Sep 17 00:00:00 2001 From: Caleb Gilmour Date: Tue, 16 Oct 2018 04:42:20 +0000 Subject: [PATCH 02/15] Updates from review comments. Signed-off-by: Caleb Gilmour --- api/envoy/config/trace/v2/trace.proto | 3 +++ bazel/repository_locations.bzl | 2 +- .../tracers/datadog/datadog_tracer_impl.cc | 14 +++++++++----- .../tracers/datadog/datadog_tracer_impl.h | 12 ++++++------ 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/api/envoy/config/trace/v2/trace.proto b/api/envoy/config/trace/v2/trace.proto index a7c543e8837b4..08d24e6b8c428 100644 --- a/api/envoy/config/trace/v2/trace.proto +++ b/api/envoy/config/trace/v2/trace.proto @@ -84,7 +84,10 @@ message DynamicOtConfig { message DatadogConfig { // The cluster to use for submitting traces to the Datadog agent. string collector_cluster = 1 [(validate.rules).string.min_bytes = 1]; + // The name used for the service when traces are generated by envoy. string service_name = 2 [(validate.rules).string.min_bytes = 1]; + // Enables distributed priority sampling, where traces are sampled based on a + // combination of user-assigned priorities and configuration from the Datadog agent. bool priority_sampling = 3; } diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index c6645b3e9fc36..f8ebb9794c72c 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -83,7 +83,7 @@ REPOSITORY_LOCATIONS = dict( remote = "https://github.com/google/googleapis", ), com_github_datadog_dd_opentracing_cpp = dict( - commit = "92d7ee11f61361ca23e00b48d328fb4e494534c4", # v0.3.1 + commit = "3103ae9860ad1988529d13fed0f1ecc8ebb39dd7", # v0.3.2 remote = "https://github.com/DataDog/dd-opentracing-cpp", ), com_github_msgpack_msgpack_c = dict( diff --git a/source/extensions/tracers/datadog/datadog_tracer_impl.cc b/source/extensions/tracers/datadog/datadog_tracer_impl.cc index c68bcd3823d72..e3396bdffcfb2 100644 --- a/source/extensions/tracers/datadog/datadog_tracer_impl.cc +++ b/source/extensions/tracers/datadog/datadog_tracer_impl.cc @@ -32,13 +32,18 @@ Driver::Driver(const envoy::config::trace::v2::DatadogConfig& datadog_config, } cluster_ = cluster->info(); + // Default tracer options. tracer_options_.operation_name_override = "envoy.proxy"; - if (datadog_config.service_name().size() > 0) { + tracer_options_.service = "envoy"; + tracer_options_.priority_sampling = true; + + // Configuration overrides for tracer options. + if (!datadog_config.service_name().empty()) { tracer_options_.service = datadog_config.service_name(); - } else { - tracer_options_.service = "envoy"; } - tracer_options_.priority_sampling = datadog_config.priority_sampling(); + if (!datadog_config.priority_sampling()) { + tracer_options_.priority_sampling = false; + } tls_->set([this](Event::Dispatcher& dispatcher) -> ThreadLocal::ThreadLocalObjectSharedPtr { auto tp = datadog::opentracing::makeTracerAndEncoder(tracer_options_); @@ -80,7 +85,6 @@ void TraceReporter::flushTraces() { message->headers().insertPath().value(encoder_->path()); message->headers().insertHost().value(driver_.cluster()->name()); for (auto& h : encoder_->headers()) { - ENVOY_LOG(debug, "Adding header {}: {}", h.first, h.second); message->headers().addCopy(Http::LowerCaseString(h.first), h.second); } diff --git a/source/extensions/tracers/datadog/datadog_tracer_impl.h b/source/extensions/tracers/datadog/datadog_tracer_impl.h index 20395f24e7e11..18044d23d2adf 100644 --- a/source/extensions/tracers/datadog/datadog_tracer_impl.h +++ b/source/extensions/tracers/datadog/datadog_tracer_impl.h @@ -45,12 +45,6 @@ class Driver : public Common::Ot::OpenTracingDriver { Upstream::ClusterManager& cluster_manager, Stats::Store& stats, ThreadLocal::SlotAllocator& tls, Runtime::Loader& runtime); - // Tracer::OpenTracingDriver - opentracing::Tracer& tracer() override; - PropagationMode propagationMode() const override { - return Common::Ot::OpenTracingDriver::PropagationMode::TracerNative; - } - // Getters to return the DatadogDriver's key members. Upstream::ClusterManager& clusterManager() { return cm_; } Upstream::ClusterInfoConstSharedPtr cluster() { return cluster_; } @@ -58,6 +52,12 @@ class Driver : public Common::Ot::OpenTracingDriver { DatadogTracerStats& tracerStats() { return tracer_stats_; } const datadog::opentracing::TracerOptions& tracerOptions() { return tracer_options_; } + // Tracer::OpenTracingDriver + opentracing::Tracer& tracer() override; + PropagationMode propagationMode() const override { + return Common::Ot::OpenTracingDriver::PropagationMode::TracerNative; + } + private: /** * Thread-local store containing DatadogDriver and Datadog::Tracer objects. From 35b8db660aee469f31c580a2437dd1672eaf5b7a Mon Sep 17 00:00:00 2001 From: Caleb Gilmour Date: Wed, 17 Oct 2018 07:52:56 +0000 Subject: [PATCH 03/15] Update dd-opentracing-cpp to v0.3.3 Signed-off-by: Caleb Gilmour --- bazel/repository_locations.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index f8ebb9794c72c..a14bd9f1d2b00 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -83,7 +83,7 @@ REPOSITORY_LOCATIONS = dict( remote = "https://github.com/google/googleapis", ), com_github_datadog_dd_opentracing_cpp = dict( - commit = "3103ae9860ad1988529d13fed0f1ecc8ebb39dd7", # v0.3.2 + commit = "16934caf138afe19a954d1224e467469bb645b74", # v0.3.3 remote = "https://github.com/DataDog/dd-opentracing-cpp", ), com_github_msgpack_msgpack_c = dict( From 7e20b686d46f40dc23ebf1351614709e4b30d0a8 Mon Sep 17 00:00:00 2001 From: Caleb Gilmour Date: Tue, 23 Oct 2018 02:17:17 +0000 Subject: [PATCH 04/15] Minor fix and bump dd-opentracing-cpp to v0.3.4 Signed-off-by: Caleb Gilmour --- bazel/repository_locations.bzl | 2 +- source/extensions/tracers/datadog/datadog_tracer_impl.cc | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index a14bd9f1d2b00..3fdc97be21ca0 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -83,7 +83,7 @@ REPOSITORY_LOCATIONS = dict( remote = "https://github.com/google/googleapis", ), com_github_datadog_dd_opentracing_cpp = dict( - commit = "16934caf138afe19a954d1224e467469bb645b74", # v0.3.3 + commit = "816a010c222959e4b8dcbb57329373626f710a3c", # v0.3.4 remote = "https://github.com/DataDog/dd-opentracing-cpp", ), com_github_msgpack_msgpack_c = dict( diff --git a/source/extensions/tracers/datadog/datadog_tracer_impl.cc b/source/extensions/tracers/datadog/datadog_tracer_impl.cc index e3396bdffcfb2..77a09a8deea22 100644 --- a/source/extensions/tracers/datadog/datadog_tracer_impl.cc +++ b/source/extensions/tracers/datadog/datadog_tracer_impl.cc @@ -114,12 +114,12 @@ void TraceReporter::onSuccess(Http::MessagePtr&& http_response) { if (responseStatus != enumToInt(Http::Code::OK)) { ENVOY_LOG(debug, "unexpected HTTP response code from datadog agent: {}", responseStatus); driver_.tracerStats().reports_dropped_.inc(); - if (driver_.tracerOptions().priority_sampling) { - encoder_->handleResponse(http_response->body()->toString()); - } } else { ENVOY_LOG(debug, "traces successfully submitted to datadog agent"); driver_.tracerStats().reports_sent_.inc(); + if (driver_.tracerOptions().priority_sampling) { + encoder_->handleResponse(http_response->body()->toString()); + } } } From b83733270fbe6284937e3cbfb96ca8536263e46c Mon Sep 17 00:00:00 2001 From: Caleb Gilmour Date: Mon, 29 Oct 2018 10:08:43 +0000 Subject: [PATCH 05/15] Use correct type name TraceEncoderSharedPtr Signed-off-by: Caleb Gilmour --- source/extensions/tracers/datadog/datadog_tracer_impl.cc | 2 +- source/extensions/tracers/datadog/datadog_tracer_impl.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/extensions/tracers/datadog/datadog_tracer_impl.cc b/source/extensions/tracers/datadog/datadog_tracer_impl.cc index 77a09a8deea22..9644543eeaca3 100644 --- a/source/extensions/tracers/datadog/datadog_tracer_impl.cc +++ b/source/extensions/tracers/datadog/datadog_tracer_impl.cc @@ -57,7 +57,7 @@ Driver::Driver(const envoy::config::trace::v2::DatadogConfig& datadog_config, opentracing::Tracer& Driver::tracer() { return *tls_->getTyped().tracer_; } -TraceReporter::TraceReporter(TraceEncoderPtr encoder, Driver& driver, Event::Dispatcher& dispatcher) +TraceReporter::TraceReporter(TraceEncoderSharedPtr encoder, Driver& driver, Event::Dispatcher& dispatcher) : driver_(driver), encoder_(encoder) { flush_timer_ = dispatcher.createTimer([this]() -> void { driver_.tracerStats().timer_flushed_.inc(); diff --git a/source/extensions/tracers/datadog/datadog_tracer_impl.h b/source/extensions/tracers/datadog/datadog_tracer_impl.h index 18044d23d2adf..6dc0e8efa527e 100644 --- a/source/extensions/tracers/datadog/datadog_tracer_impl.h +++ b/source/extensions/tracers/datadog/datadog_tracer_impl.h @@ -31,7 +31,7 @@ struct DatadogTracerStats { class TraceReporter; typedef std::unique_ptr TraceReporterPtr; -typedef std::shared_ptr TraceEncoderPtr; +typedef std::shared_ptr TraceEncoderSharedPtr; /** * Class for a Datadog-specific Driver. @@ -103,7 +103,7 @@ class TraceReporter : public Http::AsyncClient::Callbacks, * @param driver The driver to be associated with the reporter. * @param dispatcher Controls the timer used to flush buffered traces. */ - TraceReporter(TraceEncoderPtr encoder, Driver& driver, Event::Dispatcher& dispatcher); + TraceReporter(TraceEncoderSharedPtr encoder, Driver& driver, Event::Dispatcher& dispatcher); // Http::AsyncClient::Callbacks. void onSuccess(Http::MessagePtr&&) override; @@ -123,7 +123,7 @@ class TraceReporter : public Http::AsyncClient::Callbacks, Driver& driver_; Event::TimerPtr flush_timer_; - TraceEncoderPtr encoder_; + TraceEncoderSharedPtr encoder_; }; } // namespace Datadog } // namespace Tracers From 864db99bd3b9852610d984d245101206c14c5816 Mon Sep 17 00:00:00 2001 From: Caleb Gilmour Date: Mon, 29 Oct 2018 22:21:57 +0000 Subject: [PATCH 06/15] Use references instead of copies. Signed-off-by: Caleb Gilmour --- source/extensions/tracers/datadog/datadog_tracer_impl.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/extensions/tracers/datadog/datadog_tracer_impl.cc b/source/extensions/tracers/datadog/datadog_tracer_impl.cc index 9644543eeaca3..ec3c63b3fcef8 100644 --- a/source/extensions/tracers/datadog/datadog_tracer_impl.cc +++ b/source/extensions/tracers/datadog/datadog_tracer_impl.cc @@ -82,10 +82,10 @@ void TraceReporter::flushTraces() { Http::MessagePtr message(new Http::RequestMessageImpl()); message->headers().insertMethod().value().setReference(Http::Headers::get().MethodValues.Post); - message->headers().insertPath().value(encoder_->path()); - message->headers().insertHost().value(driver_.cluster()->name()); + message->headers().insertPath().value().setReference(encoder_->path()); + message->headers().insertHost().value().setReference(driver_.cluster()->name()); for (auto& h : encoder_->headers()) { - message->headers().addCopy(Http::LowerCaseString(h.first), h.second); + message->headers().addReferenceKey(Http::LowerCaseString{h.first}, h.second); } Buffer::InstancePtr body(new Buffer::OwnedImpl()); From 08bbe72ddbc8a29b372bd8e33d093dad54142181 Mon Sep 17 00:00:00 2001 From: Caleb Gilmour Date: Tue, 30 Oct 2018 05:28:54 +0000 Subject: [PATCH 07/15] Remove priority_sampling option. Signed-off-by: Caleb Gilmour --- api/envoy/config/trace/v2/trace.proto | 3 --- source/extensions/tracers/datadog/datadog_tracer_impl.cc | 8 +------- test/extensions/tracers/datadog/config_test.cc | 1 - 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/api/envoy/config/trace/v2/trace.proto b/api/envoy/config/trace/v2/trace.proto index 08d24e6b8c428..951874df0b998 100644 --- a/api/envoy/config/trace/v2/trace.proto +++ b/api/envoy/config/trace/v2/trace.proto @@ -86,9 +86,6 @@ message DatadogConfig { string collector_cluster = 1 [(validate.rules).string.min_bytes = 1]; // The name used for the service when traces are generated by envoy. string service_name = 2 [(validate.rules).string.min_bytes = 1]; - // Enables distributed priority sampling, where traces are sampled based on a - // combination of user-assigned priorities and configuration from the Datadog agent. - bool priority_sampling = 3; } // Configuration structure. diff --git a/source/extensions/tracers/datadog/datadog_tracer_impl.cc b/source/extensions/tracers/datadog/datadog_tracer_impl.cc index ec3c63b3fcef8..a8fbaa8eb3919 100644 --- a/source/extensions/tracers/datadog/datadog_tracer_impl.cc +++ b/source/extensions/tracers/datadog/datadog_tracer_impl.cc @@ -35,15 +35,11 @@ Driver::Driver(const envoy::config::trace::v2::DatadogConfig& datadog_config, // Default tracer options. tracer_options_.operation_name_override = "envoy.proxy"; tracer_options_.service = "envoy"; - tracer_options_.priority_sampling = true; // Configuration overrides for tracer options. if (!datadog_config.service_name().empty()) { tracer_options_.service = datadog_config.service_name(); } - if (!datadog_config.priority_sampling()) { - tracer_options_.priority_sampling = false; - } tls_->set([this](Event::Dispatcher& dispatcher) -> ThreadLocal::ThreadLocalObjectSharedPtr { auto tp = datadog::opentracing::makeTracerAndEncoder(tracer_options_); @@ -117,9 +113,7 @@ void TraceReporter::onSuccess(Http::MessagePtr&& http_response) { } else { ENVOY_LOG(debug, "traces successfully submitted to datadog agent"); driver_.tracerStats().reports_sent_.inc(); - if (driver_.tracerOptions().priority_sampling) { - encoder_->handleResponse(http_response->body()->toString()); - } + encoder_->handleResponse(http_response->body()->toString()); } } diff --git a/test/extensions/tracers/datadog/config_test.cc b/test/extensions/tracers/datadog/config_test.cc index 7a5bec96dac5f..750333b57f6c5 100644 --- a/test/extensions/tracers/datadog/config_test.cc +++ b/test/extensions/tracers/datadog/config_test.cc @@ -27,7 +27,6 @@ TEST(DatadogTracerConfigTest, DatadogHttpTracer) { config: collector_cluster: fake_cluster service_name: fake_file - priority_sampling: true )EOF"; envoy::config::trace::v2::Tracing configuration; MessageUtil::loadFromYaml(yaml_string, configuration); From cb479b2c5b525aecc4d3474de7c3eef601edf677 Mon Sep 17 00:00:00 2001 From: Caleb Gilmour Date: Wed, 31 Oct 2018 03:25:47 +0000 Subject: [PATCH 08/15] Revert to addCopy for encoder headers. Signed-off-by: Caleb Gilmour --- source/extensions/tracers/datadog/datadog_tracer_impl.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/extensions/tracers/datadog/datadog_tracer_impl.cc b/source/extensions/tracers/datadog/datadog_tracer_impl.cc index a8fbaa8eb3919..157035ece71eb 100644 --- a/source/extensions/tracers/datadog/datadog_tracer_impl.cc +++ b/source/extensions/tracers/datadog/datadog_tracer_impl.cc @@ -3,7 +3,6 @@ #include "common/common/enum_to_int.h" #include "common/common/fmt.h" #include "common/common/utility.h" -#include "common/http/headers.h" #include "common/http/message_impl.h" #include "common/http/utility.h" #include "common/tracing/http_tracer_impl.h" @@ -81,7 +80,7 @@ void TraceReporter::flushTraces() { message->headers().insertPath().value().setReference(encoder_->path()); message->headers().insertHost().value().setReference(driver_.cluster()->name()); for (auto& h : encoder_->headers()) { - message->headers().addReferenceKey(Http::LowerCaseString{h.first}, h.second); + message->headers().addCopy(Http::LowerCaseString{h.first}, h.second); } Buffer::InstancePtr body(new Buffer::OwnedImpl()); From cf8c51193ef1e9a8e8259a5d5696bab07660b42f Mon Sep 17 00:00:00 2001 From: Caleb Gilmour Date: Wed, 31 Oct 2018 09:26:52 +0000 Subject: [PATCH 09/15] Use sensible default, remove config items. Fix test. Signed-off-by: Caleb Gilmour --- source/extensions/tracers/datadog/datadog_tracer_impl.cc | 8 ++------ .../tracers/datadog/datadog_tracer_impl_test.cc | 6 ++---- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/source/extensions/tracers/datadog/datadog_tracer_impl.cc b/source/extensions/tracers/datadog/datadog_tracer_impl.cc index 157035ece71eb..8913f14249378 100644 --- a/source/extensions/tracers/datadog/datadog_tracer_impl.cc +++ b/source/extensions/tracers/datadog/datadog_tracer_impl.cc @@ -64,9 +64,7 @@ TraceReporter::TraceReporter(TraceEncoderSharedPtr encoder, Driver& driver, Even } void TraceReporter::enableTimer() { - const uint64_t flush_interval = - driver_.runtime().snapshot().getInteger("tracing.datadog.flush_interval_ms", 1000U); - flush_timer_->enableTimer(std::chrono::milliseconds(flush_interval)); + flush_timer_->enableTimer(std::chrono::milliseconds(1000U)); } void TraceReporter::flushTraces() { @@ -89,11 +87,9 @@ void TraceReporter::flushTraces() { ENVOY_LOG(debug, "submitting {} trace(s) to {} with payload {}", pendingTraces, encoder_->path(), encoder_->payload().size()); - const uint64_t timeout = - driver_.runtime().snapshot().getInteger("tracing.datadog.request_timeout", 1000U); driver_.clusterManager() .httpAsyncClientForCluster(driver_.cluster()->name()) - .send(std::move(message), *this, std::chrono::milliseconds(timeout)); + .send(std::move(message), *this, std::chrono::milliseconds(1000U)); encoder_->clearTraces(); } diff --git a/test/extensions/tracers/datadog/datadog_tracer_impl_test.cc b/test/extensions/tracers/datadog/datadog_tracer_impl_test.cc index 0f5b1b75312fb..5e2391520c9ad 100644 --- a/test/extensions/tracers/datadog/datadog_tracer_impl_test.cc +++ b/test/extensions/tracers/datadog/datadog_tracer_impl_test.cc @@ -144,10 +144,6 @@ TEST_F(DatadogDriverTest, FlushSpansTimer) { // Timer should be re-enabled. EXPECT_CALL(*timer_, enableTimer(std::chrono::milliseconds(1000))); - EXPECT_CALL(runtime_.snapshot_, getInteger("tracing.datadog.request_timeout", 1000U)) - .WillOnce(Return(1000U)); - EXPECT_CALL(runtime_.snapshot_, getInteger("tracing.datadog.flush_interval_ms", 1000U)) - .WillOnce(Return(1000U)); timer_->callback_(); @@ -156,6 +152,8 @@ TEST_F(DatadogDriverTest, FlushSpansTimer) { Http::MessagePtr msg(new Http::ResponseMessageImpl( Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); + msg->body().reset(new Buffer::OwnedImpl("")); + callback->onSuccess(std::move(msg)); EXPECT_EQ(1U, stats_.counter("tracing.datadog.reports_sent").value()); From 9b25a32e6e14703af6453ef803a17ebe150da38f Mon Sep 17 00:00:00 2001 From: Caleb Gilmour Date: Wed, 31 Oct 2018 21:13:24 +0000 Subject: [PATCH 10/15] Change tracers to use checkCluster Signed-off-by: Caleb Gilmour --- source/extensions/tracers/datadog/BUILD | 2 ++ .../tracers/datadog/datadog_tracer_impl.cc | 19 +++++++++---------- source/extensions/tracers/lightstep/BUILD | 2 ++ .../lightstep/lightstep_tracer_impl.cc | 12 ++++++------ source/extensions/tracers/zipkin/BUILD | 2 ++ .../tracers/zipkin/zipkin_tracer_impl.cc | 11 ++++------- 6 files changed, 25 insertions(+), 23 deletions(-) diff --git a/source/extensions/tracers/datadog/BUILD b/source/extensions/tracers/datadog/BUILD index e4ac3d95ba415..afcc3c7b7f88a 100644 --- a/source/extensions/tracers/datadog/BUILD +++ b/source/extensions/tracers/datadog/BUILD @@ -21,7 +21,9 @@ envoy_cc_library( external_deps = ["dd_opentracing_cpp"], deps = [ "//source/common/tracing:http_tracer_lib", + "//source/extensions/tracers:well_known_names", "//source/extensions/tracers/common/ot:opentracing_driver_lib", + "//source/server:configuration_lib", ], ) diff --git a/source/extensions/tracers/datadog/datadog_tracer_impl.cc b/source/extensions/tracers/datadog/datadog_tracer_impl.cc index 8913f14249378..963288c02df67 100644 --- a/source/extensions/tracers/datadog/datadog_tracer_impl.cc +++ b/source/extensions/tracers/datadog/datadog_tracer_impl.cc @@ -3,10 +3,13 @@ #include "common/common/enum_to_int.h" #include "common/common/fmt.h" #include "common/common/utility.h" +#include "common/config/utility.h" #include "common/http/message_impl.h" #include "common/http/utility.h" #include "common/tracing/http_tracer_impl.h" +#include "extensions/tracers/well_known_names.h" + namespace Envoy { namespace Extensions { namespace Tracers { @@ -24,12 +27,9 @@ Driver::Driver(const envoy::config::trace::v2::DatadogConfig& datadog_config, POOL_COUNTER_PREFIX(stats, "tracing.datadog."))}, tls_(tls.allocateSlot()), runtime_(runtime) { - Upstream::ThreadLocalCluster* cluster = cm_.get(datadog_config.collector_cluster()); - if (!cluster) { - throw EnvoyException(fmt::format("{} collector cluster is not defined on cluster manager level", - datadog_config.collector_cluster())); - } - cluster_ = cluster->info(); + Config::Utility::checkCluster(TracerNames::get().Datadog, datadog_config.collector_cluster(), + cm_); + cluster_ = cm_.get(datadog_config.collector_cluster())->info(); // Default tracer options. tracer_options_.operation_name_override = "envoy.proxy"; @@ -52,7 +52,8 @@ Driver::Driver(const envoy::config::trace::v2::DatadogConfig& datadog_config, opentracing::Tracer& Driver::tracer() { return *tls_->getTyped().tracer_; } -TraceReporter::TraceReporter(TraceEncoderSharedPtr encoder, Driver& driver, Event::Dispatcher& dispatcher) +TraceReporter::TraceReporter(TraceEncoderSharedPtr encoder, Driver& driver, + Event::Dispatcher& dispatcher) : driver_(driver), encoder_(encoder) { flush_timer_ = dispatcher.createTimer([this]() -> void { driver_.tracerStats().timer_flushed_.inc(); @@ -63,9 +64,7 @@ TraceReporter::TraceReporter(TraceEncoderSharedPtr encoder, Driver& driver, Even enableTimer(); } -void TraceReporter::enableTimer() { - flush_timer_->enableTimer(std::chrono::milliseconds(1000U)); -} +void TraceReporter::enableTimer() { flush_timer_->enableTimer(std::chrono::milliseconds(1000U)); } void TraceReporter::flushTraces() { auto pendingTraces = encoder_->pendingTraces(); diff --git a/source/extensions/tracers/lightstep/BUILD b/source/extensions/tracers/lightstep/BUILD index 7a30babd54671..60009ac3648e7 100644 --- a/source/extensions/tracers/lightstep/BUILD +++ b/source/extensions/tracers/lightstep/BUILD @@ -21,7 +21,9 @@ envoy_cc_library( external_deps = ["lightstep"], deps = [ "//source/common/tracing:http_tracer_lib", + "//source/extensions/tracers:well_known_names", "//source/extensions/tracers/common/ot:opentracing_driver_lib", + "//source/server:configuration_lib", ], ) diff --git a/source/extensions/tracers/lightstep/lightstep_tracer_impl.cc b/source/extensions/tracers/lightstep/lightstep_tracer_impl.cc index 68319613bc6f3..b1f6e2d9288bb 100644 --- a/source/extensions/tracers/lightstep/lightstep_tracer_impl.cc +++ b/source/extensions/tracers/lightstep/lightstep_tracer_impl.cc @@ -8,10 +8,13 @@ #include "common/buffer/zero_copy_input_stream_impl.h" #include "common/common/base64.h" #include "common/common/fmt.h" +#include "common/config/utility.h" #include "common/grpc/common.h" #include "common/http/message_impl.h" #include "common/tracing/http_tracer_impl.h" +#include "extensions/tracers/well_known_names.h" + namespace Envoy { namespace Extensions { namespace Tracers { @@ -138,12 +141,9 @@ LightStepDriver::LightStepDriver(const envoy::config::trace::v2::LightstepConfig tracer_stats_{LIGHTSTEP_TRACER_STATS(POOL_COUNTER_PREFIX(stats, "tracing.lightstep."))}, tls_{tls.allocateSlot()}, runtime_{runtime}, options_{std::move(options)}, propagation_mode_{propagation_mode} { - Upstream::ThreadLocalCluster* cluster = cm_.get(lightstep_config.collector_cluster()); - if (!cluster) { - throw EnvoyException(fmt::format("{} collector cluster is not defined on cluster manager level", - lightstep_config.collector_cluster())); - } - cluster_ = cluster->info(); + Config::Utility::checkCluster(TracerNames::get().Lightstep, lightstep_config.collector_cluster(), + cm_); + cluster_ = cm_.get(lightstep_config.collector_cluster())->info(); if (!(cluster_->features() & Upstream::ClusterInfo::Features::HTTP2)) { throw EnvoyException( diff --git a/source/extensions/tracers/zipkin/BUILD b/source/extensions/tracers/zipkin/BUILD index 24f30300c0a99..e520a5dde1228 100644 --- a/source/extensions/tracers/zipkin/BUILD +++ b/source/extensions/tracers/zipkin/BUILD @@ -53,6 +53,8 @@ envoy_cc_library( "//source/common/network:address_lib", "//source/common/singleton:const_singleton", "//source/common/tracing:http_tracer_lib", + "//source/extensions/tracers:well_known_names", + "//source/server:configuration_lib", ], ) diff --git a/source/extensions/tracers/zipkin/zipkin_tracer_impl.cc b/source/extensions/tracers/zipkin/zipkin_tracer_impl.cc index c5adb06b82a58..b189b17f8d4ba 100644 --- a/source/extensions/tracers/zipkin/zipkin_tracer_impl.cc +++ b/source/extensions/tracers/zipkin/zipkin_tracer_impl.cc @@ -3,11 +3,13 @@ #include "common/common/enum_to_int.h" #include "common/common/fmt.h" #include "common/common/utility.h" +#include "common/config/utility.h" #include "common/http/headers.h" #include "common/http/message_impl.h" #include "common/http/utility.h" #include "common/tracing/http_tracer_impl.h" +#include "extensions/tracers/well_known_names.h" #include "extensions/tracers/zipkin/zipkin_core_constants.h" namespace Envoy { @@ -62,13 +64,8 @@ Driver::Driver(const envoy::config::trace::v2::ZipkinConfig& zipkin_config, POOL_COUNTER_PREFIX(stats, "tracing.zipkin."))}, tls_(tls.allocateSlot()), runtime_(runtime), local_info_(local_info), time_source_(time_source) { - - Upstream::ThreadLocalCluster* cluster = cm_.get(zipkin_config.collector_cluster()); - if (!cluster) { - throw EnvoyException(fmt::format("{} collector cluster is not defined on cluster manager level", - zipkin_config.collector_cluster())); - } - cluster_ = cluster->info(); + Config::Utility::checkCluster(TracerNames::get().Zipkin, zipkin_config.collector_cluster(), cm_); + cluster_ = cm_.get(zipkin_config.collector_cluster())->info(); std::string collector_endpoint = ZipkinCoreConstants::get().DEFAULT_COLLECTOR_ENDPOINT; if (zipkin_config.collector_endpoint().size() > 0) { From 160ff4e2b734e361015fa5b5ebf39edc51d9ceaa Mon Sep 17 00:00:00 2001 From: Caleb Gilmour Date: Thu, 1 Nov 2018 08:31:01 +0000 Subject: [PATCH 11/15] Convert headers to LowerCaseString once. Pass refs Signed-off-by: Caleb Gilmour --- source/extensions/tracers/datadog/datadog_tracer_impl.cc | 5 ++++- source/extensions/tracers/datadog/datadog_tracer_impl.h | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/source/extensions/tracers/datadog/datadog_tracer_impl.cc b/source/extensions/tracers/datadog/datadog_tracer_impl.cc index 963288c02df67..81feec2ad9f8d 100644 --- a/source/extensions/tracers/datadog/datadog_tracer_impl.cc +++ b/source/extensions/tracers/datadog/datadog_tracer_impl.cc @@ -56,6 +56,9 @@ TraceReporter::TraceReporter(TraceEncoderSharedPtr encoder, Driver& driver, Event::Dispatcher& dispatcher) : driver_(driver), encoder_(encoder) { flush_timer_ = dispatcher.createTimer([this]() -> void { + for (auto& h : encoder_->headers()) { + lower_case_headers_.emplace(h.first, Http::LowerCaseString{h.first}); + } driver_.tracerStats().timer_flushed_.inc(); flushTraces(); enableTimer(); @@ -77,7 +80,7 @@ void TraceReporter::flushTraces() { message->headers().insertPath().value().setReference(encoder_->path()); message->headers().insertHost().value().setReference(driver_.cluster()->name()); for (auto& h : encoder_->headers()) { - message->headers().addCopy(Http::LowerCaseString{h.first}, h.second); + message->headers().setReferenceKey(lower_case_headers_.at(h.first), h.second); } Buffer::InstancePtr body(new Buffer::OwnedImpl()); diff --git a/source/extensions/tracers/datadog/datadog_tracer_impl.h b/source/extensions/tracers/datadog/datadog_tracer_impl.h index 6dc0e8efa527e..54f8379b84da5 100644 --- a/source/extensions/tracers/datadog/datadog_tracer_impl.h +++ b/source/extensions/tracers/datadog/datadog_tracer_impl.h @@ -124,6 +124,8 @@ class TraceReporter : public Http::AsyncClient::Callbacks, Driver& driver_; Event::TimerPtr flush_timer_; TraceEncoderSharedPtr encoder_; + + std::map lower_case_headers_; }; } // namespace Datadog } // namespace Tracers From 3ed7dafdbbbcba3499f22b1cd2fda05f396764c2 Mon Sep 17 00:00:00 2001 From: Caleb Gilmour Date: Thu, 1 Nov 2018 08:42:10 +0000 Subject: [PATCH 12/15] Update dd-opentracing-cpp -> v0.3.5 Signed-off-by: Caleb Gilmour --- bazel/repository_locations.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index 3fdc97be21ca0..d66e27dee60df 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -83,7 +83,7 @@ REPOSITORY_LOCATIONS = dict( remote = "https://github.com/google/googleapis", ), com_github_datadog_dd_opentracing_cpp = dict( - commit = "816a010c222959e4b8dcbb57329373626f710a3c", # v0.3.4 + commit = "05ebb8e0c0f1bfb3a3439e5ad4b3b9e6307b67ee", # v0.3.5 remote = "https://github.com/DataDog/dd-opentracing-cpp", ), com_github_msgpack_msgpack_c = dict( From 8c1fe84b1c916ae76b137c8701ae5ec902563107 Mon Sep 17 00:00:00 2001 From: Caleb Gilmour Date: Thu, 1 Nov 2018 09:32:33 +0000 Subject: [PATCH 13/15] Update repository locations Signed-off-by: Caleb Gilmour --- bazel/repository_locations.bzl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index db4f51769bf0c..f439ffe942313 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -91,12 +91,14 @@ REPOSITORY_LOCATIONS = dict( urls = ["https://github.com/googleapis/googleapis/archive/d6f78d948c53f3b400bb46996eb3084359914f9b.tar.gz"], ), com_github_datadog_dd_opentracing_cpp = dict( - commit = "05ebb8e0c0f1bfb3a3439e5ad4b3b9e6307b67ee", # v0.3.5 - remote = "https://github.com/DataDog/dd-opentracing-cpp", + sha256 = "733e9b698a232cfd3aa35b4e27c59641bf1fa78e52e71d29e230af4f2070cdf5", + strip_prefix = "dd-opentracing-cpp-0.3.5", + urls = ["https://github.com/DataDog/dd-opentracing-cpp/archive/v0.3.5.tar.gz"], ), com_github_msgpack_msgpack_c = dict( - commit = "83a82e3eb512b18d4149cabb7eb43c7e8bc081af", - remote = "https://github.com/msgpack/msgpack-c", # v3.1.1 + sha256 = "bda49f996a73d2c6080ff0523e7b535917cd28c8a79c3a5da54fc29332d61d1e", + strip_prefix = "msgpack-c-cpp-3.1.1", + urls = ["https://github.com/msgpack/msgpack-c/archive/cpp-3.1.1.tar.gz"], ), com_github_google_jwt_verify = dict( sha256 = "499f1e145c19f33031eb8fc6452d5d391b4cecfdeda23e2055386a3b33be4d41", From 5a243ab8bb09e651ff99c5edb549b84a645990fe Mon Sep 17 00:00:00 2001 From: Caleb Gilmour Date: Thu, 1 Nov 2018 20:02:57 +0000 Subject: [PATCH 14/15] Update for clang_tidy errors Signed-off-by: Caleb Gilmour --- source/extensions/tracers/datadog/config.cc | 6 +++--- test/extensions/tracers/datadog/datadog_tracer_impl_test.cc | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/extensions/tracers/datadog/config.cc b/source/extensions/tracers/datadog/config.cc index 2062f94d6958d..0d0e74577810b 100644 --- a/source/extensions/tracers/datadog/config.cc +++ b/source/extensions/tracers/datadog/config.cc @@ -28,9 +28,9 @@ DatadogTracerFactory::createHttpTracer(const envoy::config::trace::v2::Tracing& const auto& datadog_config = dynamic_cast(*config_ptr); - Tracing::DriverPtr datadog_driver{new Driver{datadog_config, server.clusterManager(), - server.stats(), server.threadLocal(), - server.runtime()}}; + Tracing::DriverPtr datadog_driver{ + std::make_unique(datadog_config, server.clusterManager(), server.stats(), + server.threadLocal(), server.runtime())}; return std::make_unique(std::move(datadog_driver), server.localInfo()); } diff --git a/test/extensions/tracers/datadog/datadog_tracer_impl_test.cc b/test/extensions/tracers/datadog/datadog_tracer_impl_test.cc index 5e2391520c9ad..6900e56b3ed81 100644 --- a/test/extensions/tracers/datadog/datadog_tracer_impl_test.cc +++ b/test/extensions/tracers/datadog/datadog_tracer_impl_test.cc @@ -50,7 +50,7 @@ class DatadogDriverTest : public Test { EXPECT_CALL(*timer_, enableTimer(std::chrono::milliseconds(1000))); } - driver_.reset(new Driver{datadog_config, cm_, stats_, tls_, runtime_}); + driver_ = std::make_unique(datadog_config, cm_, stats_, tls_, runtime_); } void setupValidDriver() { @@ -152,7 +152,7 @@ TEST_F(DatadogDriverTest, FlushSpansTimer) { Http::MessagePtr msg(new Http::ResponseMessageImpl( Http::HeaderMapPtr{new Http::TestHeaderMapImpl{{":status", "200"}}})); - msg->body().reset(new Buffer::OwnedImpl("")); + msg->body() = std::make_unique(""); callback->onSuccess(std::move(msg)); From cf4dfb2e53c6be0124a945ccab83892733fcade0 Mon Sep 17 00:00:00 2001 From: Caleb Gilmour Date: Fri, 2 Nov 2018 23:41:45 +0000 Subject: [PATCH 15/15] Update release notes and tracer docs. Signed-off-by: Caleb Gilmour --- api/envoy/config/trace/v2/trace.proto | 18 ++++++++---- .../configuration/http_conn_man/headers.rst | 28 +++++++++++++++++++ docs/root/install/ref_configs.rst | 2 +- docs/root/intro/arch_overview/tracing.rst | 11 ++++++-- docs/root/intro/version_history.rst | 1 + 5 files changed, 51 insertions(+), 9 deletions(-) diff --git a/api/envoy/config/trace/v2/trace.proto b/api/envoy/config/trace/v2/trace.proto index f1b12a4143ed3..7aac3277fee9b 100644 --- a/api/envoy/config/trace/v2/trace.proto +++ b/api/envoy/config/trace/v2/trace.proto @@ -23,15 +23,21 @@ import "validate/validate.proto"; message Tracing { message Http { // The name of the HTTP trace driver to instantiate. The name must match a - // supported HTTP trace driver. *envoy.lightstep*, *envoy.zipkin*, and - // *envoy.dynamic.ot* are built-in trace drivers. + // supported HTTP trace driver. Built-in trace drivers: + // + // - *envoy.lightstep* + // - *envoy.zipkin* + // - *envoy.dynamic.ot* + // - *envoy.tracers.datadog* string name = 1 [(validate.rules).string.min_bytes = 1]; // Trace driver specific configuration which depends on the driver being instantiated. - // See the :ref:`LightstepConfig - // `, :ref:`ZipkinConfig - // `, and :ref:`DynamicOtConfig - // ` trace drivers for examples. + // See the trace drivers for examples: + // + // - :ref:`LightstepConfig ` + // - :ref:`ZipkinConfig ` + // - :ref:`DynamicOtConfig ` + // - :ref:`DatadogConfig ` oneof config_type { google.protobuf.Struct config = 2; diff --git a/docs/root/configuration/http_conn_man/headers.rst b/docs/root/configuration/http_conn_man/headers.rst index 555cb3904eff4..ea46fb8ae9d75 100644 --- a/docs/root/configuration/http_conn_man/headers.rst +++ b/docs/root/configuration/http_conn_man/headers.rst @@ -437,6 +437,34 @@ The *b3* HTTP header is used by the Zipkin tracer in Envoy. Is a more compressed header format. See more on zipkin tracing `here `. +.. _config_http_conn_man_headers_x-datadog-trace-id: + +x-datadog-trace-id +------------------ + +The *x-datadog-trace-id* HTTP header is used by the Datadog tracer in Envoy. +The 64-bit value represents the ID of the overall trace, and is used to correlate +the spans. + +.. _config_http_conn_man_headers_x-datadog-parent-id: + +x-datadog-parent-id +------------------- + +The *x-datadog-parent-id* HTTP header is used by the Datadog tracer in Envoy. +The 64-bit value uniquely identifies the span within the trace, and is used to +create parent-child relationships between spans. + +.. _config_http_conn_man_headers_x-datadog-sampling-priority: + +x-datadog-sampling-priority +--------------------------- + +The *x-datadog-sampling-priority* HTTP header is used by the Datadog tracer in Envoy. +The integer value indicates the sampling decision that has been made for this trace. +A value of 0 indicates that the trace should not be collected, and a value of 1 +requests that spans are sampled and reported. + .. _config_http_conn_man_headers_custom_request_headers: Custom request/response headers diff --git a/docs/root/install/ref_configs.rst b/docs/root/install/ref_configs.rst index 6ae32e62cbda7..35fccc5b66c23 100644 --- a/docs/root/install/ref_configs.rst +++ b/docs/root/install/ref_configs.rst @@ -47,7 +47,7 @@ A few notes about the example configurations: * DNS for `yourcompany.net` is assumed to be setup for various things. Search the configuration templates for different instances of this. * Tracing is configured for `LightStep `_. To - disable this or enable `Zipkin ` tracing, delete or + disable this or enable `Zipkin ` or `Datadog ` tracing, delete or change the :ref:`tracing configuration ` accordingly. * The configuration demonstrates the use of a :ref:`global rate limiting service `. To disable this delete the :ref:`rate limit configuration diff --git a/docs/root/intro/arch_overview/tracing.rst b/docs/root/intro/arch_overview/tracing.rst index 633a64919cc64..91407ae4d01c3 100644 --- a/docs/root/intro/arch_overview/tracing.rst +++ b/docs/root/intro/arch_overview/tracing.rst @@ -14,7 +14,8 @@ sources of latency. Envoy supports three features related to system wide tracing x-request-id header for unified logging as well as tracing. * **External trace service integration**: Envoy supports pluggable external trace visualization providers. Currently Envoy supports `LightStep `_, `Zipkin `_ - or any Zipkin compatible backends (e.g. `Jaeger `_). + or any Zipkin compatible backends (e.g. `Jaeger `_), and + `Datadog `_. However, support for other tracing providers would not be difficult to add. * **Client trace ID joining**: The :ref:`config_http_conn_man_headers_x-client-trace-id` header can be used to join untrusted request IDs to the trusted internal @@ -71,6 +72,12 @@ Alternatively the trace context can be manually propagated by the service: request. In addition, the single :ref:`config_http_conn_man_headers_b3` header propagation format is supported, which is a more compressed format. +* When using the Datadog tracer, Envoy relies on the service to propagate the + Datadog-specific HTTP headers ( + :ref:`config_http_conn_man_headers_x-datadog-trace-id`, + :ref:`config_http_conn_man_headers_x-datadog-parent-id`, + :ref:`config_http_conn_man_headers_x-datadog-sampling-priority`). + What data each trace contains ----------------------------- An end-to-end trace is comprised of one or more spans. A @@ -95,7 +102,7 @@ the route. The name can also be overridden using the Envoy automatically sends spans to tracing collectors. Depending on the tracing collector, multiple spans are stitched together using common information such as the globally unique request ID :ref:`config_http_conn_man_headers_x-request-id` (LightStep) or -the trace ID configuration (Zipkin). See +the trace ID configuration (Zipkin and Datadog). See * :ref:`v2 API reference ` diff --git a/docs/root/intro/version_history.rst b/docs/root/intro/version_history.rst index e5a6d9a5ff1bd..8cef57f59259d 100644 --- a/docs/root/intro/version_history.rst +++ b/docs/root/intro/version_history.rst @@ -41,6 +41,7 @@ Version history * thrift_proxy: introduced thrift rate limiter filter * tls: add support for CRLs in :ref:`trusted_ca `. * tracing: added support to the Zipkin tracer for the :ref:`b3 ` single header format. +* tracing: added support for :ref:`Datadog ` tracer. * upstream: changed how load calculation for :ref:`priority levels` and :ref:`panic thresholds` interact. As long as normalized total health is 100% panic thresholds are disregarded. * upstream: changed the default hash for :ref:`ring hash ` from std::hash to `xxHash `_.