LCOV - code coverage report
Current view: top level - source/extensions/tracers/datadog - tracer.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 59 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 6 0.0 %

          Line data    Source code
       1             : #include "source/extensions/tracers/datadog/tracer.h"
       2             : 
       3             : #include <memory>
       4             : #include <utility>
       5             : 
       6             : #include "envoy/tracing/trace_context.h"
       7             : 
       8             : #include "source/common/common/assert.h"
       9             : #include "source/common/config/utility.h"
      10             : #include "source/common/tracing/null_span_impl.h"
      11             : #include "source/extensions/tracers/datadog/agent_http_client.h"
      12             : #include "source/extensions/tracers/datadog/dict_util.h"
      13             : #include "source/extensions/tracers/datadog/event_scheduler.h"
      14             : #include "source/extensions/tracers/datadog/logger.h"
      15             : #include "source/extensions/tracers/datadog/span.h"
      16             : #include "source/extensions/tracers/datadog/time_util.h"
      17             : 
      18             : #include "datadog/dict_reader.h"
      19             : #include "datadog/error.h"
      20             : #include "datadog/sampling_priority.h"
      21             : #include "datadog/span_config.h"
      22             : #include "datadog/trace_segment.h"
      23             : #include "datadog/tracer_config.h"
      24             : 
      25             : namespace Envoy {
      26             : namespace Extensions {
      27             : namespace Tracers {
      28             : namespace Datadog {
      29             : namespace {
      30             : 
      31             : std::shared_ptr<Tracer::ThreadLocalTracer> makeThreadLocalTracer(
      32             :     datadog::tracing::TracerConfig config, Upstream::ClusterManager& cluster_manager,
      33             :     const std::string& collector_cluster, const std::string& collector_reference_host,
      34           0 :     TracerStats& tracer_stats, Event::Dispatcher& dispatcher, spdlog::logger& logger) {
      35           0 :   config.logger = std::make_shared<Logger>(logger);
      36           0 :   config.agent.event_scheduler = std::make_shared<EventScheduler>(dispatcher);
      37           0 :   config.agent.http_client = std::make_shared<AgentHTTPClient>(
      38           0 :       cluster_manager, collector_cluster, collector_reference_host, tracer_stats);
      39             : 
      40           0 :   datadog::tracing::Expected<datadog::tracing::FinalizedTracerConfig> maybe_config =
      41           0 :       datadog::tracing::finalize_config(config);
      42           0 :   if (datadog::tracing::Error* error = maybe_config.if_error()) {
      43           0 :     datadog::tracing::StringView prefix =
      44           0 :         "Unable to configure Datadog tracer. Tracing is now disabled. Error: ";
      45           0 :     config.logger->log_error(error->with_prefix(prefix));
      46           0 :     return std::make_shared<Tracer::ThreadLocalTracer>();
      47           0 :   }
      48             : 
      49           0 :   return std::make_shared<Tracer::ThreadLocalTracer>(*maybe_config);
      50           0 : }
      51             : 
      52             : } // namespace
      53             : 
      54             : Tracer::ThreadLocalTracer::ThreadLocalTracer(const datadog::tracing::FinalizedTracerConfig& config)
      55           0 :     : tracer(config) {}
      56             : 
      57             : Tracer::Tracer(const std::string& collector_cluster, const std::string& collector_reference_host,
      58             :                const datadog::tracing::TracerConfig& config,
      59             :                Upstream::ClusterManager& cluster_manager, Stats::Scope& scope,
      60             :                ThreadLocal::SlotAllocator& thread_local_slot_allocator)
      61             :     : tracer_stats_(makeTracerStats(scope)),
      62             :       thread_local_slot_(
      63           0 :           ThreadLocal::TypedSlot<ThreadLocalTracer>::makeUnique(thread_local_slot_allocator)) {
      64           0 :   const bool allow_added_via_api = true;
      65           0 :   Config::Utility::checkCluster("envoy.tracers.datadog", collector_cluster, cluster_manager,
      66           0 :                                 allow_added_via_api);
      67             : 
      68           0 :   thread_local_slot_->set([&logger = ENVOY_LOGGER(), collector_cluster, collector_reference_host,
      69           0 :                            config, &tracer_stats = tracer_stats_,
      70           0 :                            &cluster_manager](Event::Dispatcher& dispatcher) {
      71           0 :     return makeThreadLocalTracer(config, cluster_manager, collector_cluster,
      72           0 :                                  collector_reference_host, tracer_stats, dispatcher, logger);
      73           0 :   });
      74           0 : }
      75             : 
      76             : // Tracer::TracingDriver
      77             : 
      78             : Tracing::SpanPtr Tracer::startSpan(const Tracing::Config&, Tracing::TraceContext& trace_context,
      79             :                                    const StreamInfo::StreamInfo& stream_info,
      80             :                                    const std::string& operation_name,
      81           0 :                                    Tracing::Decision tracing_decision) {
      82           0 :   ThreadLocalTracer& thread_local_tracer = **thread_local_slot_;
      83           0 :   if (!thread_local_tracer.tracer) {
      84           0 :     return std::make_unique<Tracing::NullSpan>();
      85           0 :   }
      86             : 
      87             :   // The OpenTracing implementation ignored the `Tracing::Config` argument,
      88             :   // so we will as well.
      89           0 :   datadog::tracing::SpanConfig span_config;
      90             :   // The `operation_name` parameter to this function more closely matches
      91             :   // Datadog's concept of "resource name." Datadog's "span name," or "operation
      92             :   // name," instead describes the category of operation being performed, which
      93             :   // here we hard-code.
      94           0 :   span_config.name = "envoy.proxy";
      95           0 :   span_config.resource = operation_name;
      96           0 :   span_config.start = estimateTime(stream_info.startTime());
      97             : 
      98           0 :   TraceContextReader reader{trace_context};
      99           0 :   datadog::tracing::Span span =
     100           0 :       extract_or_create_span(*thread_local_tracer.tracer, span_config, reader);
     101             : 
     102             :   // If we did not extract a sampling decision, and if Envoy is telling us to
     103             :   // drop the trace, then we treat that as a "user drop" (manual override).
     104             :   //
     105             :   // If Envoy is telling us to keep the trace, then we leave it up to the
     106             :   // tracer's internal sampler (which might decide to drop the trace anyway).
     107           0 :   if (!span.trace_segment().sampling_decision().has_value() && !tracing_decision.traced) {
     108           0 :     span.trace_segment().override_sampling_priority(
     109           0 :         int(datadog::tracing::SamplingPriority::USER_DROP));
     110           0 :   }
     111             : 
     112           0 :   return std::make_unique<Span>(std::move(span));
     113           0 : }
     114             : 
     115             : datadog::tracing::Span
     116             : Tracer::extract_or_create_span(datadog::tracing::Tracer& tracer,
     117             :                                const datadog::tracing::SpanConfig& span_config,
     118           0 :                                const datadog::tracing::DictReader& reader) {
     119           0 :   datadog::tracing::Expected<datadog::tracing::Span> maybe_span =
     120           0 :       tracer.extract_span(reader, span_config);
     121           0 :   if (datadog::tracing::Error* error = maybe_span.if_error()) {
     122             :     // We didn't extract a span. Either there's no span to extract, or an
     123             :     // error occurred during extraction.
     124             :     //
     125             :     // Either way, we're going to create a new root span, but if an error
     126             :     // occurred we're going to log the error.
     127           0 :     if (error->code != datadog::tracing::Error::NO_SPAN_TO_EXTRACT) {
     128           0 :       ENVOY_LOG(
     129           0 :           error,
     130           0 :           "Unable to extract span context. Creating a new trace instead. Error [error {}]: {}",
     131           0 :           int(error->code), error->message);
     132           0 :     }
     133             : 
     134           0 :     return tracer.create_span(span_config);
     135           0 :   }
     136             : 
     137           0 :   return std::move(*maybe_span);
     138           0 : }
     139             : 
     140             : } // namespace Datadog
     141             : } // namespace Tracers
     142             : } // namespace Extensions
     143             : } // namespace Envoy

Generated by: LCOV version 1.15