Skip to content

Commit

Permalink
heterogeneous extraction, untested
Browse files Browse the repository at this point in the history
  • Loading branch information
dgoffredo committed Nov 17, 2023
1 parent a0b50db commit ec3f06e
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 12 deletions.
50 changes: 50 additions & 0 deletions src/datadog/extraction_util.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "extraction_util.h"

#include <algorithm>
#include <cstdint>
#include <sstream>
#include <string>
Expand Down Expand Up @@ -229,5 +230,54 @@ void AuditedReader::visit(
});
}

ExtractedData merge(const std::vector<ExtractedData>& contexts) {
ExtractedData result;

const auto found = std::find_if(
contexts.begin(), contexts.end(),
[](const ExtractedData& data) { return data.trace_id.has_value(); });

if (found == contexts.end()) {
// Nothing extracted a trace ID. Return the first context that includes a
// parent ID, if any, or otherwise just return an empty `ExtractedData`.
// The purpose of looking for a parent ID is to allow for the error
// "extracted a parent ID without a trace ID," if that's what happened.
const auto other = std::find_if(
contexts.begin(), contexts.end(),
[](const ExtractedData& data) { return data.parent_id.has_value(); });
if (other != contexts.end()) {
result = *other;
}
return result;
}

// `found` refers to the first extracted context that yielded a trace ID.
// This will be our main context.
//
// If the style of `found` is not W3C, then examine the remaining contexts
// for W3C-style tracestate that we might want to include in `result`.
result = *found;
if (result.style == PropagationStyle::W3C) {
return result;
}

const auto other =
std::find_if(found, contexts.end(), [&](const ExtractedData& data) {
return data.style == PropagationStyle::W3C &&
data.trace_id == found->trace_id;
});

if (other != contexts.end()) {
result.additional_w3c_tracestate = other->additional_w3c_tracestate;
result.additional_datadog_w3c_tracestate =
other->additional_datadog_w3c_tracestate;
result.headers_examined.insert(result.headers_examined.end(),
other->headers_examined.begin(),
other->headers_examined.end());
}

return result;
}

} // namespace tracing
} // namespace datadog
7 changes: 7 additions & 0 deletions src/datadog/extraction_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,12 @@ struct AuditedReader : public DictReader {
visitor) const override;
};

// Combine the specified trace `contexts`, each of which was extracted in a
// particular propagation style, into one `ExtractedData` that includes fields
// from compatible elements of `contexts`, and return the resulting
// `ExtractedData`. The order of the elements of `contexts` must correspond to
// the order of the configured extraction propagation styles.
ExtractedData merge(const std::vector<ExtractedData>& contexts);

} // namespace tracing
} // namespace datadog
18 changes: 6 additions & 12 deletions src/datadog/tracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ Expected<Span> Tracer::extract_span(const DictReader& reader,
AuditedReader audited_reader{reader};

auto span_data = std::make_unique<SpanData>();
ExtractedData extracted_data;
std::vector<ExtractedData> extracted_contexts;

for (const auto style : extraction_styles_) {
using Extractor = decltype(&extract_datadog); // function pointer
Expand All @@ -159,19 +159,13 @@ Expected<Span> Tracer::extract_span(const DictReader& reader,
return error->with_prefix(
extraction_error_prefix(style, audited_reader.entries_found));
}
extracted_data = *data;
extracted_data.headers_examined = audited_reader.entries_found;
// If the extractor produced a non-null trace ID, then we consider this
// extraction style the one "chosen" for this trace.
// Otherwise, we loop around to the next configured extraction style.
if (extracted_data.trace_id) {
break;
}
extracted_contexts.push_back(std::move(*data));
extracted_contexts.back().headers_examined = audited_reader.entries_found;
}

auto& [trace_id, parent_id, origin, trace_tags, sampling_priority,
additional_w3c_tracestate, additional_datadog_w3c_tracestate, style,
headers_examined] = extracted_data;
auto [trace_id, parent_id, origin, trace_tags, sampling_priority,
additional_w3c_tracestate, additional_datadog_w3c_tracestate, style,
headers_examined] = merge(extracted_contexts);

// Some information might be missing.
// Here are the combinations considered:
Expand Down

0 comments on commit ec3f06e

Please sign in to comment.