Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 13 additions & 18 deletions include/datadog/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,12 @@ struct ConfigMetadata {
};

// Returns the final configuration value using the following
// precedence order: environment > user code > default, and populates two maps:
// 1. `telemetry_configs`: Records ALL configuration sources that were provided,
// ordered from lowest to highest precedence.
// 2. `metadata`: Records ONLY the winning configuration value (highest
// precedence). Template Parameters:
// precedence order: environment > user code > default, and populates metadata:
// `metadata`: Records ALL configuration sources that were provided,
// ordered from lowest to highest precedence. The last entry has the highest
// precedence and is the winning value.
//
// Template Parameters:
// Value: The type of the configuration value
// Stringifier: Optional function type to convert Value to string
// (defaults to std::nullptr_t, which uses string construction)
Expand All @@ -76,10 +77,8 @@ struct ConfigMetadata {
// Parameters:
// from_env: Optional value from environment variables (highest precedence)
// from_user: Optional value from user code (middle precedence)
// telemetry_configs: Output map that will be populated with all config
// sources found for this config_name, in precedence order
// metadata: Output map that will be populated with the winning config value
// for this config_name
// metadata: Output map that will be populated with all config sources found
// for this config_name, in precedence order (last = highest)
// config_name: The configuration parameter name identifier
// fallback: Optional default value (lowest precedence). Pass nullptr to
// indicate no default.
Expand All @@ -94,9 +93,7 @@ template <typename Value, typename Stringifier = std::nullptr_t,
typename DefaultValue = std::nullptr_t>
Value resolve_and_record_config(
const Optional<Value>& from_env, const Optional<Value>& from_user,
std::unordered_map<ConfigName, std::vector<ConfigMetadata>>*
telemetry_configs,
std::unordered_map<ConfigName, ConfigMetadata>* metadata,
std::unordered_map<ConfigName, std::vector<ConfigMetadata>>* metadata,
ConfigName config_name, DefaultValue fallback = nullptr,
Stringifier to_string_fn = nullptr) {
auto stringify = [&](const Value& v) -> std::string {
Expand All @@ -111,13 +108,12 @@ Value resolve_and_record_config(
}
};

std::vector<ConfigMetadata> telemetry_entries;
std::vector<ConfigMetadata> metadata_entries;
Optional<Value> chosen_value;

auto add_entry = [&](ConfigMetadata::Origin origin, const Value& val) {
std::string val_str = stringify(val);
telemetry_entries.emplace_back(
ConfigMetadata{config_name, val_str, origin});
metadata_entries.emplace_back(ConfigMetadata{config_name, val_str, origin});
chosen_value = val;
};

Expand All @@ -134,9 +130,8 @@ Value resolve_and_record_config(
add_entry(ConfigMetadata::Origin::ENVIRONMENT_VARIABLE, *from_env);
}

(*telemetry_configs)[config_name] = std::move(telemetry_entries);
if (!(*telemetry_configs)[config_name].empty()) {
(*metadata)[config_name] = (*telemetry_configs)[config_name].back();
if (!metadata_entries.empty()) {
(*metadata)[config_name] = std::move(metadata_entries);
}

return chosen_value.value_or(Value{});
Expand Down
2 changes: 1 addition & 1 deletion include/datadog/datadog_agent_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class FinalizedDatadogAgentConfig {
std::chrono::steady_clock::duration request_timeout;
std::chrono::steady_clock::duration shutdown_timeout;
std::chrono::steady_clock::duration remote_configuration_poll_interval;
std::unordered_map<ConfigName, ConfigMetadata> metadata;
std::unordered_map<ConfigName, std::vector<ConfigMetadata>> metadata;

// Origin detection
Optional<std::string> admission_controller_uid;
Expand Down
2 changes: 1 addition & 1 deletion include/datadog/span_sampler_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class FinalizedSpanSamplerConfig {
};

std::vector<Rule> rules;
std::unordered_map<ConfigName, ConfigMetadata> metadata;
std::unordered_map<ConfigName, std::vector<ConfigMetadata>> metadata;
};

Expected<FinalizedSpanSamplerConfig> finalize_config(const SpanSamplerConfig&,
Expand Down
2 changes: 1 addition & 1 deletion include/datadog/trace_sampler_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class FinalizedTraceSamplerConfig {
public:
double max_per_second;
std::vector<TraceSamplerRule> rules;
std::unordered_map<ConfigName, ConfigMetadata> metadata;
std::unordered_map<ConfigName, std::vector<ConfigMetadata>> metadata;

public:
/// Returns the trace sampler configuration when APM Tracing is disabled.
Expand Down
2 changes: 1 addition & 1 deletion include/datadog/tracer_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ class FinalizedTracerConfig final {
std::string integration_name;
std::string integration_version;
bool report_traces;
std::unordered_map<ConfigName, ConfigMetadata> metadata;
std::unordered_map<ConfigName, std::vector<ConfigMetadata>> metadata;
Baggage::Options baggage_opts;
HTTPClient::URL agent_url;
std::shared_ptr<EventScheduler> event_scheduler;
Expand Down
10 changes: 8 additions & 2 deletions src/datadog/config_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,12 +287,18 @@ namespace rc = datadog::remote_config;

ConfigManager::ConfigManager(const FinalizedTracerConfig& config)
: clock_(config.clock),
default_metadata_(config.metadata),
trace_sampler_(
std::make_shared<TraceSampler>(config.trace_sampler, clock_)),
rules_(config.trace_sampler.rules),
span_defaults_(std::make_shared<SpanDefaults>(config.defaults)),
report_traces_(config.report_traces) {}
report_traces_(config.report_traces) {
// Extract winning value (last entry) from each config's metadata history
for (const auto& [name, metadata_vec] : config.metadata) {
if (!metadata_vec.empty()) {
default_metadata_[name] = metadata_vec.back();
}
}
}

rc::Products ConfigManager::get_products() { return rc::product::APM_TRACING; }

Expand Down
4 changes: 2 additions & 2 deletions src/datadog/datadog_agent_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ Expected<FinalizedDatadogAgentConfig> finalize_config(
return std::move(*error);
}
result.url = *parsed_url;
result.metadata[ConfigName::AGENT_URL] =
ConfigMetadata(ConfigName::AGENT_URL, url, origin);
result.metadata[ConfigName::AGENT_URL] = {
ConfigMetadata(ConfigName::AGENT_URL, url, origin)};

// Starting Datadog Agent 7.62.0, the admission controller inject a unique
// identifier through `DD_EXTERNAL_ENV`. This uid is used for origin
Expand Down
24 changes: 12 additions & 12 deletions src/datadog/span_sampler_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,20 +228,21 @@ Expected<FinalizedSpanSamplerConfig> finalize_config(
}

FinalizedSpanSamplerConfig result;

std::vector<SpanSamplerConfig::Rule> rules;
Optional<std::vector<SpanSamplerConfig::Rule>> env_rules;
Optional<std::vector<SpanSamplerConfig::Rule>> user_rules;
if (!env_config->rules.empty()) {
rules = env_config->rules;
result.metadata[ConfigName::SPAN_SAMPLING_RULES] =
ConfigMetadata(ConfigName::SPAN_SAMPLING_RULES, to_string(rules),
ConfigMetadata::Origin::ENVIRONMENT_VARIABLE);
} else if (!user_config.rules.empty()) {
rules = user_config.rules;
result.metadata[ConfigName::SPAN_SAMPLING_RULES] =
ConfigMetadata(ConfigName::SPAN_SAMPLING_RULES, to_string(rules),
ConfigMetadata::Origin::CODE);
env_rules = env_config->rules;
}
if (!user_config.rules.empty()) {
user_rules = user_config.rules;
}

std::vector<SpanSamplerConfig::Rule> rules = resolve_and_record_config(
env_rules, user_rules, &result.metadata, ConfigName::SPAN_SAMPLING_RULES,
nullptr, [](const std::vector<SpanSamplerConfig::Rule> &r) {
return to_string(r);
});

for (const auto &rule : rules) {
auto maybe_rate = Rate::from(rule.sample_rate);
if (auto *error = maybe_rate.if_error()) {
Expand Down Expand Up @@ -276,7 +277,6 @@ Expected<FinalizedSpanSamplerConfig> finalize_config(
finalized.max_per_second = rule.max_per_second;
result.rules.push_back(std::move(finalized));
}

return result;
}

Expand Down
37 changes: 12 additions & 25 deletions src/datadog/trace_sampler_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,14 @@ Expected<FinalizedTraceSamplerConfig> finalize_config(

if (!env_config->rules.empty()) {
rules = std::move(env_config->rules);
result.metadata[ConfigName::TRACE_SAMPLING_RULES] =
result.metadata[ConfigName::TRACE_SAMPLING_RULES] = {
ConfigMetadata(ConfigName::TRACE_SAMPLING_RULES, to_string(rules),
ConfigMetadata::Origin::ENVIRONMENT_VARIABLE);
ConfigMetadata::Origin::ENVIRONMENT_VARIABLE)};
} else if (!config.rules.empty()) {
rules = std::move(config.rules);
result.metadata[ConfigName::TRACE_SAMPLING_RULES] =
result.metadata[ConfigName::TRACE_SAMPLING_RULES] = {
ConfigMetadata(ConfigName::TRACE_SAMPLING_RULES, to_string(rules),
ConfigMetadata::Origin::CODE);
ConfigMetadata::Origin::CODE)};
}

for (const auto &rule : rules) {
Expand All @@ -191,27 +191,16 @@ Expected<FinalizedTraceSamplerConfig> finalize_config(
result.rules.emplace_back(std::move(finalized_rule));
}

Optional<double> sample_rate;
if (env_config->sample_rate) {
sample_rate = env_config->sample_rate;
result.metadata[ConfigName::TRACE_SAMPLING_RATE] = ConfigMetadata(
ConfigName::TRACE_SAMPLING_RATE, to_string(*sample_rate, 1),
ConfigMetadata::Origin::ENVIRONMENT_VARIABLE);
} else if (config.sample_rate) {
sample_rate = config.sample_rate;
result.metadata[ConfigName::TRACE_SAMPLING_RATE] = ConfigMetadata(
ConfigName::TRACE_SAMPLING_RATE, to_string(*sample_rate, 1),
ConfigMetadata::Origin::CODE);
} else {
result.metadata[ConfigName::TRACE_SAMPLING_RATE] =
ConfigMetadata(ConfigName::TRACE_SAMPLING_RATE, "1.0",
ConfigMetadata::Origin::DEFAULT);
}
Optional<double> sample_rate = resolve_and_record_config(
env_config->sample_rate, config.sample_rate, &result.metadata,
ConfigName::TRACE_SAMPLING_RATE, 1.0,
[](const double &d) { return to_string(d, 1); });

bool is_sample_rate_provided = env_config->sample_rate || config.sample_rate;
// If `sample_rate` was specified, then it translates to a "catch-all" rule
// appended to the end of `rules`. First, though, we have to make sure the
// sample rate is valid.
if (sample_rate) {
if (sample_rate && is_sample_rate_provided) {
auto maybe_rate = Rate::from(*sample_rate);
if (auto *error = maybe_rate.if_error()) {
return error->with_prefix(
Expand All @@ -225,11 +214,9 @@ Expected<FinalizedTraceSamplerConfig> finalize_config(
result.rules.emplace_back(std::move(finalized_rule));
}

std::unordered_map<ConfigName, std::vector<ConfigMetadata>>
telemetry_configs_tmp;
double max_per_second = resolve_and_record_config(
env_config->max_per_second, config.max_per_second, &telemetry_configs_tmp,
&result.metadata, ConfigName::TRACE_SAMPLING_LIMIT, 100.0,
env_config->max_per_second, config.max_per_second, &result.metadata,
ConfigName::TRACE_SAMPLING_LIMIT, 100.0,
[](const double &d) { return std::to_string(d); });

const auto allowed_types = {FP_NORMAL, FP_SUBNORMAL};
Expand Down
Loading