8000 move some things around in anticipation of ActiveTrace/TraceSegment c… · DataDog/dd-opentracing-cpp@35ef666 · GitHub
[go: up one dir, main page]

Skip to content

Commit 35ef666

Browse files
authored
move some things around in anticipation of ActiveTrace/TraceSegment changes (#216)
* remove unused forward declaration * propagation.* -> span_context.* * Trace -> TraceData * move PendingTrace into its own component
1 parent 43fd953 commit 35ef666

22 files changed

+268
-206
lines changed

BUILD.bazel

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
cc_library(
22
name = "dd_opentracing_cpp",
33
srcs = [
4-
"src/base64_rfc4648.h",
54
< 10BC0 span class=pl-s>"src/base64_rfc4648.cpp",
6-
"src/bool.h",
5+
"src/base64_rfc4648.h",
76
"src/bool.cpp",
7+
"src/bool.h",
88
"src/clock.h",
99
"src/encoder.cpp",
1010
"src/encoder.h",
@@ -15,8 +15,8 @@ cc_library(
1515
"src/opentracing_external.cpp",
1616
"src/parse_util.cpp",
1717
"src/parse_util.h",
18-
"src/propagation.cpp",
19-
"src/propagation.h",
18+
"src/pending_trace.cpp",
19+
"src/pending_trace.h",
2020
"src/sample.cpp",
2121
"src/sample.h",
2222
"src/sampling_mechanism.cpp",
@@ -27,9 +27,13 @@ cc_library(
2727
"src/span.h",
2828
"src/span_buffer.cpp",
2929
"src/span_buffer.h",
30-
"src/tags.cpp",
30+
"src/span_context.cpp",
31+
"src/span_context.h",
3132
"src/tag_propagation.cpp",
3233
"src/tag_propagation.h",
34+
"src/tags.cpp",
35+
"src/trace_data.cpp",
36+
"src/trace_data.h",
3337
"src/tracer.cpp",
3438
"src/tracer.h",
3539
"src/tracer_options.cpp",

src/agent_writer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ void AgentWriter::stop() {
119119
worker_->join();
120120
}
121121

122-
void AgentWriter::write(Trace trace) {
122+
void AgentWriter::write(TraceData trace) {
123123
std::unique_lock<std::mutex> lock(mutex_);
124124
if (stop_writing_) {
125125
return;

src/agent_writer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class AgentWriter : public Writer {
3838
// Does not flush on destruction, buffered traces may be lost. Stops all threads.
3939
~AgentWriter() override;
4040

41-
void write(Trace trace) override;
41+
void write(TraceData trace) override;
4242

4343
// Send all buffered Traces to the destination now. Will block until sending is complete, or
4444
// timeout passes.

src/encoder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const std::string AgentHttpEncoder::payload() {
5555
return buffer_.str();
5656
}
5757

58-
void AgentHttpEncoder::addTrace(Trace trace) { traces_.push_back(std::move(trace)); }
58+
void AgentHttpEncoder::addTrace(TraceData trace) { traces_.push_back(std::move(trace)); }
5959

6060
void AgentHttpEncoder::handleResponse(const std::string& response) {
6161
if (sampler_ != nullptr) {

src/encoder.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,13 @@
88
#include <sstream>
99

1010
#include "logger.h"
11+
#include "trace_data.h"
1112

1213
namespace datadog {
1314
namespace opentracing {
1415

1516
class Logger;
1617
class RulesSampler;
17-
struct SpanData;
18-
using Trace = std::unique_ptr<std::vector<std::unique_ptr<SpanData>>>;
1918

2019
class AgentHttpEncoder : public TraceEncoder {
2120
public:
@@ -31,12 +30,12 @@ class AgentHttpEncoder : public TraceEncoder {
3130
// Returns the encoded payload from the collection of traces.
3231
const std::string payload() override;
3332
void handleResponse(const std::string& response) override;
34-
void addTrace(Trace trace);
33+
void addTrace(TraceData trace);
3534

3635
private:
3736
// Holds the headers that are used for all HTTP requests.
3837
std::map<std::string, std::string> common_headers_;
39-
std::deque<Trace> traces_;
38+
std::deque<TraceData> traces_;
4039
std::stringstream buffer_;
4140
// Responses from the Agent may contain configuration for the sampler. May be nullptr if priority
4241
// sampling is not enabled.

src/pending_trace.cpp

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#include "pending_trace.h"
2+
3+
#include <cassert>
4+
5+
#include "span.h"
6+
7+
namespace datadog {
8+
namespace opentracing {
9+
namespace {
10+
11+
const std::string sampling_priority_metric = "_sampling_priority_v1";
12+
const std::string datadog_origin_tag = "_dd.origin";
13+
const std::string datadog_hostname_tag = "_dd.hostname";
14+
const std::string datadog_upstream_services_tag = "_dd.p.upstream_services";
15+
const std::string datadog_propagation_error_tag = "_dd.propagation_error";
16+
const std::string event_sample_rate_metric = "_dd1.sr.eausr";
17+
const std::string rules_sampler_applied_rate = "_dd.rule_psr";
18+
const std::string rules_sampler_limiter_rate = "_dd.limit_psr";
19+
const std::string priority_sampler_applied_rate = "_dd.agent_psr";
20+
21+
// Return whether the specified `span` is without a parent among the specified
22+
// `all_spans_in_trace`.
23+
bool is_root(const SpanData& span, const std::unordered_set<uint64_t>& all_spans_in_trace) {
24+
return
25+
// root span
26+
span.parent_id == 0 ||
27+
// local root span of a distributed trace
28+
all_spans_in_trace.find(span.parent_id) == all_spans_in_trace.end();
29+
}
30+
31+
// Alter the specified `span` to prepare it for encoding with the specified
32+
// `trace`.
33+
void finish_span(const PendingTrace& trace, SpanData& span) {
34+
// Propagate the trace origin in every span, if present. This allows, for
35+
// example, sampling to vary with the trace's stated origin.
36+
if (!trace.origin.empty()) {
37+
span.meta[datadog_origin_tag] = trace.origin;
38+
}
39+
}
40+
41+
// Alter the specified root (i.e. having no parent in the local trace) `span`
42+
// to prepare it for encoding with the specified `trace`.
43+
void finish_root_span(PendingTrace& trace, SpanData& span) {
44+
// Check for sampling.
45+
if (trace.sampling_priority != nullptr) {
46+
span.metrics[sampling_priority_metric] = static_cast<int>(*trace.sampling_priority);
47+
// The span's datadog origin tag is set in `finish_span`, below.
48+
}
49+
if (!trace.hostname.empty()) {
50+
span.meta[datadog_hostname_tag] = trace.hostname;
51+
}
52+
if (!std::isnan(trace.analytics_rate) &&
53+
span.metrics.find(event_sample_rate_metric) == span.metrics.end()) {
54+
span.metrics[event_sample_rate_metric] = trace.analytics_rate;
55+
}
56+
if (!std::isnan(trace.sample_result.rule_rate)) {
57+
span.metrics[rules_sampler_applied_rate] = trace.sample_result.rule_rate;
58+
}
59+
if (!std::isnan(trace.sample_result.limiter_rate)) {
60+
span.metrics[rules_sampler_limiter_rate] = trace.sample_result.limiter_rate;
61+
}
62+
if (!std::isnan(trace.sample_result.priority_rate)) {
63+
span.metrics[priority_sampler_applied_rate] = trace.sample_result.priority_rate;
64+
}
65+
trace.applySamplingDecisionToUpstreamServices();
66+
span.meta.insert(trace.trace_tags.begin(), trace.trace_tags.end());
67+
if (!trace.propagation_error.empty()) {
68+
span.meta[datadog_propagation_error_tag] = trace.propagation_error;
69+
}
70+
// Forward to the finisher that applies to all spans (not just root spans).
71+
finish_span(trace, span);
72+
}
73+
74+
} // namespace
75+
76+
PendingTrace::PendingTrace(std::shared_ptr<const Logger> logger, uint64_t trace_id)
77+
: logger(logger),
78+
trace_id(trace_id),
79+
finished_spans(TraceData{new std::vector<std::unique_ptr<SpanData>>()}),
80+
all_spans() {}
81+
82+
PendingTrace::PendingTrace(std::shared_ptr<const Logger> logger, uint64_t trace_id,
83+
std::unique_ptr<SamplingPriority> sampling_priority)
84+
: logger(logger),
85+
trace_id(trace_id),
86+
finished_spans(TraceData{new std::vector<std::unique_ptr<SpanData>>()}),
87+
all_spans(),
88+
sampling_priority(std::move(sampling_priority)) {}
89+
90+
void PendingTrace::finish() {
91+
// Apply changes to spans, in particular treating the root / local-root
92+
// span as special.
93+
for (const auto& span : *finished_spans) {
94+
if (is_root(*span, all_spans)) {
95+
finish_root_span(*this, *span);
96+
} else {
97+
finish_span(*this, *span);
98+
}
99+
}
100+
}
101+
102+
void PendingTrace::applySamplingDecisionToUpstreamServices() {
103+
if (applied_sampling_decision_to_upstream_services || sampling_decision_extracted ||
104+
sampling_priority == nullptr) {
105+
// We did not make the sampling decision, or we've already done this.
106+
return;
107+
}
108+
109+
// In unit tests, we sometimes don't have a service name. In those cases,
110+
// omit our `UpstreamService` entry (those tests are not looking for the
111+
// corresponding tag).
112+
if (service.empty()) {
113+
return;
114+
}
115+
116+
// If we have a sampling priority and `sampling_decision_extracted == false`,
117+
// then the sampling priority was determined by this tracer, and so we will
118+
// have set a corresponding sampling mechanism.
119+
assert(sample_result.sampling_mechanism != nullptr);
120+
121+
UpstreamService this_service;
122+
this_service.service_name = service;
123+
this_service.sampling_priority = *sampling_priority;
124+
this_service.sampling_mechanism = int(sample_result.sampling_mechanism.get<SamplingMechanism>());
125+
this_service.sampling_rate = sample_result.applied_rate;
126+
127+
appendUpstreamService(trace_tags[upstream_services_tag], this_service);
128+
applied_sampling_decision_to_upstream_services = true;
129+
}
130+
131+
} // namespace opentracing
132+
} // namespace datadog

src/pending_trace.h

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#ifndef DD_OPENTRACING_PENDING_TRACE_H
2+
#define DD_OPENTRACING_PENDING_TRACE_H
3+
4+
#include <memory>
5+
#include <unordered_set>
6+
7+
#include "sample.h"
8+
#include "sampling_priority.h"
9+
#include "trace_data.h"
10+
11+
namespace datadog {
12+
namespace opentracing {
13+
14+
class Logger;
15+
16+
// `PendingTrace` is an implementation detail of `SpanBuffer`. A
17+
// `PendingTrace` contains all of the information associated with a trace as it
18+
// is happening. When all of the spans in a `PendingTrace` have finished,
19+
// `SpanBuffer` finalizes the spans and writes them (e.g. to the agent)
20+
// together as a trace.
21+
struct PendingTrace {
22+
PendingTrace(std::shared_ptr<const Logger> logger, uint64_t trace_id);
23+
24+
// This constructor is only used in propagation tests.
25+
PendingTrace(std::shared_ptr<const Logger> logger, uint64_t trace_id,
26+
std::unique_ptr<SamplingPriority> sampling_priority);
27+
28+
void finish();
29+
// If this tracer did not inherit a sampling decision from an upstream
30+
// service, but instead made a sampling decision, then append an
31+
// `UpstreamService` record to the "_dd.p.upstream_services" member of
32+
// `trace_tags`. Note that this function is idempotent.
33+
void applySamplingDecisionToUpstreamServices();
34+
35+
std::shared_ptr<const Logger> logger;
36+
uint64_t trace_id;
37+
TraceData finished_spans;
38+
std::unordered_set<uint64_t> all_spans;
39+
OptionalSamplingPriority sampling_priority;
40+
bool sampling_priority_locked = false;
41+
std::string origin;
42+
std::string hostname;
43+
double analytics_rate;
44+
SampleResult sample_result;
45+
// `trace_tags` are tags that are associated with the entire local trace,
46+
// rather than with a single span. Some other tags are added to the local
47+
// root span when the trace chunk is sent to the agent (see
48+
// `finish_root_span` in `span_buffer.cpp`). In addition to those tags,
49+
// `trace_tags` are similarly added.
50+
// `trace_tags` originate from extracted trace context (`SpanContext`). Some
51+
// trace tags require special handling, e.g. "_dd.p.upstream_services".
52+
std::unordered_map<std::string, std::string> trace_tags;
53+
// `service` is the name of the service associated with this trace. If the
54+
// service name changes (such as by calling `Span::setServiceName`), then
55+
// this is the most recent value.
56+
std::string service;
57+
// If an error occurs while propagating trace tags (see
58+
// `SpanBuffer::serializeTraceTags`), then the "_dd.propagation_error"
59+
// tag will be set on the local root span to the value of
60+
// `propagation_error`. If no error occurs, then `propagation_error` will be
61+
// empty and the "_dd.propagation_error" tag will not be added.
62+
std::string propagation_error;
63+
// `sampling_decision_extracted` is whether `sampling_priority` was
64+
// determined by a decision within this tracer (`true`), or inherited from an
65+
// upstream service when span context was extracted (`false`), or has not yet
66+
// been decided (`false`).
67+
bool sampling_decision_extracted = false;
68+
// `applied_sampling_decision_to_upstream_services` is whether the function
69+
// `applySamplingDecisionToUpstreamServices` has done its work.
70+
bool applied_sampling_decision_to_upstream_services = false;
71+
};
72+
73+
} // namespace opentracing
74+
} // namespace datadog
75+
76+
#endif

src/sample.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
#include <nlohmann/json.hpp>
1818

1919
#include "limiter.h"
20-
#include "propagation.h"
2120
#include "sampling_mechanism.h"
2221
#include "sampling_priority.h"
22+
#include "span_context.h"
2323

2424
namespace ot = opentracing;
2525
using json = nlohmann::json;

src/span.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
#include "clock.h"
77
#include "logger.h"
8 8AF6 -
#include "propagation.h"
8+
#include "span_context.h"
99

1010
namespace ot = opentracing;
1111

@@ -16,7 +16,9 @@ class Tracer;
1616
class SpanBuffer;
1717
typedef std::function<uint64_t()> IdProvider; // See tracer.h
1818

19-
// Contains data that describes a Span.
19+
// `SpanData` contains the data fields associated with a `Span`. A `Span`
20+
// additionally contains handles to mechanisms it needs in order to implement
21+
// its methods (e.g. the logger, the tracer). `SpanData` is just the data.
2022
struct SpanData {
2123
~SpanData() = default;
2224

0 commit comments

Comments
 (0)
0