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

Commit 5fc9c65

Browse files
mdouaihyyurishkuro
authored andcommitted
Support Tracer tags and configuration via environment variables (#181)
* Support configuring client from environment variables (fix #178) Signed-off-by: FR-MUREX-COM\mchaikhadouaihy <[email protected]> * Apply Changes requested by @Yurishkhuro 1. When testing the config, start with a defined config instead of an empty one 2. Make sure fromEnv is harmful in case nothing is defined 3. Use literals to avoid fat-finger problem in the code 4. Avoid adding yet additional methods to the Tracer Signed-off-by: FR-MUREX-COM\mchaikhadouaihy <[email protected]> * Exclude sampler config. Signed-off-by: FR-MUREX-COM\mchaikhadouaihy <[email protected]>
1 parent 4ee8a66 commit 5fc9c65

File tree

16 files changed

+424
-8
lines changed

16 files changed

+424
-8
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ set(SRC
210210
src/jaegertracing/thrift-gen/zipkincore_types.cpp
211211
src/jaegertracing/utils/ErrorUtil.cpp
212212
src/jaegertracing/utils/HexParsing.cpp
213+
src/jaegertracing/utils/EnvVariable.cpp
213214
src/jaegertracing/utils/RateLimiter.cpp
214215
src/jaegertracing/utils/UDPTransporter.cpp
215216
src/jaegertracing/utils/HTTPTransporter.cpp

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,27 @@ sampler:
8686
samplingServerURL: http://jaeger-agent.local:5778
8787
```
8888

89+
### Configuration via Environment
90+
91+
It's possible to populate the tracer configuration from the environement variables by calling `jaegertracing::Config::fromEnv`.
92+
93+
The following property names are currently available:
94+
95+
Property | Description
96+
--- | ---
97+
JAEGER_SERVICE_NAME | The service name
98+
JAEGER_DISABLED _(not recommended)_ | Instructs the Configuration to return a no-op tracer
99+
JAEGER_AGENT_HOST | The hostname for communicating with agent via UDP
100+
JAEGER_AGENT_PORT | The port for communicating with agent via UDP
101+
JAEGER_ENDPOINT | The traces endpoint, in case the client should connect directly to the Collector, like http://jaeger-collector:14268/api/traces
102+
JAEGER_REPORTER_LOG_SPANS | Whether the reporter should also log the spans
103+
JAEGER_REPORTER_MAX_QUEUE_SIZE | The reporter's maximum queue size
104+
JAEGER_REPORTER_FLUSH_INTERVAL | The reporter's flush interval (ms)
105+
JAEGER_SAMPLER_TYPE | The [sampler type](https://www.jaegertracing.io/docs/latest/sampling/#client-sampling-configuration)
106+
JAEGER_SAMPLER_PARAM | The sampler parameter (number)
107+
JAEGER_SAMPLER_MANAGER_HOST_PORT | The host name and port when using the remote controlled sampler
108+
JAEGER_TAGS | A comma separated list of `name = value` tracer level tags, which get added to all reported spans. The value can also refer to an environment variable using the format `${envVarName:default}`, where the `:default` is optional, and identifies a value to be used if the environment variable cannot be found
109+
89110
## License
90111

91112
[Apache 2.0 License](./LICENSE).

src/jaegertracing/Config.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,53 @@
1515
*/
1616

1717
#include "jaegertracing/Config.h"
18+
#include "jaegertracing/samplers/Config.h"
19+
#include "jaegertracing/utils/EnvVariable.h"
20+
21+
namespace jaegertracing {
22+
23+
constexpr const char* Config::kJAEGER_SERVICE_NAME_ENV_PROP;
24+
constexpr const char* Config::kJAEGER_TAGS_ENV_PROP;
25+
constexpr const char* Config::kJAEGER_JAEGER_DISABLED_ENV_PROP;
26+
27+
void Config::fromEnv()
28+
{
29+
const auto disabled =
30+
utils::EnvVariable::getBoolVariable(kJAEGER_JAEGER_DISABLED_ENV_PROP);
31+
if (disabled.first) {
32+
_disabled = disabled.second;
33+
}
34+
35+
const auto serviceName =
36+
utils::EnvVariable::getStringVariable(kJAEGER_SERVICE_NAME_ENV_PROP);
37+
if (!serviceName.empty()) {
38+
_serviceName = serviceName;
39+
}
40+
41+
const auto tags =
42+
utils::EnvVariable::getStringVariable(kJAEGER_TAGS_ENV_PROP);
43+
if (!tags.empty()) {
44+
std::string tag;
45+
std::istringstream tagsStream(tags);
46+
while (std::getline(tagsStream, tag, ',')) {
47+
48+
std::istringstream tagStream(tag);
49+
50+
std::string tagKey;
51+
std::string tagValue;
52+
if (std::getline(tagStream, tagKey, '=')) {
53+
std::getline(tagStream, tagValue, '=');
54+
if (std::getline(tagStream, tagValue, '=')) {
55+
// error, should be logged somewhere
56+
}
57+
else {
58+
_tags.emplace_back(tagKey, tagValue);
59+
}
60+
}
61+
}
62+
}
63+
_reporter.fromEnv();
64+
_sampler.fromEnv();
65+
}
66+
67+
} // namespace jaegertracing

src/jaegertracing/Config.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "jaegertracing/Compilers.h"
2121
#include "jaegertracing/Constants.h"
22+
#include "jaegertracing/Tag.h"
2223
#include "jaegertracing/baggage/RestrictionsConfig.h"
2324
#include "jaegertracing/propagation/HeadersConfig.h"
2425
#include "jaegertracing/reporters/Config.h"
@@ -29,6 +30,11 @@ namespace jaegertracing {
2930

3031
class Config {
3132
public:
33+
34+
static constexpr auto kJAEGER_SERVICE_NAME_ENV_PROP = "JAEGER_SERVICE_NAME";
35+
static constexpr auto kJAEGER_TAGS_ENV_PROP = "JAEGER_TAGS";
36+
static constexpr auto kJAEGER_JAEGER_DISABLED_ENV_PROP = "JAEGER_DISABLED";
37+
3238
#ifdef JAEGERTRACING_WITH_YAML_CPP
3339

3440
static Config parse(const YAML::Node& configYAML)
@@ -37,6 +43,9 @@ class Config {
3743
return Config();
3844
}
3945

46+
const auto serviceName =
47+
utils::yaml::findOrDefault<std::string>(configYAML, "service_name", "");
48+
4049
const auto disabled =
4150
utils::yaml::findOrDefault<bool>(configYAML, "disabled", false);
4251
const auto samplerNode = configYAML["sampler"];
@@ -49,7 +58,7 @@ class Config {
4958
const auto baggageRestrictions =
5059
baggage::RestrictionsConfig::parse(baggageRestrictionsNode);
5160
return Config(
52-
disabled, sampler, reporter, headers, baggageRestrictions);
61+
disabled, sampler, reporter, headers, baggageRestrictions, serviceName);
5362
}
5463

5564
#endif // JAEGERTRACING_WITH_YAML_CPP
@@ -60,8 +69,12 @@ class Config {
6069
const propagation::HeadersConfig& headers =
6170
propagation::HeadersConfig(),
6271
const baggage::RestrictionsConfig& baggageRestrictions =
63-
baggage::RestrictionsConfig())
72+
baggage::RestrictionsConfig(),
73+
const std::string& serviceName = "",
74+
const std::vector<Tag>& tags = std::vector<Tag>())
6475
: _disabled(disabled)
76+
, _serviceName(serviceName)
77+
, _tags(tags)
6578
, _sampler(sampler)
6679
, _reporter(reporter)
6780
, _headers(headers)
@@ -82,8 +95,16 @@ class Config {
8295
return _baggageRestrictions;
8396
}
8497

98+
const std::string& serviceName() const { return _serviceName; }
99+
100+
const std::vector<Tag>& tags() const { return _tags; }
101+
102+
void fromEnv();
103+
85104
private:
86105
bool _disabled;
106+
std::string _serviceName;
107+
std::vector< Tag > _tags;
87108
samplers::Config _sampler;
88109
reporters::Config _reporter;
89110
propagation::HeadersConfig _headers;

src/jaegertracing/ConfigTest.cpp

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include "jaegertracing/utils/YAML.h"
2222
#include <gtest/gtest.h>
2323

24+
#include <cstdlib>
25+
2426
namespace jaegertracing {
2527

2628
#ifdef JAEGERTRACING_WITH_YAML_CPP
@@ -93,4 +95,95 @@ TEST(Config, testZeroSamplingParam)
9395

9496
#endif // JAEGERTRACING_WITH_YAML_CPP
9597

98+
99+
void setEnv(const char *variable, const char *value) {
100+
#ifdef WIN32
101+
_putenv_s(variable, value);
102+
#else
103+
setenv(variable, value, true);
104+
#endif
105+
}
106+
107+
TEST(Config, testFromEnv)
108+
{
109+
std::vector<Tag> tags;
110+
tags.emplace_back("hostname", std::string("foo"));
111+
tags.emplace_back("my.app.version", std::string("1.2.3"));
112+
113+
Config config(false,
114+
samplers::Config("probabilistic",
115+
0.7,
116+
"http://host34:57/sampling",
117+
0,
118+
samplers::Config::Clock::duration()),
119+
reporters::Config(10,
120+
std::chrono::milliseconds(100),
121+
false,
122+
"host35:77",
123+
"http://host36:56568"),
124+
propagation::HeadersConfig(),
125+
baggage::RestrictionsConfig(),
126+
"test-service",
127+
tags);
128+
129+
config.fromEnv();
130+
131+
ASSERT_EQ(std::string("http://host36:56568"), config.reporter().endpoint());
132+
ASSERT_EQ(std::string("host35:77"), config.reporter().localAgentHostPort());
133+
134+
ASSERT_EQ(10, config.reporter().queueSize());
135+
ASSERT_EQ(std::chrono::milliseconds(100),
136+
config.reporter().bufferFlushInterval());
137+
ASSERT_EQ(false, config.reporter().logSpans());
138+
139+
ASSERT_EQ(.7, config.sampler().param());
140+
ASSERT_EQ(std::string("probabilistic"), config.sampler().type());
141+
142+
setEnv("JAEGER_AGENT_HOST", "host33");
143+
setEnv("JAEGER_AGENT_PORT", "45");
144+
setEnv("JAEGER_ENDPOINT", "http://host34:56567");
145+
146+
setEnv("JAEGER_REPORTER_MAX_QUEUE_SIZE", "33");
147+
setEnv("JAEGER_REPORTER_FLUSH_INTERVAL", "45");
148+
setEnv("JAEGER_REPORTER_LOG_SPANS", "true");
149+
150+
setEnv("JAEGER_SAMPLER_PARAM", "33");
151+
setEnv("JAEGER_SAMPLER_TYPE", "const");
152+
153+
setEnv("JAEGER_SERVICE_NAME", "AService");
154+
setEnv("JAEGER_TAGS", "hostname=foobar,my.app.version=4.5.6");
155+
156+
config.fromEnv();
157+
158+
ASSERT_EQ(std::string("http://host34:56567"), config.reporter().endpoint());
159+
ASSERT_EQ(std::string("host33:45"), config.reporter().localAgentHostPort());
160+
161+
ASSERT_EQ(33, config.reporter().queueSize());
162+
ASSERT_EQ(std::chrono::milliseconds(45),
163+
config.reporter().bufferFlushInterval());
164+
ASSERT_EQ(true, config.reporter().logSpans());
165+
166+
ASSERT_EQ(33., config.sampler().param());
167+
ASSERT_EQ(std::string("const"), config.sampler().type());
168+
169+
ASSERT_EQ(std::string("AService"), config.serviceName());
170+
171+
std::vector<Tag> expectedTags;
172+
expectedTags.emplace_back("hostname", std::string("foo"));
173+
expectedTags.emplace_back("my.app.version", std::string("1.2.3"));
174+
expectedTags.emplace_back("hostname", std::string("foobar"));
175+
expectedTags.emplace_back("my.app.version", std::string("4.5.6"));
176+
ASSERT_EQ(expectedTags, config.tags());
177+
178+
ASSERT_EQ(false, config.disabled());
179+
180+
setEnv("JAEGER_DISABLED", "TRue"); // case-insensitive
181+
setEnv("JAEGER_AGENT_PORT", "445");
182+
183+
config.fromEnv();
184+
ASSERT_EQ(true, config.disabled());
185+
ASSERT_EQ(std::string("host33:445"),
186+
config.reporter().localAgentHostPort());
187+
}
188+
96189
} // namespace jaegertracing

src/jaegertracing/Tracer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ Tracer::make(const std::string& serviceName,
239239
logger,
240240
metrics,
241241
config.headers(),
242+
config.tags(),
242243
options));
243244
}
244245

src/jaegertracing/Tracer.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ class Tracer : public opentracing::Tracer,
5353

5454
static constexpr auto kGen128BitOption = 1;
5555

56+
static std::shared_ptr<opentracing::Tracer> make(const Config& config)
57+
{
58+
return make(config.serviceName(),
59+
config,
60+
std::shared_ptr<logging::Logger>(logging::nullLogger()));
61+
}
62+
5663
static std::shared_ptr<opentracing::Tracer>
5764
make(const std::string& serviceName, const Config& config)
5865
{
@@ -69,7 +76,6 @@ class Tracer : public opentracing::Tracer,
6976
metrics::NullStatsFactory factory;
7077
return make(serviceName, config, logger, factory);
7178
}
72-
7379
static std::shared_ptr<opentracing::Tracer>
7480
make(const std::string& serviceName,
7581
const Config& config,
@@ -78,7 +84,6 @@ class Tracer : public opentracing::Tracer,
7884
{
7985
return make(serviceName, config, logger, statsFactory, 0);
8086
}
81-
8287
static std::shared_ptr<opentracing::Tracer>
8388
make(const std::string& serviceName,
8489
const Config& config,
@@ -202,6 +207,7 @@ class Tracer : public opentracing::Tracer,
202207
const std::shared_ptr<logging::Logger>& logger,
203208
const std::shared_ptr<metrics::Metrics>& metrics,
204209
const propagation::HeadersConfig& headersConfig,
210+
const std::vector<Tag>& tags,
205211
int options)
206212
: _serviceName(serviceName)
207213
, _hostIPv4(net::IPAddress::localIP(AF_INET))
@@ -233,6 +239,8 @@ class Tracer : public opentracing::Tracer,
233239
_tags.push_back(Tag(kTracerIPTagKey, _hostIPv4.host()));
234240
}
235241

242+
std::copy(tags.cbegin(), tags.cend(), std::back_inserter(_tags));
243+
236244
std::random_device device;
237245
_randomNumberGenerator.seed(device());
238246
}

src/jaegertracing/TracerFactory.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,9 @@ TracerFactory::MakeTracer(const char* configuration,
4949
return opentracing::make_unexpected(
5050
opentracing::invalid_configuration_error);
5151
}
52-
std::string serviceName = serviceNameNode.Scalar();
5352

5453
const auto tracerConfig = jaegertracing::Config::parse(yaml);
55-
return jaegertracing::Tracer::make(serviceName, tracerConfig);
54+
return jaegertracing::Tracer::make(tracerConfig);
5655
#endif // JAEGERTRACING_WITH_YAML_CPP
5756
} catch (const std::bad_alloc&) {
5857
return opentracing::make_unexpected(

src/jaegertracing/TracerTest.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,4 +416,36 @@ TEST(Tracer, testPropagation)
416416
tracer->Close();
417417
}
418418

419+
TEST(Tracer, testTracerTags)
420+
{
421+
std::vector<Tag> tags;
422+
tags.emplace_back("hostname", std::string("foobar"));
423+
tags.emplace_back("my.app.version", std::string("1.2.3"));
424+
425+
Config config(
426+
false,
427+
samplers::Config(
428+
"const", 1, "", 0, samplers::Config::Clock::duration()),
429+
reporters::Config(0, std::chrono::milliseconds(100), false, "", ""),
430+
propagation::HeadersConfig(),
431+
baggage::RestrictionsConfig(),
432+
"test-service",
433+
tags);
434+
435+
auto tracer = Tracer::make(config);
436+
const auto jaegerTracer = std::static_pointer_cast<Tracer>(tracer);
437+
438+
ASSERT_TRUE(std::find(jaegerTracer->tags().begin(),
439+
jaegerTracer->tags().end(),
440+
Tag("hostname", std::string("foobar"))) !=
441+
jaegerTracer->tags().end());
442+
443+
ASSERT_TRUE(std::find(jaegerTracer->tags().begin(),
444+
jaegerTracer->tags().end(),
445+
Tag("my.app.version", std::string("1.2.3"))) !=
446+
jaegerTracer->tags().end());
447+
448+
ASSERT_EQ(std::string("test-service"), jaegerTracer->serviceName());
449+
}
450+
419451
} // namespace jaegertracing

src/jaegertracing/net/IPAddress.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ namespace net {
5353

5454
class IPAddress {
5555
public:
56-
static IPAddress v4(const std::string& hostPort)
56+
static std::pair<std::string, int> parse(const std::string& hostPort)
5757
{
5858
const auto colonPos = hostPort.find(':');
5959
const auto ip = hostPort.substr(0, colonPos);
@@ -65,7 +65,13 @@ class IPAddress {
6565
port = 0;
6666
}
6767
}
68-
return v4(ip, port);
68+
return std::make_pair(ip, port);
69+
}
70+
71+
static IPAddress v4(const std::string& hostPort)
72+
{
73+
auto result = parse(hostPort);
74+
return v4(result.first, result.second);
6975
}
7076

7177
static IPAddress v4(const std::string& ip, int port)

0 commit comments

Comments
 (0)