Skip to content

Commit e9aa08a

Browse files
authored
feat: active configuration (#97)
- All fields are now optional. This allows us to distinguish default configuration from user configuration. - Report configurations to telemetry - Update README.md
1 parent b286465 commit e9aa08a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1461
-665
lines changed

BUILD.bazel

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ cc_library(
1515
"src/datadog/error.cpp",
1616
"src/datadog/extraction_util.cpp",
1717
"src/datadog/glob.cpp",
18+
"src/datadog/http_client.cpp",
1819
"src/datadog/id_generator.cpp",
1920
"src/datadog/limiter.cpp",
2021
"src/datadog/logger.cpp",
@@ -34,6 +35,7 @@ cc_library(
3435
"src/datadog/span_matcher.cpp",
3536
"src/datadog/span_sampler_config.cpp",
3637
"src/datadog/span_sampler.cpp",
38+
"src/datadog/string_util.cpp",
3739
"src/datadog/tag_propagation.cpp",
3840
"src/datadog/tags.cpp",
3941
"src/datadog/threaded_event_scheduler.cpp",
@@ -50,6 +52,7 @@ cc_library(
5052
hdrs = [
5153
"src/datadog/base64.h",
5254
"src/datadog/cerr_logger.h",
55+
"src/datadog/config.h",
5356
"src/datadog/clock.h",
5457
"src/datadog/config_manager.h",
5558
"src/datadog/config_update.h",
@@ -98,6 +101,7 @@ cc_library(
98101
"src/datadog/span_matcher.h",
99102
"src/datadog/span_sampler_config.h",
100103
"src/datadog/span_sampler.h",
104+
"src/datadog/string_util.h",
101105
"src/datadog/string_view.h",
102106
"src/datadog/tag_propagation.h",
103107
"src/datadog/tags.h",

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ target_sources(dd_trace_cpp-objects PRIVATE
101101
src/datadog/error.cpp
102102
src/datadog/extraction_util.cpp
103103
src/datadog/glob.cpp
104+
src/datadog/http_client.cpp
104105
src/datadog/id_generator.cpp
105106
src/datadog/limiter.cpp
106107
src/datadog/logger.cpp
@@ -120,6 +121,7 @@ target_sources(dd_trace_cpp-objects PRIVATE
120121
src/datadog/span_matcher.cpp
121122
src/datadog/span_sampler_config.cpp
122123
src/datadog/span_sampler.cpp
124+
src/datadog/string_util.cpp
123125
src/datadog/tags.cpp
124126
src/datadog/tag_propagation.cpp
125127
src/datadog/threaded_event_scheduler.cpp
@@ -141,6 +143,7 @@ target_sources(dd_trace_cpp-objects PUBLIC
141143
BASE_DIRS src/
142144
FILES
143145
src/datadog/base64.h
146+
src/datadog/config.h
144147
src/datadog/cerr_logger.h
145148
src/datadog/clock.h
146149
src/datadog/config_manager.h
@@ -190,6 +193,7 @@ target_sources(dd_trace_cpp-objects PUBLIC
190193
src/datadog/span_matcher.h
191194
src/datadog/span_sampler_config.h
192195
src/datadog/span_sampler.h
196+
src/datadog/string_util.h
193197
src/datadog/string_view.h
194198
src/datadog/tag_propagation.h
195199
src/datadog/tags.h

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ int main() {
1313
namespace dd = datadog::tracing;
1414

1515
dd::TracerConfig config;
16-
config.defaults.service = "my-service";
16+
config.service = "my-service";
1717

1818
const auto validated_config = dd::finalize_config(config);
1919
if (!validated_config) {

benchmark/benchmark.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
#include <benchmark/benchmark.h>
2-
32
#include <datadog/collector.h>
4-
#include <datadog/json.hpp>
53
#include <datadog/logger.h>
64
#include <datadog/span_data.h>
75
#include <datadog/tracer.h>
86
#include <datadog/tracer_config.h>
97

8+
#include <datadog/json.hpp>
109
#include <memory>
1110

1211
#include "hasher.h"
@@ -35,9 +34,7 @@ struct SerializingCollector : public dd::Collector {
3534
}
3635

3736
nlohmann::json config_json() const override {
38-
return nlohmann::json::object({
39-
{"type", "SerializingCollector"}
40-
});
37+
return nlohmann::json::object({{"type", "SerializingCollector"}});
4138
}
4239
};
4340

@@ -47,7 +44,7 @@ struct SerializingCollector : public dd::Collector {
4744
void BM_TraceTinyCCSource(benchmark::State& state) {
4845
for (auto _ : state) {
4946
dd::TracerConfig config;
50-
config.defaults.service = "benchmark";
47+
config.service = "benchmark";
5148
config.logger = std::make_shared<NullLogger>();
5249
config.collector = std::make_shared<SerializingCollector>();
5350
const auto valid_config = dd::finalize_config(config);
@@ -58,6 +55,6 @@ void BM_TraceTinyCCSource(benchmark::State& state) {
5855
}
5956
BENCHMARK(BM_TraceTinyCCSource);
6057

61-
} // namespace
58+
} // namespace
6259

6360
BENCHMARK_MAIN();

examples/hasher/hasher.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ int sha256_traced(Digest &digest, const fs::path &path,
132132

133133
int main() {
134134
dd::TracerConfig config;
135-
config.defaults.service = "dd-trace-cpp-example";
136-
config.defaults.environment = "dev";
135+
config.service = "dd-trace-cpp-example";
136+
config.environment = "dev";
137137

138138
auto validated = dd::finalize_config(config);
139139
if (auto *error = validated.if_error()) {

examples/http-server/proxy/proxy.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ void hard_stop(int /*signal*/) { std::exit(0); }
2525
int main() {
2626
// Set up the Datadog tracer. See `src/datadog/tracer_config.h`.
2727
dd::TracerConfig config;
28-
config.defaults.service = "dd-trace-cpp-http-server-example-proxy";
29-
config.defaults.service_type = "proxy";
28+
config.service = "dd-trace-cpp-http-server-example-proxy";
29+
config.service_type = "proxy";
3030

3131
// `finalize_config` validates `config` and applies any settings from
3232
// environment variables, such as `DD_AGENT_HOST`.

examples/http-server/server/server.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ void on_post_notes(const httplib::Request& request, httplib::Response& response)
109109
int main() {
110110
// Set up the Datadog tracer. See `src/datadog/tracer_config.h`.
111111
dd::TracerConfig config;
112-
config.defaults.service = "dd-trace-cpp-http-server-example-server";
113-
config.defaults.service_type = "server";
112+
config.service = "dd-trace-cpp-http-server-example-server";
113+
config.service_type = "server";
114114

115115
// `finalize_config` validates `config` and applies any settings from
116116
// environment variables, such as `DD_AGENT_HOST`.

src/datadog/config.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#pragma once
2+
3+
#include "error.h"
4+
#include "optional.h"
5+
6+
namespace datadog {
7+
namespace tracing {
8+
9+
// Enumerates available configuration names for the tracing library
10+
enum class ConfigName : char {
11+
SERVICE_NAME,
12+
SERVICE_ENV,
13+
SERVICE_VERSION,
14+
REPORT_TRACES,
15+
TAGS,
16+
EXTRACTION_STYLES,
17+
INJECTION_STYLES,
18+
STARTUP_LOGS,
19+
REPORT_TELEMETRY,
20+
DELEGATE_SAMPLING,
21+
GENEREATE_128BIT_TRACE_IDS,
22+
AGENT_URL,
23+
RC_POLL_INTERVAL,
24+
TRACE_SAMPLING_RATE,
25+
TRACE_SAMPLING_LIMIT,
26+
TRACE_SAMPLING_RULES,
27+
SPAN_SAMPLING_RULES,
28+
};
29+
30+
// Represents metadata for configuration parameters
31+
struct ConfigMetadata {
32+
enum class Origin : char {
33+
ENVIRONMENT_VARIABLE, // Originating from environment variables
34+
CODE, // Defined in code
35+
REMOTE_CONFIG, // Retrieved from remote configuration
36+
DEFAULT // Default value
37+
};
38+
39+
// Name of the configuration parameter
40+
ConfigName name;
41+
// Value of the configuration parameter
42+
std::string value;
43+
// Origin of the configuration parameter
44+
Origin origin;
45+
// Optional error associated with the configuration parameter
46+
Optional<Error> error;
47+
48+
ConfigMetadata() = default;
49+
ConfigMetadata(ConfigName n, std::string v, Origin orig,
50+
Optional<Error> err = nullopt)
51+
: name(n), value(std::move(v)), origin(orig), error(std::move(err)) {}
52+
};
53+
54+
// Return a pair containing the configuration origin and value of a
55+
// configuration value chosen from one of the specified `from_env`,
56+
// `from_config`, and `fallback`. This function defines the relative precedence
57+
// among configuration values originating from the environment, programmatic
58+
// configuration, and default configuration.
59+
template <typename Value, typename DefaultValue>
60+
std::pair<ConfigMetadata::Origin, Value> pick(const Optional<Value> &from_env,
61+
const Optional<Value> &from_user,
62+
DefaultValue fallback) {
63+
if (from_env) {
64+
return {ConfigMetadata::Origin::ENVIRONMENT_VARIABLE, *from_env};
65+
} else if (from_user) {
66+
return {ConfigMetadata::Origin::CODE, *from_user};
67+
}
68+
return {ConfigMetadata::Origin::DEFAULT, fallback};
69+
}
70+
71+
} // namespace tracing
72+
} // namespace datadog

src/datadog/config_manager.cpp

Lines changed: 75 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,118 @@
11
#include "config_manager.h"
22

3+
#include "parse_util.h"
4+
#include "string_util.h"
35
#include "trace_sampler.h"
46

57
namespace datadog {
68
namespace tracing {
79

810
ConfigManager::ConfigManager(const FinalizedTracerConfig& config)
911
: clock_(config.clock),
10-
default_trace_sampler_(
12+
default_metadata_(config.metadata),
13+
trace_sampler_(
1114
std::make_shared<TraceSampler>(config.trace_sampler, clock_)),
12-
current_trace_sampler_(default_trace_sampler_),
13-
default_span_defaults_(std::make_shared<SpanDefaults>(config.defaults)),
14-
current_span_defaults_(default_span_defaults_),
15-
default_report_traces_(config.report_traces),
16-
current_report_traces_(default_report_traces_) {}
15+
span_defaults_(std::make_shared<SpanDefaults>(config.defaults)),
16+
report_traces_(config.report_traces) {}
1717

1818
std::shared_ptr<TraceSampler> ConfigManager::trace_sampler() {
1919
std::lock_guard<std::mutex> lock(mutex_);
20-
return current_trace_sampler_;
20+
return trace_sampler_.value();
2121
}
2222

2323
std::shared_ptr<const SpanDefaults> ConfigManager::span_defaults() {
2424
std::lock_guard<std::mutex> lock(mutex_);
25-
return current_span_defaults_;
25+
return span_defaults_.value();
2626
}
2727

2828
bool ConfigManager::report_traces() {
2929
std::lock_guard<std::mutex> lock(mutex_);
30-
return current_report_traces_;
30+
return report_traces_.value();
3131
}
3232

33-
void ConfigManager::update(const ConfigUpdate& conf) {
33+
std::vector<ConfigMetadata> ConfigManager::update(const ConfigUpdate& conf) {
34+
std::vector<ConfigMetadata> metadata;
35+
3436
std::lock_guard<std::mutex> lock(mutex_);
3537

36-
if (conf.trace_sampler) {
37-
if (auto finalized_trace_sampler_cfg =
38-
finalize_config(*conf.trace_sampler)) {
39-
current_trace_sampler_ =
40-
std::make_shared<TraceSampler>(*finalized_trace_sampler_cfg, clock_);
41-
} else {
42-
// TODO: report error
43-
}
38+
if (!conf.trace_sampling_rate) {
39+
reset_config(ConfigName::TRACE_SAMPLING_RATE, trace_sampler_, metadata);
4440
} else {
45-
current_trace_sampler_ = default_trace_sampler_;
46-
}
41+
ConfigMetadata trace_sampling_metadata(
42+
ConfigName::TRACE_SAMPLING_RATE,
43+
to_string(*conf.trace_sampling_rate, 1),
44+
ConfigMetadata::Origin::REMOTE_CONFIG);
4745

48-
if (conf.tags) {
49-
auto new_span_defaults =
50-
std::make_shared<SpanDefaults>(*current_span_defaults_);
51-
new_span_defaults->tags = std::move(*conf.tags);
46+
TraceSamplerConfig trace_sampler_cfg;
47+
trace_sampler_cfg.sample_rate = *conf.trace_sampling_rate;
48+
49+
auto finalized_trace_sampler_cfg = finalize_config(trace_sampler_cfg);
50+
if (auto error = finalized_trace_sampler_cfg.if_error()) {
51+
trace_sampling_metadata.error = *error;
52+
}
5253

53-
current_span_defaults_ = new_span_defaults;
54+
auto trace_sampler =
55+
std::make_shared<TraceSampler>(*finalized_trace_sampler_cfg, clock_);
56+
57+
// This reset rate limiting and `TraceSampler` has no `operator==`.
58+
// TODO: Instead of creating another `TraceSampler`, we should
59+
// update the default sampling rate.
60+
trace_sampler_ = std::move(trace_sampler);
61+
metadata.emplace_back(std::move(trace_sampling_metadata));
62+
}
63+
64+
if (!conf.tags) {
65+
reset_config(ConfigName::TAGS, span_defaults_, metadata);
5466
} else {
55-
current_span_defaults_ = default_span_defaults_;
67+
ConfigMetadata tags_metadata(ConfigName::TAGS, join(*conf.tags, ","),
68+
ConfigMetadata::Origin::REMOTE_CONFIG);
69+
70+
auto parsed_tags = parse_tags(*conf.tags);
71+
if (auto error = parsed_tags.if_error()) {
72+
tags_metadata.error = *error;
73+
}
74+
75+
if (*parsed_tags != span_defaults_.value()->tags) {
76+
auto new_span_defaults =
77+
std::make_shared<SpanDefaults>(*span_defaults_.value());
78+
new_span_defaults->tags = std::move(*parsed_tags);
79+
80+
span_defaults_ = new_span_defaults;
81+
metadata.emplace_back(std::move(tags_metadata));
82+
}
5683
}
5784

58-
if (conf.report_traces) {
59-
current_report_traces_ = *conf.report_traces;
85+
if (!conf.report_traces) {
86+
reset_config(ConfigName::REPORT_TRACES, report_traces_, metadata);
6087
} else {
61-
current_report_traces_ = default_report_traces_;
88+
if (conf.report_traces != report_traces_.value()) {
89+
report_traces_ = *conf.report_traces;
90+
metadata.emplace_back(ConfigName::REPORT_TRACES,
91+
to_string(*conf.report_traces),
92+
ConfigMetadata::Origin::REMOTE_CONFIG);
93+
}
6294
}
95+
96+
return metadata;
6397
}
6498

65-
void ConfigManager::reset() {
66-
std::lock_guard<std::mutex> lock(mutex_);
67-
current_trace_sampler_ = default_trace_sampler_;
68-
current_span_defaults_ = default_span_defaults_;
69-
current_report_traces_ = default_report_traces_;
99+
template <typename T>
100+
void ConfigManager::reset_config(ConfigName name, T& conf,
101+
std::vector<ConfigMetadata>& metadata) {
102+
if (conf.is_original_value()) return;
103+
104+
conf.reset();
105+
metadata.emplace_back(default_metadata_[name]);
70106
}
71107

108+
std::vector<ConfigMetadata> ConfigManager::reset() { return update({}); }
109+
72110
nlohmann::json ConfigManager::config_json() const {
73111
std::lock_guard<std::mutex> lock(mutex_);
74112
return nlohmann::json{
75-
{"defaults", to_json(*current_span_defaults_)},
76-
{"trace_sampler", current_trace_sampler_->config_json()},
77-
{"report_traces", current_report_traces_}};
113+
{"defaults", to_json(*span_defaults_.value())},
114+
{"trace_sampler", trace_sampler_.value()->config_json()},
115+
{"report_traces", report_traces_.value()}};
78116
}
79117

80118
} // namespace tracing

0 commit comments

Comments
 (0)