]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentracing-cpp/mocktracer/src/mock_span.cpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / jaegertracing / opentracing-cpp / mocktracer / src / mock_span.cpp
1 #include "mock_span.h"
2 #include <cstdio>
3 #include <random>
4
5 namespace opentracing {
6 BEGIN_OPENTRACING_ABI_NAMESPACE
7 namespace mocktracer {
8
9 static uint64_t GenerateId() {
10 static thread_local std::mt19937_64 rand_source{std::random_device()()};
11 return static_cast<uint64_t>(rand_source());
12 }
13
14 static std::tuple<SystemTime, SteadyTime> ComputeStartTimestamps(
15 const SystemTime& start_system_timestamp,
16 const SteadyTime& start_steady_timestamp) {
17 // If neither the system nor steady timestamps are set, get the tme from the
18 // respective clocks; otherwise, use the set timestamp to initialize the
19 // other.
20 if (start_system_timestamp == SystemTime() &&
21 start_steady_timestamp == SteadyTime()) {
22 return std::tuple<SystemTime, SteadyTime>{SystemClock::now(),
23 SteadyClock::now()};
24 }
25 if (start_system_timestamp == SystemTime()) {
26 return std::tuple<SystemTime, SteadyTime>{
27 opentracing::convert_time_point<SystemClock>(start_steady_timestamp),
28 start_steady_timestamp};
29 }
30 if (start_steady_timestamp == SteadyTime()) {
31 return std::tuple<SystemTime, SteadyTime>{
32 start_system_timestamp,
33 opentracing::convert_time_point<SteadyClock>(start_system_timestamp)};
34 }
35 return std::tuple<SystemTime, SteadyTime>{start_system_timestamp,
36 start_steady_timestamp};
37 }
38
39 static bool SetSpanReference(
40 const std::pair<SpanReferenceType, const SpanContext*>& reference,
41 std::map<std::string, std::string>& baggage,
42 SpanReferenceData& reference_data) {
43 reference_data.reference_type = reference.first;
44 if (reference.second == nullptr) {
45 return false;
46 }
47 auto referenced_context =
48 dynamic_cast<const MockSpanContext*>(reference.second);
49 if (referenced_context == nullptr) {
50 return false;
51 }
52 reference_data.trace_id = referenced_context->trace_id();
53 reference_data.span_id = referenced_context->span_id();
54
55 referenced_context->ForeachBaggageItem(
56 [&baggage](const std::string& key, const std::string& value) {
57 baggage[key] = value;
58 return true;
59 });
60
61 return true;
62 }
63
64 MockSpan::MockSpan(std::shared_ptr<const Tracer>&& tracer, Recorder* recorder,
65 string_view operation_name, const StartSpanOptions& options)
66 : tracer_{std::move(tracer)}, recorder_{recorder} {
67 data_.operation_name = operation_name;
68
69 // Set start timestamps
70 std::tie(data_.start_timestamp, start_steady_) = ComputeStartTimestamps(
71 options.start_system_timestamp, options.start_steady_timestamp);
72
73 // Set references
74 SpanContextData span_context_data;
75 for (auto& reference : options.references) {
76 SpanReferenceData reference_data;
77 if (!SetSpanReference(reference, span_context_data.baggage,
78 reference_data)) {
79 continue;
80 }
81 data_.references.push_back(reference_data);
82 }
83
84 // Set tags
85 for (auto& tag : options.tags) {
86 data_.tags[tag.first] = tag.second;
87 }
88
89 // Set span context
90 span_context_data.trace_id =
91 data_.references.empty() ? GenerateId() : data_.references[0].trace_id;
92 span_context_data.span_id = GenerateId();
93 span_context_ = MockSpanContext{std::move(span_context_data)};
94 }
95
96 MockSpan::~MockSpan() {
97 if (!is_finished_) {
98 Finish();
99 }
100 }
101
102 void MockSpan::FinishWithOptions(const FinishSpanOptions& options) noexcept {
103 // Ensure the span is only finished once.
104 if (is_finished_.exchange(true)) {
105 return;
106 }
107
108 data_.logs.reserve(data_.logs.size() + options.log_records.size());
109 for (auto& log_record : options.log_records) {
110 data_.logs.push_back(log_record);
111 }
112
113 auto finish_timestamp = options.finish_steady_timestamp;
114 if (finish_timestamp == SteadyTime{}) {
115 finish_timestamp = SteadyClock::now();
116 }
117
118 data_.duration = finish_timestamp - start_steady_;
119
120 span_context_.CopyData(data_.span_context);
121
122 if (recorder_ != nullptr) {
123 recorder_->RecordSpan(std::move(data_));
124 }
125 }
126
127 void MockSpan::SetOperationName(string_view name) noexcept try {
128 std::lock_guard<std::mutex> lock_guard{mutex_};
129 data_.operation_name = name;
130 } catch (const std::exception& e) {
131 // Ignore operation
132 fprintf(stderr, "Failed to set operation name: %s\n", e.what());
133 }
134
135 void MockSpan::SetTag(string_view key,
136 const opentracing::Value& value) noexcept try {
137 std::lock_guard<std::mutex> lock_guard{mutex_};
138 data_.tags[key] = value;
139 } catch (const std::exception& e) {
140 // Ignore upon error.
141 fprintf(stderr, "Failed to set tag: %s\n", e.what());
142 }
143
144 void MockSpan::Log(
145 std::initializer_list<std::pair<string_view, Value>> fields) noexcept {
146 Log(SystemClock::now(), fields);
147 }
148
149 void MockSpan::Log(
150 SystemTime timestamp,
151 std::initializer_list<std::pair<string_view, Value>> fields) noexcept try {
152 LogRecord log_record;
153 log_record.timestamp = timestamp;
154 log_record.fields.reserve(fields.size());
155 for (auto& field : fields) {
156 log_record.fields.emplace_back(field.first, field.second);
157 }
158 std::lock_guard<std::mutex> lock_guard{mutex_};
159 data_.logs.emplace_back(std::move(log_record));
160 } catch (const std::exception& e) {
161 // Drop log record upon error.
162 fprintf(stderr, "Failed to log: %s\n", e.what());
163 }
164
165 void MockSpan::Log(
166 SystemTime timestamp,
167 const std::vector<std::pair<string_view, Value>>& fields) noexcept try {
168 LogRecord log_record;
169 log_record.timestamp = timestamp;
170 log_record.fields.reserve(fields.size());
171 for (auto& field : fields) {
172 log_record.fields.emplace_back(field.first, field.second);
173 }
174 std::lock_guard<std::mutex> lock_guard{mutex_};
175 data_.logs.emplace_back(std::move(log_record));
176 } catch (const std::exception& e) {
177 // Drop log record upon error.
178 fprintf(stderr, "Failed to log: %s\n", e.what());
179 }
180
181 void MockSpan::SetBaggageItem(string_view restricted_key,
182 string_view value) noexcept try {
183 std::lock_guard<std::mutex> lock_guard{span_context_.baggage_mutex_};
184 span_context_.data_.baggage.emplace(restricted_key, value);
185 } catch (const std::exception& e) {
186 // Drop baggage item upon error.
187 fprintf(stderr, "Failed to set baggage item: %s\n", e.what());
188 }
189
190 std::string MockSpan::BaggageItem(string_view restricted_key) const
191 noexcept try {
192 std::lock_guard<std::mutex> lock_guard{span_context_.baggage_mutex_};
193 auto lookup = span_context_.data_.baggage.find(restricted_key);
194 if (lookup != span_context_.data_.baggage.end()) {
195 return lookup->second;
196 }
197 return {};
198 } catch (const std::exception& e) {
199 // Return empty string upon error.
200 fprintf(stderr, "Failed to retrieve baggage item: %s\n", e.what());
201 return {};
202 }
203
204 } // namespace mocktracer
205 END_OPENTRACING_ABI_NAMESPACE
206 } // namespace opentracing