Line data Source code
1 : #include "source/extensions/tracers/datadog/span.h" 2 : 3 : #include <utility> 4 : 5 : #include "source/common/tracing/null_span_impl.h" 6 : #include "source/extensions/tracers/datadog/time_util.h" 7 : 8 : #include "absl/strings/str_cat.h" 9 : #include "absl/strings/string_view.h" 10 : #include "datadog/dict_writer.h" 11 : #include "datadog/sampling_priority.h" 12 : #include "datadog/span_config.h" 13 : #include "datadog/trace_segment.h" 14 : 15 : namespace Envoy { 16 : namespace Extensions { 17 : namespace Tracers { 18 : namespace Datadog { 19 : namespace { 20 : 21 : class TraceContextWriter : public datadog::tracing::DictWriter { 22 : public: 23 0 : explicit TraceContextWriter(Tracing::TraceContext& context) : context_(context) {} 24 : 25 0 : void set(datadog::tracing::StringView key, datadog::tracing::StringView value) override { 26 0 : context_.set(key, value); 27 0 : } 28 : 29 : private: 30 : Tracing::TraceContext& context_; 31 : }; 32 : 33 : } // namespace 34 : 35 0 : Span::Span(datadog::tracing::Span&& span) : span_(std::move(span)) {} 36 : 37 0 : const datadog::tracing::Optional<datadog::tracing::Span>& Span::impl() const { return span_; } 38 : 39 0 : void Span::setOperation(absl::string_view operation) { 40 0 : if (!span_) { 41 0 : return; 42 0 : } 43 : 44 : // What Envoy calls the operation name more closely corresponds to what 45 : // Datadog calls the resource name. 46 0 : span_->set_resource_name(operation); 47 0 : } 48 : 49 0 : void Span::setTag(absl::string_view name, absl::string_view value) { 50 0 : if (!span_) { 51 0 : return; 52 0 : } 53 : 54 : // The special "resource.name" tag is a holdover from when the Datadog tracer 55 : // was OpenTracing-based, and so there was no way to set the Datadog resource 56 : // name directly. 57 : // In Envoy, it's still the case that there's no way to set the Datadog 58 : // resource name directly; so, here if the tag name is "resource.name", we 59 : // actually set the resource name instead of setting a tag. 60 0 : if (name == "resource.name") { 61 0 : span_->set_resource_name(value); 62 0 : } else { 63 0 : span_->set_tag(name, value); 64 0 : } 65 0 : } 66 : 67 0 : void Span::log(SystemTime, const std::string&) { 68 : // Datadog spans don't have in-bound "events" or "logs". 69 0 : } 70 : 71 0 : void Span::finishSpan() { span_.reset(); } 72 : 73 : void Span::injectContext(Tracing::TraceContext& trace_context, 74 0 : const Upstream::HostDescriptionConstSharedPtr&) { 75 0 : if (!span_) { 76 0 : return; 77 0 : } 78 : 79 0 : TraceContextWriter writer{trace_context}; 80 0 : span_->inject(writer); 81 0 : } 82 : 83 : Tracing::SpanPtr Span::spawnChild(const Tracing::Config&, const std::string& name, 84 0 : SystemTime start_time) { 85 0 : if (!span_) { 86 : // I don't expect this to happen. This means that `spawnChild` was called 87 : // after `finishSpan`. 88 0 : return std::make_unique<Tracing::NullSpan>(); 89 0 : } 90 : 91 : // The OpenTracing implementation ignored the `Tracing::Config` argument, 92 : // so we will as well. 93 : // The `name` parameter to this function more closely matches Datadog's 94 : // concept of "resource name." Datadog's "span name," or "operation name," 95 : // instead describes the category of operation being performed, which here 96 : // we hard-code. 97 0 : datadog::tracing::SpanConfig config; 98 0 : config.name = "envoy.proxy"; 99 0 : config.resource = name; 100 0 : config.start = estimateTime(start_time); 101 : 102 0 : return std::make_unique<Span>(span_->create_child(config)); 103 0 : } 104 : 105 0 : void Span::setSampled(bool sampled) { 106 0 : if (!span_) { 107 0 : return; 108 0 : } 109 : 110 0 : auto priority = static_cast<int>(sampled ? datadog::tracing::SamplingPriority::USER_KEEP 111 0 : : datadog::tracing::SamplingPriority::USER_DROP); 112 0 : span_->trace_segment().override_sampling_priority(priority); 113 0 : } 114 : 115 0 : std::string Span::getBaggage(absl::string_view) { 116 : // not implemented 117 0 : return std::string{}; 118 0 : } 119 : 120 0 : void Span::setBaggage(absl::string_view, absl::string_view) { 121 : // not implemented 122 0 : } 123 : 124 0 : std::string Span::getTraceIdAsHex() const { 125 0 : if (!span_) { 126 0 : return std::string{}; 127 0 : } 128 0 : return absl::StrCat(absl::Hex(span_->id())); 129 0 : } 130 : 131 : } // namespace Datadog 132 : } // namespace Tracers 133 : } // namespace Extensions 134 : } // namespace Envoy