Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/extensions/tracers/skywalking/skywalking_tracer_impl.cc
Line
Count
Source (jump to first uncovered line)
1
#include "source/extensions/tracers/skywalking/skywalking_tracer_impl.h"
2
3
#include <memory>
4
5
#include "source/common/common/macros.h"
6
#include "source/common/common/utility.h"
7
#include "source/common/http/path_utility.h"
8
9
#include "cpp2sky/propagation.h"
10
11
namespace Envoy {
12
namespace Extensions {
13
namespace Tracers {
14
namespace SkyWalking {
15
16
namespace {
17
constexpr uint32_t DEFAULT_DELAYED_SEGMENTS_CACHE_SIZE = 1024;
18
19
// When the user does not provide any available configuration, in order to ensure that the service
20
// name and instance name are not empty, use this value as the default identifier. In practice,
21
// user should provide accurate configuration as much as possible to avoid using the default value.
22
constexpr absl::string_view DEFAULT_SERVICE_AND_INSTANCE = "EnvoyProxy";
23
} // namespace
24
25
using cpp2sky::createSpanContext;
26
using cpp2sky::SpanContextPtr;
27
28
Driver::Driver(const envoy::config::trace::v3::SkyWalkingConfig& proto_config,
29
               Server::Configuration::TracerFactoryContext& context)
30
    : tracing_stats_(std::make_shared<SkyWalkingTracerStats>(
31
          SkyWalkingTracerStats{SKYWALKING_TRACER_STATS(POOL_COUNTER_PREFIX(
32
              context.serverFactoryContext().scope(), "tracing.skywalking."))})),
33
0
      tls_slot_ptr_(context.serverFactoryContext().threadLocal().allocateSlot()) {
34
0
  loadConfig(proto_config.client_config(), context.serverFactoryContext());
35
0
  tracing_context_factory_ = std::make_unique<TracingContextFactory>(config_);
36
0
  auto& factory_context = context.serverFactoryContext();
37
0
  tls_slot_ptr_->set([proto_config, &factory_context, this](Event::Dispatcher& dispatcher) {
38
0
    TracerPtr tracer = std::make_unique<Tracer>(std::make_unique<TraceSegmentReporter>(
39
0
        factory_context.clusterManager().grpcAsyncClientManager().factoryForGrpcService(
40
0
            proto_config.grpc_service(), factory_context.scope(), true),
41
0
        dispatcher, factory_context.api().randomGenerator(), tracing_stats_,
42
0
        config_.delayed_buffer_size(), config_.token()));
43
0
    return std::make_shared<TlsTracer>(std::move(tracer));
44
0
  });
45
0
}
46
47
Tracing::SpanPtr Driver::startSpan(const Tracing::Config&, Tracing::TraceContext& trace_context,
48
                                   const StreamInfo::StreamInfo&, const std::string&,
49
0
                                   Tracing::Decision decision) {
50
0
  auto& tracer = tls_slot_ptr_->getTyped<Driver::TlsTracer>().tracer();
51
0
  TracingContextPtr tracing_context;
52
  // TODO(shikugawa): support extension span header.
53
0
  auto propagation_header = trace_context.getByKey(skywalkingPropagationHeaderKey());
54
0
  if (!propagation_header.has_value()) {
55
    // Although a sampling flag can be added to the propagation header, it will be ignored by most
56
    // of SkyWalking agent. The agent will enable tracing anyway if it see the propagation header.
57
    // So, if no propagation header is provided and sampling decision of Envoy is false, we need not
58
    // propagate this sampling decision to the upstream. A null span will be used directly.
59
0
    if (!decision.traced) {
60
0
      return std::make_unique<Tracing::NullSpan>();
61
0
    }
62
0
    tracing_context = tracing_context_factory_->create();
63
0
  } else {
64
0
    auto header_value_string = propagation_header.value();
65
66
    // TODO(wbpcode): catching all exceptions is not a good practice. But the cpp2sky library may
67
    // throw exception that not be wrapped by TracerException. See
68
    // https://github.com/SkyAPM/cpp2sky/issues/117. So, we need to catch all exceptions here to
69
    // avoid Envoy crash in the runtime.
70
0
    TRY_NEEDS_AUDIT {
71
0
      SpanContextPtr span_context =
72
0
          createSpanContext(toStdStringView(header_value_string)); // NOLINT(std::string_view)
73
0
      tracing_context = tracing_context_factory_->create(span_context);
74
0
    }
75
0
    END_TRY catch (std::exception& e) {
76
0
      ENVOY_LOG(
77
0
          warn,
78
0
          "New SkyWalking Span/Segment with previous span context cannot be created for error: {}",
79
0
          e.what());
80
0
      if (!decision.traced) {
81
0
        return std::make_unique<Tracing::NullSpan>();
82
0
      }
83
0
      tracing_context = tracing_context_factory_->create();
84
0
    }
85
0
  }
86
87
0
  return tracer.startSpan(trace_context.path(), trace_context.protocol(), tracing_context);
88
0
}
89
90
void Driver::loadConfig(const envoy::config::trace::v3::ClientConfig& client_config,
91
0
                        Server::Configuration::ServerFactoryContext& server_factory_context) {
92
0
  config_.set_service_name(!client_config.service_name().empty()
93
0
                               ? client_config.service_name()
94
0
                               : (!server_factory_context.localInfo().clusterName().empty()
95
0
                                      ? server_factory_context.localInfo().clusterName()
96
0
                                      : DEFAULT_SERVICE_AND_INSTANCE.data()));
97
0
  config_.set_instance_name(!client_config.instance_name().empty()
98
0
                                ? client_config.instance_name()
99
0
                                : (!server_factory_context.localInfo().nodeName().empty()
100
0
                                       ? server_factory_context.localInfo().nodeName()
101
0
                                       : DEFAULT_SERVICE_AND_INSTANCE.data()));
102
0
  config_.set_token(client_config.backend_token());
103
0
  config_.set_delayed_buffer_size(PROTOBUF_GET_WRAPPED_OR_DEFAULT(
104
0
      client_config, max_cache_size, DEFAULT_DELAYED_SEGMENTS_CACHE_SIZE));
105
0
}
106
107
0
Driver::TlsTracer::TlsTracer(TracerPtr tracer) : tracer_(std::move(tracer)) {}
108
109
0
Tracer& Driver::TlsTracer::tracer() {
110
0
  ASSERT(tracer_);
111
0
  return *tracer_;
112
0
}
113
114
} // namespace SkyWalking
115
} // namespace Tracers
116
} // namespace Extensions
117
} // namespace Envoy