Skip to content
This repository was archived by the owner on Aug 30, 2022. It is now read-only.

Commit c1d5795

Browse files
Add Support for W3C traceparent/tracestate propagation (#255)
* Implemented W3C traceparent propagation Signed-off-by: Tobias Stadler <[email protected]> * W3C should be lowercase as mentioned in https://www.jaegertracing.io/docs/1.21/client-features/, Signed-off-by: Tobias Stadler <[email protected]> * Added support for setting the propagation format via environment variables Signed-off-by: Tobias Stadler <[email protected]> * Fix assignment Signed-off-by: Tobias Stadler <[email protected]> * Implemented Support for W3C tracestate Signed-off-by: Tobias Stadler <[email protected]> * Extracted Jager porpagation and W3C propgation in their own classes Signed-off-by: Tobias Stadler <[email protected]> * Fix build Signed-off-by: Tobias Stadler <[email protected]> * Fix copyright Signed-off-by: Tobias Stadler <[email protected]> * Use shared_ptr instead of raw pointer Signed-off-by: Tobias Stadler <[email protected]> * Log unknown propagation formats and fall back to jaeger format Signed-off-by: Tobias Stadler <[email protected]> * Extracted propagation format parsing Signed-off-by: Tobias Stadler <[email protected]> * Use SpanContext with known IDs to simplify test Signed-off-by: Tobias Stadler <[email protected]>
1 parent d123936 commit c1d5795

20 files changed

+916
-220
lines changed

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ set(SRC
171171
src/jaegertracing/propagation/HeadersConfig.cpp
172172
src/jaegertracing/propagation/Injector.cpp
173173
src/jaegertracing/propagation/Propagator.cpp
174+
src/jaegertracing/propagation/JaegerPropagator.cpp
175+
src/jaegertracing/propagation/W3CPropagator.cpp
174176
src/jaegertracing/reporters/CompositeReporter.cpp
175177
src/jaegertracing/reporters/Config.cpp
176178
src/jaegertracing/reporters/InMemoryReporter.cpp
@@ -332,6 +334,7 @@ if(BUILD_TESTING)
332334
src/jaegertracing/net/http/MethodTest.cpp
333335
src/jaegertracing/net/http/ResponseTest.cpp
334336
src/jaegertracing/propagation/PropagatorTest.cpp
337+
src/jaegertracing/propagation/W3CPropagatorTest.cpp
335338
src/jaegertracing/reporters/ConfigTest.cpp
336339
src/jaegertracing/reporters/ReporterTest.cpp
337340
src/jaegertracing/samplers/SamplerTest.cpp

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ JAEGER_DISABLED _(not recommended)_ | Instructs the Configuration to return a no
104104
JAEGER_AGENT_HOST | The hostname for communicating with agent via UDP
105105
JAEGER_AGENT_PORT | The port for communicating with agent via UDP
106106
JAEGER_ENDPOINT | The traces endpoint, in case the client should connect directly to the Collector, like http://jaeger-collector:14268/api/traces
107+
JAEGER_PROPAGATION | The propagation format used by the tracer. Supported values are jaeger and w3c
107108
JAEGER_REPORTER_LOG_SPANS | Whether the reporter should also log the spans
108109
JAEGER_REPORTER_MAX_QUEUE_SIZE | The reporter's maximum queue size
109110
JAEGER_REPORTER_FLUSH_INTERVAL | The reporter's flush interval (ms)

src/jaegertracing/Config.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,18 @@ void Config::fromEnv()
3232
_disabled = disabled.second;
3333
}
3434

35-
const auto traceId128Bit =
36-
utils::EnvVariable::getBoolVariable(kJAEGER_JAEGER_TRACEID_128BIT_ENV_PROP);
35+
const auto traceId128Bit = utils::EnvVariable::getBoolVariable(
36+
kJAEGER_JAEGER_TRACEID_128BIT_ENV_PROP);
3737
if (traceId128Bit.first) {
3838
_traceId128Bit = traceId128Bit.second;
3939
}
4040

41+
const auto propagationFormat =
42+
utils::EnvVariable::getStringVariable(kJAEGER_PROPAGATION_ENV_PROP);
43+
if (!propagationFormat.empty()) {
44+
_propagationFormat = parsePropagationFormat(propagationFormat);
45+
}
46+
4147
const auto serviceName =
4248
utils::EnvVariable::getStringVariable(kJAEGER_SERVICE_NAME_ENV_PROP);
4349
if (!serviceName.empty()) {
@@ -70,4 +76,20 @@ void Config::fromEnv()
7076
_sampler.fromEnv();
7177
}
7278

79+
propagation::Format
80+
Config::parsePropagationFormat(std::string strPropagationFormat)
81+
{
82+
auto propagationFormat = propagation::Format::JAEGER;
83+
if (strPropagationFormat == "w3c") {
84+
propagationFormat = propagation::Format::W3C;
85+
}
86+
else if (strPropagationFormat != "jaeger") {
87+
std::cerr << "ERROR: unknown propagation format '"
88+
<< strPropagationFormat
89+
<< "', falling back to jaeger propagation format";
90+
}
91+
92+
return propagationFormat;
93+
}
94+
7395
} // namespace jaegertracing

src/jaegertracing/Config.h

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "jaegertracing/Tag.h"
2323
#include "jaegertracing/baggage/RestrictionsConfig.h"
2424
#include "jaegertracing/propagation/HeadersConfig.h"
25+
#include "jaegertracing/propagation/Format.h"
2526
#include "jaegertracing/reporters/Config.h"
2627
#include "jaegertracing/samplers/Config.h"
2728
#include "jaegertracing/utils/YAML.h"
@@ -35,6 +36,7 @@ class Config {
3536
static constexpr auto kJAEGER_TAGS_ENV_PROP = "JAEGER_TAGS";
3637
static constexpr auto kJAEGER_JAEGER_DISABLED_ENV_PROP = "JAEGER_DISABLED";
3738
static constexpr auto kJAEGER_JAEGER_TRACEID_128BIT_ENV_PROP = "JAEGER_TRACEID_128BIT";
39+
static constexpr auto kJAEGER_PROPAGATION_ENV_PROP = "JAEGER_PROPAGATION";
3840

3941
#ifdef JAEGERTRACING_WITH_YAML_CPP
4042

@@ -49,8 +51,14 @@ class Config {
4951

5052
const auto disabled =
5153
utils::yaml::findOrDefault<bool>(configYAML, "disabled", false);
54+
5255
const auto traceId128Bit =
5356
utils::yaml::findOrDefault<bool>(configYAML, "traceid_128bit", false);
57+
58+
const auto propagationFormat =
59+
parsePropagationFormat(utils::yaml::findOrDefault<std::string>(
60+
configYAML, "propagation_format", "jaeger"));
61+
5462
const auto samplerNode = configYAML["sampler"];
5563
const auto sampler = samplers::Config::parse(samplerNode);
5664
const auto reporterNode = configYAML["reporter"];
@@ -60,8 +68,15 @@ class Config {
6068
const auto baggageRestrictionsNode = configYAML["baggage_restrictions"];
6169
const auto baggageRestrictions =
6270
baggage::RestrictionsConfig::parse(baggageRestrictionsNode);
63-
return Config(
64-
disabled, traceId128Bit, sampler, reporter, headers, baggageRestrictions, serviceName);
71+
return Config(disabled,
72+
traceId128Bit,
73+
sampler,
74+
reporter,
75+
headers,
76+
baggageRestrictions,
77+
serviceName,
78+
std::vector<Tag>(),
79+
propagationFormat);
6580
}
6681

6782
#endif // JAEGERTRACING_WITH_YAML_CPP
@@ -75,9 +90,12 @@ class Config {
7590
const baggage::RestrictionsConfig& baggageRestrictions =
7691
baggage::RestrictionsConfig(),
7792
const std::string& serviceName = "",
78-
const std::vector<Tag>& tags = std::vector<Tag>())
93+
const std::vector<Tag>& tags = std::vector<Tag>(),
94+
const propagation::Format propagationFormat =
95+
propagation::Format::JAEGER)
7996
: _disabled(disabled)
8097
, _traceId128Bit(traceId128Bit)
98+
, _propagationFormat(propagationFormat)
8199
, _serviceName(serviceName)
82100
, _tags(tags)
83101
, _sampler(sampler)
@@ -91,6 +109,8 @@ class Config {
91109

92110
bool traceId128Bit() const { return _traceId128Bit; }
93111

112+
propagation::Format propagationFormat() const { return _propagationFormat; }
113+
94114
const samplers::Config& sampler() const { return _sampler; }
95115

96116
const reporters::Config& reporter() const { return _reporter; }
@@ -109,8 +129,12 @@ class Config {
109129
void fromEnv();
110130

111131
private:
132+
static propagation::Format
133+
parsePropagationFormat(std::string strPropagationFormat);
134+
112135
bool _disabled;
113136
bool _traceId128Bit;
137+
propagation::Format _propagationFormat;
114138
std::string _serviceName;
115139
std::vector< Tag > _tags;
116140
samplers::Config _sampler;

src/jaegertracing/ConfigTest.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,17 @@ TEST(Config, testZeroSamplingParam)
9696
}
9797
}
9898

99+
TEST(Config, testPropagationFormat)
100+
{
101+
{
102+
constexpr auto kConfigYAML = R"cfg(
103+
propagation_format: w3c
104+
)cfg";
105+
const auto config = Config::parse(YAML::Load(kConfigYAML));
106+
ASSERT_EQ(propagation::Format::W3C, config.propagationFormat());
107+
}
108+
}
109+
99110
#endif // JAEGERTRACING_WITH_YAML_CPP
100111

101112
TEST(Config, testFromEnv)
@@ -186,6 +197,11 @@ TEST(Config, testFromEnv)
186197
ASSERT_EQ(std::string("host33:445"),
187198
config.reporter().localAgentHostPort());
188199

200+
testutils::EnvVariable::setEnv("JAEGER_PROPAGATION", "w3c");
201+
202+
config.fromEnv();
203+
ASSERT_EQ(propagation::Format::W3C, config.propagationFormat());
204+
189205
testutils::EnvVariable::setEnv("JAEGER_AGENT_HOST", "");
190206
testutils::EnvVariable::setEnv("JAEGER_AGENT_PORT", "");
191207
testutils::EnvVariable::setEnv("JAEGER_ENDPOINT", "");
@@ -198,6 +214,7 @@ TEST(Config, testFromEnv)
198214
testutils::EnvVariable::setEnv("JAEGER_TAGS", "");
199215
testutils::EnvVariable::setEnv("JAEGER_DISABLED", "");
200216
testutils::EnvVariable::setEnv("JAEGER_TRACE_ID_128BIT", "");
217+
testutils::EnvVariable::setEnv("JAEGER_PROPAGATION", "");
201218
}
202219

203220
} // namespace jaegertracing

src/jaegertracing/Constants.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ static constexpr auto kSamplerParamTagKey = "sampler.param";
3232
static constexpr auto kTraceContextHeaderName = "uber-trace-id";
3333
static constexpr auto kTracerStateHeaderName = kTraceContextHeaderName;
3434
static constexpr auto kTraceBaggageHeaderPrefix = "uberctx-";
35+
static constexpr auto kW3CTraceParentHeaderName = "traceparent";
36+
static constexpr auto kW3CTraceStateHeaderName = "tracestate";
3537
static constexpr auto kSamplerTypeConst = "const";
3638
static constexpr auto kSamplerTypeRemote = "remote";
3739
static constexpr auto kSamplerTypeProbabilistic = "probabilistic";

src/jaegertracing/SpanContext.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,15 @@ class SpanContext : public opentracing::SpanContext {
5454
uint64_t parentID,
5555
unsigned char flags,
5656
const StrMap& baggage,
57-
const std::string& debugID = "")
57+
const std::string& debugID = "",
58+
const std::string& traceState = "")
5859
: _traceID(traceID)
5960
, _spanID(spanID)
6061
, _parentID(parentID)
6162
, _flags(flags)
6263
, _baggage(baggage)
6364
, _debugID(debugID)
65+
, _traceState(traceState)
6466
, _mutex()
6567
{
6668
}
@@ -72,6 +74,7 @@ class SpanContext : public opentracing::SpanContext {
7274
, _flags(ctx._flags)
7375
, _baggage(ctx._baggage)
7476
, _debugID(ctx._debugID)
77+
, _traceState(ctx._traceState)
7578
{
7679
}
7780

@@ -90,6 +93,7 @@ class SpanContext : public opentracing::SpanContext {
9093
swap(_flags, ctx._flags);
9194
swap(_baggage, ctx._baggage);
9295
swap(_debugID, ctx._debugID);
96+
swap(_traceState, ctx._traceState);
9397
}
9498

9599
friend void swap(SpanContext& lhs, SpanContext& rhs) { lhs.swap(rhs); }
@@ -105,8 +109,13 @@ class SpanContext : public opentracing::SpanContext {
105109
SpanContext withBaggage(const StrMap& baggage) const
106110
{
107111
std::lock_guard<std::mutex> lock(_mutex);
108-
return SpanContext(
109-
_traceID, _spanID, _parentID, _flags, baggage, _debugID);
112+
return SpanContext(_traceID,
113+
_spanID,
114+
_parentID,
115+
_flags,
116+
baggage,
117+
_debugID,
118+
_traceState);
110119
}
111120

112121
template <typename Function>
@@ -140,6 +149,8 @@ class SpanContext : public opentracing::SpanContext {
140149
return _flags & static_cast<unsigned char>(Flag::kSampled);
141150
}
142151

152+
const std::string& traceState() const { return _traceState; }
153+
143154
bool isDebug() const
144155
{
145156
return _flags & static_cast<unsigned char>(Flag::kDebug);
@@ -187,7 +198,8 @@ class SpanContext : public opentracing::SpanContext {
187198
}
188199
return lhs._traceID == rhs._traceID && lhs._spanID == rhs._spanID &&
189200
lhs._parentID == rhs._parentID && lhs._flags == rhs._flags &&
190-
lhs._debugID == rhs._debugID;
201+
lhs._debugID == rhs._debugID &&
202+
lhs._traceState == rhs._traceState;
191203
}
192204

193205
friend bool operator!=(const SpanContext& lhs, const SpanContext& rhs)
@@ -202,6 +214,7 @@ class SpanContext : public opentracing::SpanContext {
202214
unsigned char _flags;
203215
StrMap _baggage;
204216
std::string _debugID;
217+
std::string _traceState;
205218
mutable std::mutex _mutex; // Protects _baggage.
206219
};
207220

src/jaegertracing/Tracer.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "jaegertracing/Tracer.h"
1919
#include "jaegertracing/Reference.h"
2020
#include "jaegertracing/TraceID.h"
21+
#include "jaegertracing/propagation/JaegerPropagator.h"
22+
#include "jaegertracing/propagation/W3CPropagator.h"
2123
#include "jaegertracing/samplers/SamplingStatus.h"
2224
#include <algorithm>
2325
#include <cassert>
@@ -258,6 +260,25 @@ Tracer::make(const std::string& serviceName,
258260
}
259261

260262
auto metrics = std::make_shared<metrics::Metrics>(statsFactory);
263+
264+
std::shared_ptr<TextMapPropagator> textPropagator;
265+
std::shared_ptr<HTTPHeaderPropagator> httpHeaderPropagator;
266+
if (config.propagationFormat() == propagation::Format::W3C) {
267+
textPropagator = std::shared_ptr<TextMapPropagator>(
268+
new propagation::W3CTextMapPropagator(config.headers(), metrics));
269+
httpHeaderPropagator = std::shared_ptr<HTTPHeaderPropagator>(
270+
new propagation::W3CHTTPHeaderPropagator(config.headers(),
271+
metrics));
272+
}
273+
else {
274+
textPropagator = std::shared_ptr<TextMapPropagator>(
275+
new propagation::JaegerTextMapPropagator(config.headers(),
276+
metrics));
277+
httpHeaderPropagator = std::shared_ptr<HTTPHeaderPropagator>(
278+
new propagation::JaegerHTTPHeaderPropagator(config.headers(),
279+
metrics));
280+
}
281+
261282
std::shared_ptr<samplers::Sampler> sampler(
262283
config.sampler().makeSampler(serviceName, *logger, *metrics));
263284
std::shared_ptr<reporters::Reporter> reporter(
@@ -267,7 +288,8 @@ Tracer::make(const std::string& serviceName,
267288
reporter,
268289
logger,
269290
metrics,
270-
config.headers(),
291+
textPropagator,
292+
httpHeaderPropagator,
271293
config.tags(),
272294
options));
273295
}

src/jaegertracing/Tracer.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ class Tracer : public opentracing::Tracer,
119119
return opentracing::make_expected_from_error<void>(
120120
opentracing::invalid_span_context_error);
121121
}
122-
_textPropagator.inject(*jaegerCtx, writer);
122+
_textPropagator->inject(*jaegerCtx, writer);
123123
return opentracing::make_expected();
124124
}
125125

@@ -132,7 +132,7 @@ class Tracer : public opentracing::Tracer,
132132
return opentracing::make_expected_from_error<void>(
133133
opentracing::invalid_span_context_error);
134134
}
135-
_httpHeaderPropagator.inject(*jaegerCtx, writer);
135+
_httpHeaderPropagator->inject(*jaegerCtx, writer);
136136
return opentracing::make_expected();
137137
}
138138

@@ -150,7 +150,7 @@ class Tracer : public opentracing::Tracer,
150150
opentracing::expected<std::unique_ptr<opentracing::SpanContext>>
151151
Extract(const opentracing::TextMapReader& reader) const override
152152
{
153-
const auto spanContext = _textPropagator.extract(reader);
153+
const auto spanContext = _textPropagator->extract(reader);
154154
if (spanContext == SpanContext()) {
155155
return std::unique_ptr<opentracing::SpanContext>();
156156
}
@@ -161,7 +161,7 @@ class Tracer : public opentracing::Tracer,
161161
opentracing::expected<std::unique_ptr<opentracing::SpanContext>>
162162
Extract(const opentracing::HTTPHeadersReader& reader) const override
163163
{
164-
const auto spanContext = _httpHeaderPropagator.extract(reader);
164+
const auto spanContext = _httpHeaderPropagator->extract(reader);
165165
if (spanContext == SpanContext()) {
166166
return std::unique_ptr<opentracing::SpanContext>();
167167
}
@@ -201,12 +201,20 @@ class Tracer : public opentracing::Tracer,
201201
}
202202

203203
private:
204+
using TextMapPropagator =
205+
propagation::Propagator<const opentracing::TextMapReader&,
206+
const opentracing::TextMapWriter&>;
207+
using HTTPHeaderPropagator =
208+
propagation::Propagator<const opentracing::HTTPHeadersReader&,
209+
const opentracing::HTTPHeadersWriter&>;
210+
204211
Tracer(const std::string& serviceName,
205212
const std::shared_ptr<samplers::Sampler>& sampler,
206213
const std::shared_ptr<reporters::Reporter>& reporter,
207214
const std::shared_ptr<logging::Logger>& logger,
208215
const std::shared_ptr<metrics::Metrics>& metrics,
209-
const propagation::HeadersConfig& headersConfig,
216+
const std::shared_ptr<TextMapPropagator> &textPropagator,
217+
const std::shared_ptr<HTTPHeaderPropagator> &httpHeaderPropagator,
210218
const std::vector<Tag>& tags,
211219
int options)
212220
: _serviceName(serviceName)
@@ -216,8 +224,8 @@ class Tracer : public opentracing::Tracer,
216224
, _metrics(metrics)
217225
, _logger(logger)
218226
, _randomNumberGenerator()
219-
, _textPropagator(headersConfig, _metrics)
220-
, _httpHeaderPropagator(headersConfig, _metrics)
227+
, _textPropagator(textPropagator)
228+
, _httpHeaderPropagator(httpHeaderPropagator)
221229
, _binaryPropagator(_metrics)
222230
, _tags()
223231
, _restrictionManager(new baggage::DefaultRestrictionManager(0))
@@ -294,8 +302,8 @@ class Tracer : public opentracing::Tracer,
294302
std::shared_ptr<logging::Logger> _logger;
295303
mutable std::mt19937_64 _randomNumberGenerator;
296304
mutable std::mutex _randomMutex;
297-
propagation::TextMapPropagator _textPropagator;
298-
propagation::HTTPHeaderPropagator _httpHeaderPropagator;
305+
std::shared_ptr<TextMapPropagator> _textPropagator;
306+
std::shared_ptr<HTTPHeaderPropagator> _httpHeaderPropagator;
299307
propagation::BinaryPropagator _binaryPropagator;
300308
std::vector<Tag> _tags;
301309
std::unique_ptr<baggage::RestrictionManager> _restrictionManager;

0 commit comments

Comments
 (0)