|
6 | 6 | #include <datadog/tracer_config.h> |
7 | 7 |
|
8 | 8 | #include <datadog/json.hpp> |
| 9 | +#include <type_traits> |
9 | 10 |
|
10 | 11 | #include "httplib.h" |
11 | 12 | #include "utils.h" |
@@ -106,40 +107,49 @@ void RequestHandler::on_span_start(const httplib::Request& req, |
106 | 107 | res.set_content(response_body.dump(), "application/json"); |
107 | 108 | }; |
108 | 109 |
|
109 | | - if (auto parent_id = |
110 | | - utils::get_if_exists<uint64_t>(request_json, "parent_id")) { |
111 | | - auto parent_span_it = active_spans_.find(*parent_id); |
112 | | - auto parent_header_it = http_headers_.find(*parent_id); |
113 | | - if (parent_span_it != active_spans_.cend()) { |
114 | | - auto span = parent_span_it->second.create_child(span_cfg); |
115 | | - success(span, res); |
116 | | - active_spans_.emplace(span.id(), std::move(span)); |
117 | | - } else if (parent_header_it != http_headers_.cend()) { |
118 | | - auto span = tracer_.extract_span( |
119 | | - utils::HeaderReader(parent_header_it->second), span_cfg); |
120 | | - if (span) { |
121 | | - success(*span, res); |
122 | | - active_spans_.emplace(span->id(), std::move(*span)); |
123 | | - } else { |
124 | | - const auto msg = |
125 | | - "on_span_start: unable to create span from http_headers identified " |
126 | | - "by parent_id " + |
127 | | - std::to_string(*parent_id); |
128 | | - VALIDATION_ERROR(res, msg); |
129 | | - } |
130 | | - } else if (*parent_id != 0) { |
131 | | - const auto msg = "on_span_start: span or http_headers not found for id " + |
132 | | - std::to_string(*parent_id); |
133 | | - VALIDATION_ERROR(res, msg); |
134 | | - } else { |
135 | | - auto span = tracer_.create_span(span_cfg); |
136 | | - success(span, res); |
137 | | - active_spans_.emplace(span.id(), std::move(span)); |
138 | | - } |
139 | | - } else { |
| 110 | + auto parent_id = utils::get_if_exists<uint64_t>(request_json, "parent_id"); |
| 111 | + |
| 112 | + // No `parent_id` field OR parent is `0` -> create a span. |
| 113 | + if (!parent_id || *parent_id == 0) { |
140 | 114 | auto span = tracer_.create_span(span_cfg); |
141 | 115 | success(span, res); |
142 | 116 | active_spans_.emplace(span.id(), std::move(span)); |
| 117 | + return; |
| 118 | + } |
| 119 | + |
| 120 | + // If there's a parent ID -> Extract using the tracing context stored earlier |
| 121 | + // OR -> Create a child span from the span. |
| 122 | + auto parent_span_it = active_spans_.find(*parent_id); |
| 123 | + if (parent_span_it != active_spans_.cend()) { |
| 124 | + auto span = parent_span_it->second.create_child(span_cfg); |
| 125 | + success(span, res); |
| 126 | + active_spans_.emplace(span.id(), std::move(span)); |
| 127 | + return; |
| 128 | + } |
| 129 | + |
| 130 | + auto context_it = tracing_context_.find(*parent_id); |
| 131 | + if (context_it != tracing_context_.cend()) { |
| 132 | + auto span = |
| 133 | + tracer_.extract_span(utils::HeaderReader(context_it->second), span_cfg); |
| 134 | + if (!span) { |
| 135 | + const auto msg = |
| 136 | + "on_span_start: unable to create span from http_headers " |
| 137 | + "identified " |
| 138 | + "by parent_id " + |
| 139 | + std::to_string(*parent_id); |
| 140 | + VALIDATION_ERROR(res, msg); |
| 141 | + return; |
| 142 | + } |
| 143 | + success(*span, res); |
| 144 | + active_spans_.emplace(span->id(), std::move(*span)); |
| 145 | + return; |
| 146 | + } |
| 147 | + |
| 148 | + // Safeguard |
| 149 | + if (*parent_id != 0) { |
| 150 | + const auto msg = "on_span_start: span or http_headers not found for id " + |
| 151 | + std::to_string(*parent_id); |
| 152 | + VALIDATION_ERROR(res, msg); |
143 | 153 | } |
144 | 154 | } |
145 | 155 |
|
@@ -245,38 +255,33 @@ void RequestHandler::on_extract_headers(const httplib::Request& req, |
245 | 255 | VALIDATION_ERROR(res, "on_extract_headers: missing `http_headers` field."); |
246 | 256 | } |
247 | 257 |
|
248 | | - datadog::tracing::SpanConfig span_cfg; |
249 | | - // The span below will not be finished and flushed. |
250 | | - auto span = |
251 | | - tracer_.extract_span(utils::HeaderReader(*http_headers), span_cfg); |
| 258 | + auto span = tracer_.extract_span(utils::HeaderReader(*http_headers)); |
252 | 259 |
|
253 | 260 | if (span.if_error()) { |
254 | | - // clang-format off |
255 | 261 | const auto response_body_fail = nlohmann::json{ |
256 | 262 | {"span_id", nullptr}, |
257 | 263 | }; |
258 | | - // clang-format on |
259 | 264 | res.set_content(response_body_fail.dump(), "application/json"); |
260 | 265 | return; |
261 | 266 | } |
262 | 267 |
|
263 | | - // clang-format off |
264 | 268 | const auto response_body = nlohmann::json{ |
265 | | - {"span_id", span->parent_id().value() }, |
| 269 | + {"span_id", span->parent_id().value()}, |
266 | 270 | }; |
267 | | - // clang-format on |
268 | 271 |
|
269 | | - res.set_content(response_body.dump(), "application/json"); |
270 | | - http_headers_[span->parent_id().value()] = std::move(*http_headers); |
| 272 | + tracing_context_[*span->parent_id()] = std::move(*http_headers); |
| 273 | + |
271 | 274 | // The span below will not be finished and flushed. |
272 | | - extract_headers_spans_.push_back(std::move(*span)); |
| 275 | + blackhole_.emplace_back(std::move(*span)); |
| 276 | + |
| 277 | + res.set_content(response_body.dump(), "application/json"); |
273 | 278 | } |
274 | 279 |
|
275 | 280 | void RequestHandler::on_span_flush(const httplib::Request& /* req */, |
276 | 281 | httplib::Response& res) { |
277 | 282 | scheduler_->flush_telemetry(); |
278 | 283 | active_spans_.clear(); |
279 | | - http_headers_.clear(); |
| 284 | + tracing_context_.clear(); |
280 | 285 | res.status = 200; |
281 | 286 | } |
282 | 287 |
|
|
0 commit comments