Skip to content

Commit b7d831d

Browse files
committed
remove ExtractionPolicy interface
1 parent 6cd77b3 commit b7d831d

File tree

1 file changed

+90
-140
lines changed

1 file changed

+90
-140
lines changed

src/datadog/tracer.cpp

Lines changed: 90 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -24,180 +24,128 @@ namespace datadog {
2424
namespace tracing {
2525
namespace {
2626

27-
class ExtractionPolicy {
28-
public:
29-
virtual Expected<Optional<std::uint64_t>> trace_id(
30-
const DictReader& headers) = 0;
31-
virtual Expected<Optional<std::uint64_t>> parent_id(
32-
const DictReader& headers) = 0;
33-
virtual Expected<Optional<int>> sampling_priority(
34-
const DictReader& headers) = 0;
35-
virtual Optional<std::string> origin(const DictReader& headers) = 0;
36-
virtual Optional<std::string> trace_tags(const DictReader&) = 0;
27+
Expected<Optional<std::uint64_t>> extract_id_header(const DictReader& headers,
28+
StringView header,
29+
StringView header_kind,
30+
StringView style_name,
31+
int base) {
32+
auto found = headers.lookup(header);
33+
if (!found) {
34+
return nullopt;
35+
}
36+
auto result = parse_uint64(*found, base);
37+
if (auto* error = result.if_error()) {
38+
std::string prefix;
39+
prefix += "Could not extract ";
40+
append(prefix, style_name);
41+
prefix += "-style ";
42+
append(prefix, header_kind);
43+
prefix += "ID from ";
44+
append(prefix, header);
45+
prefix += ": ";
46+
append(prefix, *found);
47+
prefix += ' ';
48+
return error->with_prefix(prefix);
49+
}
50+
return *result;
51+
}
52+
53+
struct ExtractedData {
54+
Optional<std::uint64_t> trace_id;
55+
Optional<std::uint64_t> parent_id;
56+
Optional<std::string> origin;
57+
Optional<std::string> trace_tags;
58+
Optional<int> sampling_priority;
3759
};
3860

39-
class DatadogExtractionPolicy : public ExtractionPolicy {
40-
Expected<Optional<std::uint64_t>> id(const DictReader& headers,
41-
StringView header, StringView kind) {
42-
auto found = headers.lookup(header);
43-
if (!found) {
44-
return nullopt;
45-
}
46-
auto result = parse_uint64(*found, 10);
47-
if (auto* error = result.if_error()) {
48-
std::string prefix;
49-
prefix += "Could not extract Datadog-style ";
50-
append(prefix, kind);
51-
prefix += "ID from ";
52-
append(prefix, header);
53-
prefix += ": ";
54-
append(prefix, *found);
55-
prefix += ' ';
56-
return error->with_prefix(prefix);
57-
}
58-
return *result;
59-
}
61+
Expected<ExtractedData> extract_datadog(const DictReader& headers) {
62+
ExtractedData result;
6063

61-
public:
62-
Expected<Optional<std::uint64_t>> trace_id(
63-
const DictReader& headers) override {
64-
return id(headers, "x-datadog-trace-id", "trace");
64+
auto trace_id =
65+
extract_id_header(headers, "x-datadog-trace-id", "trace", "Datadog", 10);
66+
if (auto* error = trace_id.if_error()) {
67+
return std::move(*error);
6568
}
69+
result.trace_id = *trace_id;
6670

67-
Expected<Optional<std::uint64_t>> parent_id(
68-
const DictReader& headers) override {
69-
return id(headers, "x-datadog-parent-id", "parent span");
71+
auto parent_id = extract_id_header(headers, "x-datadog-parent-id",
72+
"parent span", "Datadog", 10);
73+
if (auto* error = parent_id.if_error()) {
74+
return std::move(*error);
7075
}
76+
result.parent_id = *parent_id;
7177

72-
Expected<Optional<int>> sampling_priority(
73-
const DictReader& headers) override {
74-
const StringView header = "x-datadog-sampling-priority";
75-
auto found = headers.lookup(header);
76-
if (!found) {
77-
return nullopt;
78-
}
79-
auto result = parse_int(*found, 10);
80-
if (auto* error = result.if_error()) {
78+
const StringView sampling_priority_header = "x-datadog-sampling-priority";
79+
if (auto found = headers.lookup(sampling_priority_header)) {
80+
auto sampling_priority = parse_int(*found, 10);
81+
if (auto* error = sampling_priority.if_error()) {
8182
std::string prefix;
8283
prefix += "Could not extract Datadog-style sampling priority from ";
83-
append(prefix, header);
84+
append(prefix, sampling_priority_header);
8485
prefix += ": ";
8586
append(prefix, *found);
8687
prefix += ' ';
8788
return error->with_prefix(prefix);
8889
}
89-
return *result;
90+
result.sampling_priority = *sampling_priority;
9091
}
9192

92-
Optional<std::string> origin(const DictReader& headers) override {
93-
auto found = headers.lookup("x-datadog-origin");
94-
if (found) {
95-
return std::string(*found);
96-
}
97-
return nullopt;
93+
auto origin = headers.lookup("x-datadog-origin");
94+
if (origin) {
95+
result.origin = *origin;
9896
}
9997

100-
Optional<std::string> trace_tags(const DictReader& headers) override {
101-
auto found = headers.lookup("x-datadog-tags");
102-
if (found) {
103-
return std::string(*found);
104-
}
105-
return nullopt;
98+
auto trace_tags = headers.lookup("x-datadog-tags");
99+
if (trace_tags) {
100+
result.trace_tags = *trace_tags;
106101
}
107-
};
108102

109-
class B3ExtractionPolicy : public DatadogExtractionPolicy {
110-
Expected<Optional<std::uint64_t>> id(const DictReader& headers,
111-
StringView header, StringView kind) {
112-
auto found = headers.lookup(header);
113-
if (!found) {
114-
return nullopt;
115-
}
116-
auto result = parse_uint64(*found, 16);
117-
if (auto* error = result.if_error()) {
118-
std::string prefix;
119-
prefix += "Could not extract B3-style ";
120-
append(prefix, kind);
121-
prefix += "ID from ";
122-
append(prefix, header);
123-
prefix += ": ";
124-
append(prefix, *found);
125-
prefix += ' ';
126-
return error->with_prefix(prefix);
127-
}
128-
return *result;
129-
}
103+
return result;
104+
}
105+
106+
Expected<ExtractedData> extract_b3(const DictReader& headers) {
107+
ExtractedData result;
130108

131-
public:
132-
Expected<Optional<std::uint64_t>> trace_id(
133-
const DictReader& headers) override {
134-
return id(headers, "x-b3-traceid", "trace");
109+
auto trace_id = extract_id_header(headers, "x-b3-traceid", "trace", "B3", 16);
110+
if (auto* error = trace_id.if_error()) {
111+
return std::move(*error);
135112
}
113+
result.trace_id = *trace_id;
136114

137-
Expected<Optional<std::uint64_t>> parent_id(
138-
const DictReader& headers) override {
139-
return id(headers, "x-b3-spanid", "parent span");
115+
auto parent_id =
116+
extract_id_header(headers, "x-b3-spanid", "parent span", "B3", 16);
117+
if (auto* error = parent_id.if_error()) {
118+
return std::move(*error);
140119
}
120+
result.parent_id = *parent_id;
141121

142-
Expected<Optional<int>> sampling_priority(
143-
const DictReader& headers) override {
144-
const StringView header = "x-b3-sampled";
145-
auto found = headers.lookup(header);
146-
if (!found) {
147-
return nullopt;
148-
}
149-
auto result = parse_int(*found, 10);
150-
if (auto* error = result.if_error()) {
122+
const StringView sampling_priority_header = "x-b3-sampled";
123+
if (auto found = headers.lookup(sampling_priority_header)) {
124+
auto sampling_priority = parse_int(*found, 10);
125+
if (auto* error = sampling_priority.if_error()) {
151126
std::string prefix;
152127
prefix += "Could not extract B3-style sampling priority from ";
153-
append(prefix, header);
128+
append(prefix, sampling_priority_header);
154129
prefix += ": ";
155130
append(prefix, *found);
156131
prefix += ' ';
157132
return error->with_prefix(prefix);
158133
}
159-
return *result;
134+
result.sampling_priority = *sampling_priority;
160135
}
161-
};
162136

163-
struct ExtractedData {
164-
Optional<std::uint64_t> trace_id;
165-
Optional<std::uint64_t> parent_id;
166-
Optional<std::string> origin;
167-
Optional<std::string> trace_tags;
168-
Optional<int> sampling_priority;
169-
};
170-
171-
Expected<ExtractedData> extract_data(ExtractionPolicy& extract,
172-
const DictReader& reader) {
173-
ExtractedData extracted_data;
174-
175-
auto& [trace_id, parent_id, origin, trace_tags, sampling_priority] =
176-
extracted_data;
177-
178-
auto maybe_trace_id = extract.trace_id(reader);
179-
if (auto* error = maybe_trace_id.if_error()) {
180-
return std::move(*error);
137+
// Origin and trace tags are still extracted, but from the Datadog headers.
138+
auto origin = headers.lookup("x-datadog-origin");
139+
if (origin) {
140+
result.origin = *origin;
181141
}
182-
trace_id = *maybe_trace_id;
183142

184-
origin = extract.origin(reader);
185-
186-
auto maybe_parent_id = extract.parent_id(reader);
187-
if (auto* error = maybe_parent_id.if_error()) {
188-
return std::move(*error);
189-
}
190-
parent_id = *maybe_parent_id;
191-
192-
auto maybe_sampling_priority = extract.sampling_priority(reader);
193-
if (auto* error = maybe_sampling_priority.if_error()) {
194-
return std::move(*error);
143+
auto trace_tags = headers.lookup("x-datadog-tags");
144+
if (trace_tags) {
145+
result.trace_tags = *trace_tags;
195146
}
196-
sampling_priority = *maybe_sampling_priority;
197-
198-
trace_tags = extract.trace_tags(reader);
199147

200-
return extracted_data;
148+
return result;
201149
}
202150

203151
void log_startup_message(Logger& logger, StringView tracer_version_string,
@@ -299,9 +247,8 @@ Expected<Span> Tracer::extract_span(const DictReader& reader,
299247
ExtractedData extracted_data;
300248

301249
for (const auto style : extraction_styles_) {
302-
DatadogExtractionPolicy extract_datadog;
303-
B3ExtractionPolicy extract_b3;
304-
ExtractionPolicy* extract;
250+
using Extractor = decltype(&extract_datadog); // function pointer
251+
Extractor extract;
305252
switch (style) {
306253
case PropagationStyle::DATADOG:
307254
extract = &extract_datadog;
@@ -314,11 +261,14 @@ Expected<Span> Tracer::extract_span(const DictReader& reader,
314261
extracted_data = ExtractedData{};
315262
continue;
316263
}
317-
auto data = extract_data(*extract, reader);
264+
auto data = extract(reader);
318265
if (auto* error = data.if_error()) {
319266
return std::move(*error);
320267
}
321268
extracted_data = *data;
269+
// If the extractor produced a non-null trace ID, then we consider this
270+
// extraction style the one "chosen" for this trace.
271+
// Otherwise, we loop around to the next configured extraction style.
322272
if (extracted_data.trace_id) {
323273
break;
324274
}

0 commit comments

Comments
 (0)