Line data Source code
1 : #include "span.h" 2 : 3 : #include <cassert> 4 : #include <string> 5 : 6 : #include "dict_writer.h" 7 : #include "optional.h" 8 : #include "span_config.h" 9 : #include "span_data.h" 10 : #include "string_view.h" 11 : #include "tags.h" 12 : #include "trace_segment.h" 13 : 14 : namespace datadog { 15 : namespace tracing { 16 : 17 82916 : Span::Span(SpanData* data, const std::shared_ptr<TraceSegment>& trace_segment, 18 : const std::function<std::uint64_t()>& generate_span_id, 19 82916 : const Clock& clock) 20 82916 : : trace_segment_(trace_segment), 21 82916 : data_(data), 22 82916 : generate_span_id_(generate_span_id), 23 82916 : clock_(clock) { 24 82916 : assert(trace_segment_); 25 82916 : assert(data_); 26 82916 : assert(generate_span_id_); 27 82916 : assert(clock_); 28 82916 : } 29 : 30 165972 : Span::~Span() { 31 83056 : if (!trace_segment_) { 32 : // We were moved from. 33 140 : return; 34 : } 35 : 36 82916 : if (end_time_) { 37 1 : data_->duration = *end_time_ - data_->start.tick; 38 : } else { 39 82915 : const auto now = clock_(); 40 82915 : data_->duration = now - data_->start; 41 : } 42 : 43 82916 : trace_segment_->span_finished(); 44 83336 : } 45 : 46 41 : Span Span::create_child(const SpanConfig& config) const { 47 41 : auto span_data = std::make_unique<SpanData>(); 48 41 : span_data->apply_config(trace_segment_->defaults(), config, clock_); 49 41 : span_data->trace_id = data_->trace_id; 50 41 : span_data->parent_id = data_->span_id; 51 41 : span_data->span_id = generate_span_id_(); 52 : 53 41 : const auto span_data_ptr = span_data.get(); 54 41 : trace_segment_->register_span(std::move(span_data)); 55 82 : return Span(span_data_ptr, trace_segment_, generate_span_id_, clock_); 56 41 : } 57 : 58 78 : Span Span::create_child() const { return create_child(SpanConfig{}); } 59 : 60 32 : void Span::inject(DictWriter& writer) const { 61 32 : trace_segment_->inject(writer, *data_); 62 32 : } 63 : 64 2 : std::uint64_t Span::id() const { return data_->span_id; } 65 : 66 31 : TraceID Span::trace_id() const { return data_->trace_id; } 67 : 68 19 : Optional<std::uint64_t> Span::parent_id() const { 69 19 : if (data_->parent_id == 0) { 70 3 : return nullopt; 71 : } 72 16 : return data_->parent_id; 73 : } 74 : 75 1 : TimePoint Span::start_time() const { return data_->start; } 76 : 77 7 : bool Span::error() const { return data_->error; } 78 : 79 1 : const std::string& Span::service_name() const { return data_->service; } 80 : 81 1 : const std::string& Span::service_type() const { return data_->service_type; } 82 : 83 1 : const std::string& Span::name() const { return data_->name; } 84 : 85 1 : const std::string& Span::resource_name() const { return data_->resource; } 86 : 87 11 : Optional<StringView> Span::lookup_tag(StringView name) const { 88 11 : if (tags::is_internal(name)) { 89 3 : return nullopt; 90 : } 91 : 92 8 : const auto found = data_->tags.find(std::string(name)); 93 8 : if (found == data_->tags.end()) { 94 4 : return nullopt; 95 : } 96 4 : return found->second; 97 : } 98 : 99 42 : void Span::set_tag(StringView name, StringView value) { 100 42 : if (!tags::is_internal(name)) { 101 40 : data_->tags.insert_or_assign(std::string(name), std::string(value)); 102 : } 103 42 : } 104 : 105 3 : void Span::remove_tag(StringView name) { 106 3 : if (!tags::is_internal(name)) { 107 3 : data_->tags.erase(std::string(name)); 108 : } 109 3 : } 110 : 111 1 : void Span::set_service_name(StringView service) { 112 1 : assign(data_->service, service); 113 1 : } 114 : 115 1 : void Span::set_service_type(StringView type) { 116 1 : assign(data_->service_type, type); 117 1 : } 118 : 119 25 : void Span::set_resource_name(StringView resource) { 120 25 : assign(data_->resource, resource); 121 25 : } 122 : 123 2 : void Span::set_error(bool is_error) { 124 2 : data_->error = is_error; 125 2 : if (!is_error) { 126 1 : data_->tags.erase("error.message"); 127 1 : data_->tags.erase("error.type"); 128 : } 129 2 : } 130 : 131 3 : void Span::set_error_message(StringView message) { 132 3 : data_->error = true; 133 3 : data_->tags.insert_or_assign("error.message", std::string(message)); 134 3 : } 135 : 136 3 : void Span::set_error_type(StringView type) { 137 3 : data_->error = true; 138 3 : data_->tags.insert_or_assign("error.type", std::string(type)); 139 3 : } 140 : 141 3 : void Span::set_error_stack(StringView type) { 142 3 : data_->error = true; 143 3 : data_->tags.insert_or_assign("error.stack", std::string(type)); 144 3 : } 145 : 146 25 : void Span::set_name(StringView value) { assign(data_->name, value); } 147 : 148 1 : void Span::set_end_time(std::chrono::steady_clock::time_point end_time) { 149 1 : end_time_ = end_time; 150 1 : } 151 : 152 34 : TraceSegment& Span::trace_segment() { return *trace_segment_; } 153 : 154 18 : const TraceSegment& Span::trace_segment() const { return *trace_segment_; } 155 : 156 : } // namespace tracing 157 : } // namespace datadog