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

          Line data    Source code
       1             : #include "source/extensions/tracers/opentelemetry/opentelemetry_tracer_impl.h"
       2             : 
       3             : #include <string>
       4             : 
       5             : #include "envoy/common/optref.h"
       6             : #include "envoy/config/trace/v3/opentelemetry.pb.h"
       7             : 
       8             : #include "source/common/common/empty_string.h"
       9             : #include "source/common/common/logger.h"
      10             : #include "source/common/config/utility.h"
      11             : #include "source/common/tracing/http_tracer_impl.h"
      12             : #include "source/extensions/tracers/opentelemetry/grpc_trace_exporter.h"
      13             : #include "source/extensions/tracers/opentelemetry/http_trace_exporter.h"
      14             : #include "source/extensions/tracers/opentelemetry/resource_detectors/resource_detector.h"
      15             : #include "source/extensions/tracers/opentelemetry/resource_detectors/resource_provider.h"
      16             : #include "source/extensions/tracers/opentelemetry/samplers/sampler.h"
      17             : #include "source/extensions/tracers/opentelemetry/span_context.h"
      18             : #include "source/extensions/tracers/opentelemetry/span_context_extractor.h"
      19             : #include "source/extensions/tracers/opentelemetry/trace_exporter.h"
      20             : #include "source/extensions/tracers/opentelemetry/tracer.h"
      21             : 
      22             : #include "opentelemetry/proto/collector/trace/v1/trace_service.pb.h"
      23             : #include "opentelemetry/proto/trace/v1/trace.pb.h"
      24             : 
      25             : namespace Envoy {
      26             : namespace Extensions {
      27             : namespace Tracers {
      28             : namespace OpenTelemetry {
      29             : 
      30             : namespace {
      31             : 
      32             : SamplerSharedPtr
      33             : tryCreateSamper(const envoy::config::trace::v3::OpenTelemetryConfig& opentelemetry_config,
      34           0 :                 Server::Configuration::TracerFactoryContext& context) {
      35           0 :   SamplerSharedPtr sampler;
      36           0 :   if (opentelemetry_config.has_sampler()) {
      37           0 :     auto& sampler_config = opentelemetry_config.sampler();
      38           0 :     auto* factory = Envoy::Config::Utility::getFactory<SamplerFactory>(sampler_config);
      39           0 :     if (!factory) {
      40           0 :       throw EnvoyException(fmt::format("Sampler factory not found: '{}'", sampler_config.name()));
      41           0 :     }
      42           0 :     sampler = factory->createSampler(sampler_config.typed_config(), context);
      43           0 :   }
      44           0 :   return sampler;
      45           0 : }
      46             : 
      47           0 : OTelSpanKind getSpanKind(const Tracing::Config& config) {
      48             :   // If this is downstream span that be created by 'startSpan' for downstream request, then
      49             :   // set the span type based on the spawnUpstreamSpan flag and traffic direction:
      50             :   // * If separate tracing span will be created for upstream request, then set span type to
      51             :   //   SERVER because the downstream span should be server span in trace chain.
      52             :   // * If separate tracing span will not be created for upstream request, that means the
      53             :   //   Envoy will not be treated as independent hop in trace chain and then set span type
      54             :   //   based on the traffic direction.
      55           0 :   return (config.spawnUpstreamSpan() ? ::opentelemetry::proto::trace::v1::Span::SPAN_KIND_SERVER
      56           0 :           : config.operationName() == Tracing::OperationName::Egress
      57           0 :               ? ::opentelemetry::proto::trace::v1::Span::SPAN_KIND_CLIENT
      58           0 :               : ::opentelemetry::proto::trace::v1::Span::SPAN_KIND_SERVER);
      59           0 : }
      60             : 
      61             : } // namespace
      62             : 
      63             : Driver::Driver(const envoy::config::trace::v3::OpenTelemetryConfig& opentelemetry_config,
      64             :                Server::Configuration::TracerFactoryContext& context)
      65           0 :     : Driver(opentelemetry_config, context, ResourceProviderImpl{}) {}
      66             : 
      67             : Driver::Driver(const envoy::config::trace::v3::OpenTelemetryConfig& opentelemetry_config,
      68             :                Server::Configuration::TracerFactoryContext& context,
      69             :                const ResourceProvider& resource_provider)
      70             :     : tls_slot_ptr_(context.serverFactoryContext().threadLocal().allocateSlot()),
      71             :       tracing_stats_{OPENTELEMETRY_TRACER_STATS(
      72           0 :           POOL_COUNTER_PREFIX(context.serverFactoryContext().scope(), "tracing.opentelemetry"))} {
      73           0 :   auto& factory_context = context.serverFactoryContext();
      74             : 
      75           0 :   Resource resource = resource_provider.getResource(opentelemetry_config, context);
      76           0 :   ResourceConstSharedPtr resource_ptr = std::make_shared<Resource>(std::move(resource));
      77             : 
      78           0 :   if (opentelemetry_config.has_grpc_service() && opentelemetry_config.has_http_service()) {
      79           0 :     throw EnvoyException(
      80           0 :         "OpenTelemetry Tracer cannot have both gRPC and HTTP exporters configured. "
      81           0 :         "OpenTelemetry tracer will be disabled.");
      82           0 :   }
      83             : 
      84             :   // Create the sampler if configured
      85           0 :   SamplerSharedPtr sampler = tryCreateSamper(opentelemetry_config, context);
      86             : 
      87             :   // Create the tracer in Thread Local Storage.
      88           0 :   tls_slot_ptr_->set([opentelemetry_config, &factory_context, this, resource_ptr,
      89           0 :                       sampler](Event::Dispatcher& dispatcher) {
      90           0 :     OpenTelemetryTraceExporterPtr exporter;
      91           0 :     if (opentelemetry_config.has_grpc_service()) {
      92           0 :       Grpc::AsyncClientFactoryPtr&& factory =
      93           0 :           factory_context.clusterManager().grpcAsyncClientManager().factoryForGrpcService(
      94           0 :               opentelemetry_config.grpc_service(), factory_context.scope(), true);
      95           0 :       const Grpc::RawAsyncClientSharedPtr& async_client_shared_ptr =
      96           0 :           factory->createUncachedRawAsyncClient();
      97           0 :       exporter = std::make_unique<OpenTelemetryGrpcTraceExporter>(async_client_shared_ptr);
      98           0 :     } else if (opentelemetry_config.has_http_service()) {
      99           0 :       exporter = std::make_unique<OpenTelemetryHttpTraceExporter>(
     100           0 :           factory_context.clusterManager(), opentelemetry_config.http_service());
     101           0 :     }
     102           0 :     TracerPtr tracer = std::make_unique<Tracer>(
     103           0 :         std::move(exporter), factory_context.timeSource(), factory_context.api().randomGenerator(),
     104           0 :         factory_context.runtime(), dispatcher, tracing_stats_, resource_ptr, sampler);
     105           0 :     return std::make_shared<TlsTracer>(std::move(tracer));
     106           0 :   });
     107           0 : }
     108             : 
     109             : Tracing::SpanPtr Driver::startSpan(const Tracing::Config& config,
     110             :                                    Tracing::TraceContext& trace_context,
     111             :                                    const StreamInfo::StreamInfo& stream_info,
     112             :                                    const std::string& operation_name,
     113           0 :                                    Tracing::Decision tracing_decision) {
     114             :   // Get tracer from TLS and start span.
     115           0 :   auto& tracer = tls_slot_ptr_->getTyped<Driver::TlsTracer>().tracer();
     116           0 :   SpanContextExtractor extractor(trace_context);
     117           0 :   const auto span_kind = getSpanKind(config);
     118           0 :   if (!extractor.propagationHeaderPresent()) {
     119             :     // No propagation header, so we can create a fresh span with the given decision.
     120           0 :     Tracing::SpanPtr new_open_telemetry_span = tracer.startSpan(
     121           0 :         operation_name, stream_info.startTime(), tracing_decision, trace_context, span_kind);
     122           0 :     return new_open_telemetry_span;
     123           0 :   } else {
     124             :     // Try to extract the span context. If we can't, just return a null span.
     125           0 :     absl::StatusOr<SpanContext> span_context = extractor.extractSpanContext();
     126           0 :     if (span_context.ok()) {
     127           0 :       return tracer.startSpan(operation_name, stream_info.startTime(), span_context.value(),
     128           0 :                               trace_context, span_kind);
     129           0 :     } else {
     130           0 :       ENVOY_LOG(trace, "Unable to extract span context: ", span_context.status());
     131           0 :       return std::make_unique<Tracing::NullSpan>();
     132           0 :     }
     133           0 :   }
     134           0 : }
     135             : 
     136           0 : Driver::TlsTracer::TlsTracer(TracerPtr tracer) : tracer_(std::move(tracer)) {}
     137             : 
     138           0 : Tracer& Driver::TlsTracer::tracer() {
     139           0 :   ASSERT(tracer_);
     140           0 :   return *tracer_;
     141           0 : }
     142             : 
     143             : } // namespace OpenTelemetry
     144             : } // namespace Tracers
     145             : } // namespace Extensions
     146             : } // namespace Envoy

Generated by: LCOV version 1.15