Overview
Datadog APM tracer supports B3 headers extraction and injection for distributed tracing.
Distributed headers injection and extraction is controlled by configuring injection/extraction styles. The supported styles for C++ are:
Injection styles can be configured using:
- Environment Variable:
DD_TRACE_PROPAGATION_STYLE_INJECT="Datadog B3"
The value of the environment variable is a comma (or space) separated list of header styles that are enabled for injection. By default only Datadog injection style is enabled.
Extraction styles can be configured using:
- Environment Variable:
DD_TRACE_PROPAGATION_STYLE_EXTRACT="Datadog B3"
The value of the environment variable is a comma (or space) separated list of header styles that are enabled for extraction. By default only Datadog extraction style is enabled.
If multiple extraction styles are enabled, the extraction attempt is done on the order those styles are configured and first successful extracted value is used.
Inject and extract context for distributed tracing
Distributed tracing can be accomplished by using the Inject
and Extract
methods on the tracer, which accept generic Reader
and Writer
types. Priority sampling (enabled by default) ensures uniform delivery of spans.
// Allows writing propagation headers to a simple map<string, string>.
// Copied from https://github.com/opentracing/opentracing-cpp/blob/master/mocktracer/test/propagation_test.cpp
struct HTTPHeadersCarrier : HTTPHeadersReader, HTTPHeadersWriter {
HTTPHeadersCarrier(std::unordered_map<std::string, std::string>& text_map_)
: text_map(text_map_) {}
expected<void> Set(string_view key, string_view value) const override {
text_map[key] = value;
return {};
}
expected<void> ForeachKey(
std::function<expected<void>(string_view key, string_view value)> f)
const override {
for (const auto& key_value : text_map) {
auto result = f(key_value.first, key_value.second);
if (!result) return result;
}
return {};
}
std::unordered_map<std::string, std::string>& text_map;
};
void example() {
auto tracer = ...
std::unordered_map<std::string, std::string> headers;
HTTPHeadersCarrier carrier(headers);
auto span = tracer->StartSpan("operation_name");
tracer->Inject(span->context(), carrier);
// `headers` now populated with the headers needed to propagate the span.
}
Further Reading
Additional helpful documentation, links, and articles: