Get started
Logs monitoring
Exceptions and errors
Kubernetes
Migrating from Datadog
Migrating from NewRelic
Hosted
C++
.NET
Erlang/Elixir
Golang
Java
JavaScript
PHP
Python
Ruby
Rust
Swift
OpenTelemetry Context Propagation [C++]
This guide covers C++ implementation of context propagation. For concepts, see OpenTelemetry Context Propagation.
What is traceparent header?
The traceparent HTTP header contains trace context information:
text
traceparent: 00-80e1afed08e019fc1110464cfa66635c-7a085853722dc6d2-01
Format: version-trace_id-span_id-trace_flags
Setting up propagators
cpp
#include "opentelemetry/context/propagation/global_propagator.h"
#include "opentelemetry/trace/propagation/http_trace_context.h"
namespace propagation = opentelemetry::context::propagation;
namespace trace_prop = opentelemetry::trace::propagation;
void InitPropagator() {
propagation::GlobalTextMapPropagator::SetGlobalPropagator(
opentelemetry::nostd::shared_ptr<propagation::TextMapPropagator>(
new trace_prop::HttpTraceContext()));
}
HTTP Header Carrier
cpp
#include "opentelemetry/context/propagation/text_map_propagator.h"
#include <map>
namespace propagation = opentelemetry::context::propagation;
class HttpHeaderCarrier : public propagation::TextMapCarrier {
public:
HttpHeaderCarrier(std::map<std::string, std::string>& headers)
: headers_(headers) {}
opentelemetry::nostd::string_view Get(
opentelemetry::nostd::string_view key) const noexcept override {
auto it = headers_.find(std::string(key));
if (it != headers_.end()) return it->second;
return "";
}
void Set(opentelemetry::nostd::string_view key,
opentelemetry::nostd::string_view value) noexcept override {
headers_[std::string(key)] = std::string(value);
}
private:
std::map<std::string, std::string>& headers_;
};
Extracting context
Extract trace context from incoming HTTP requests:
cpp
#include "opentelemetry/context/propagation/global_propagator.h"
#include "opentelemetry/context/runtime_context.h"
#include "opentelemetry/trace/provider.h"
namespace propagation = opentelemetry::context::propagation;
namespace trace_api = opentelemetry::trace;
void handleRequest(std::map<std::string, std::string>& headers) {
HttpHeaderCarrier carrier(headers);
auto propagator = propagation::GlobalTextMapPropagator::GetGlobalPropagator();
auto current_ctx = opentelemetry::context::RuntimeContext::GetCurrent();
auto new_ctx = propagator->Extract(carrier, current_ctx);
auto tracer = trace_api::Provider::GetTracerProvider()->GetTracer("myservice");
trace_api::StartSpanOptions opts;
opts.kind = trace_api::SpanKind::kServer;
opts.parent = trace_api::GetSpan(new_ctx)->GetContext();
auto span = tracer->StartSpan("handle-request", opts);
auto scope = tracer->WithActiveSpan(span);
// Process request...
span->End();
}
Injecting context
Inject trace context into outgoing HTTP requests:
cpp
void makeHttpRequest(const std::string& url) {
auto tracer = trace_api::Provider::GetTracerProvider()->GetTracer("myservice");
trace_api::StartSpanOptions opts;
opts.kind = trace_api::SpanKind::kClient;
auto span = tracer->StartSpan("http-request", opts);
auto scope = tracer->WithActiveSpan(span);
std::map<std::string, std::string> headers;
HttpHeaderCarrier carrier(headers);
auto propagator = propagation::GlobalTextMapPropagator::GetGlobalPropagator();
auto current_ctx = opentelemetry::context::RuntimeContext::GetCurrent();
propagator->Inject(carrier, current_ctx);
// Headers now contain traceparent - use in HTTP client
span->End();
}
Complete example
cpp
#include <map>
#include <string>
#include "opentelemetry/context/propagation/global_propagator.h"
#include "opentelemetry/context/propagation/text_map_propagator.h"
#include "opentelemetry/context/runtime_context.h"
#include "opentelemetry/trace/propagation/http_trace_context.h"
#include "opentelemetry/trace/provider.h"
namespace propagation = opentelemetry::context::propagation;
namespace trace_prop = opentelemetry::trace::propagation;
namespace trace_api = opentelemetry::trace;
// Carrier for HTTP headers
class HttpHeaderCarrier : public propagation::TextMapCarrier {
public:
HttpHeaderCarrier(std::map<std::string, std::string>& headers)
: headers_(headers) {}
opentelemetry::nostd::string_view Get(
opentelemetry::nostd::string_view key) const noexcept override {
auto it = headers_.find(std::string(key));
return it != headers_.end() ? it->second : "";
}
void Set(opentelemetry::nostd::string_view key,
opentelemetry::nostd::string_view value) noexcept override {
headers_[std::string(key)] = std::string(value);
}
private:
std::map<std::string, std::string>& headers_;
};
void InitPropagator() {
propagation::GlobalTextMapPropagator::SetGlobalPropagator(
opentelemetry::nostd::shared_ptr<propagation::TextMapPropagator>(
new trace_prop::HttpTraceContext()));
}
void clientRequest() {
auto tracer = trace_api::Provider::GetTracerProvider()->GetTracer("client");
auto span = tracer->StartSpan("client-request");
auto scope = tracer->WithActiveSpan(span);
std::map<std::string, std::string> headers;
HttpHeaderCarrier carrier(headers);
auto propagator = propagation::GlobalTextMapPropagator::GetGlobalPropagator();
propagator->Inject(carrier, opentelemetry::context::RuntimeContext::GetCurrent());
// Use headers in HTTP request
span->End();
}