Skip to content
Merged
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
21 changes: 20 additions & 1 deletion src/datadog/config_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,20 @@ ConfigManager::ConfigManager(const FinalizedTracerConfig& config)
: clock_(config.clock),
default_trace_sampler_(
std::make_shared<TraceSampler>(config.trace_sampler, clock_)),
current_trace_sampler_(default_trace_sampler_) {}
current_trace_sampler_(default_trace_sampler_),
default_span_defaults_(std::make_shared<SpanDefaults>(config.defaults)),
current_span_defaults_(default_span_defaults_) {}

std::shared_ptr<TraceSampler> ConfigManager::get_trace_sampler() {
std::lock_guard<std::mutex> lock(mutex_);
return current_trace_sampler_;
}

std::shared_ptr<const SpanDefaults> ConfigManager::get_span_defaults() {
std::lock_guard<std::mutex> lock(mutex_);
return current_span_defaults_;
}

void ConfigManager::update(const ConfigUpdate& conf) {
std::lock_guard<std::mutex> lock(mutex_);

Expand All @@ -30,16 +37,28 @@ void ConfigManager::update(const ConfigUpdate& conf) {
} else {
current_trace_sampler_ = default_trace_sampler_;
}

if (conf.tags) {
auto new_span_defaults =
std::make_shared<SpanDefaults>(*current_span_defaults_);
new_span_defaults->tags = std::move(*conf.tags);

current_span_defaults_ = new_span_defaults;
} else {
current_span_defaults_ = default_span_defaults_;
}
}

void ConfigManager::reset() {
std::lock_guard<std::mutex> lock(mutex_);
current_trace_sampler_ = default_trace_sampler_;
current_span_defaults_ = default_span_defaults_;
}

nlohmann::json ConfigManager::config_json() const {
std::lock_guard<std::mutex> lock(mutex_);
return nlohmann::json{
{"default", to_json(*current_span_defaults_)},
{"trace_sampler", current_trace_sampler_->config_json()}};
}

Expand Down
7 changes: 7 additions & 0 deletions src/datadog/config_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "clock.h"
#include "config_update.h"
#include "json.hpp"
#include "span_defaults.h"
#include "tracer_config.h"

namespace datadog {
Expand All @@ -21,12 +22,18 @@ class ConfigManager {
std::shared_ptr<TraceSampler> default_trace_sampler_;
std::shared_ptr<TraceSampler> current_trace_sampler_;

std::shared_ptr<const SpanDefaults> default_span_defaults_;
std::shared_ptr<const SpanDefaults> current_span_defaults_;

public:
ConfigManager(const FinalizedTracerConfig& config);

// Return the `TraceSampler` consistent with the most recent configuration.
std::shared_ptr<TraceSampler> get_trace_sampler();

// Return the `SpanDefaults` consistent with the most recent configuration.
std::shared_ptr<const SpanDefaults> get_span_defaults();

// Apply the specified `conf` update.
void update(const ConfigUpdate& conf);

Expand Down
3 changes: 3 additions & 0 deletions src/datadog/config_update.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include <unordered_map>

#include "optional"
#include "trace_sampler_config.h"

Expand All @@ -13,6 +15,7 @@ namespace tracing {
// remote configuration value.
struct ConfigUpdate {
Optional<TraceSamplerConfig> trace_sampler;
Optional<std::unordered_map<std::string, std::string>> tags;
};

} // namespace tracing
Expand Down
37 changes: 36 additions & 1 deletion src/datadog/remote_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ namespace {
// within the array.
enum CapabilitiesFlag : uint64_t {
APM_TRACING_SAMPLE_RATE = 1 << 12,
APM_TRACING_TAGS = 1 << 15
};

constexpr std::array<uint8_t, sizeof(uint64_t)> capabilities_byte_array(
Expand All @@ -43,11 +44,36 @@ constexpr std::array<uint8_t, sizeof(uint64_t)> capabilities_byte_array(
}

constexpr std::array<uint8_t, sizeof(uint64_t)> k_apm_capabilities =
capabilities_byte_array(APM_TRACING_SAMPLE_RATE);
capabilities_byte_array(APM_TRACING_SAMPLE_RATE | APM_TRACING_TAGS);

constexpr StringView k_apm_product = "APM_TRACING";
constexpr StringView k_apm_product_path_substring = "/APM_TRACING/";

Expected<std::unordered_map<std::string, std::string>> parse_tags(
const std::vector<StringView>& list_of_tags) {
std::unordered_map<std::string, std::string> tags;

// Within a tag, the key and value are separated by a colon (":").
for (const StringView& token : list_of_tags) {
const auto separator = std::find(token.begin(), token.end(), ':');
if (separator == token.end()) {
std::string message;
message += "Unable to parse a key/value from the tag text \"";
append(message, token);
message +=
"\" because it does not contain the separator character \":\".";
return Error{Error::TAG_MISSING_SEPARATOR, std::move(message)};
}

std::string key{token.begin(), separator};
std::string value{separator + 1, token.end()};
// If there are duplicate values, then the last one wins.
tags.insert_or_assign(std::move(key), std::move(value));
}

return tags;
}

ConfigUpdate parse_dynamic_config(const nlohmann::json& j) {
ConfigUpdate config_update;

Expand All @@ -59,6 +85,15 @@ ConfigUpdate parse_dynamic_config(const nlohmann::json& j) {
config_update.trace_sampler = trace_sampler_cfg;
}

if (auto tags_it = j.find("tracing_tags"); tags_it != j.cend()) {
auto parsed_tags = parse_tags(*tags_it);
if (parsed_tags.if_error()) {
// TODO: report to telemetry
} else {
config_update.tags = std::move(*parsed_tags);
}
}

return config_update;
}

Expand Down
15 changes: 8 additions & 7 deletions src/datadog/tracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ Tracer::Tracer(const FinalizedTracerConfig& config,
: logger_(config.logger),
config_manager_(std::make_shared<ConfigManager>(config)),
collector_(/* see constructor body */),
defaults_(std::make_shared<SpanDefaults>(config.defaults)),
runtime_id_(config.runtime_id ? *config.runtime_id
: RuntimeID::generate()),
signature_{runtime_id_, config.defaults.service,
Expand Down Expand Up @@ -83,7 +82,6 @@ nlohmann::json Tracer::config_json() const {
// clang-format off
auto config = nlohmann::json::object({
{"version", tracer_version_string},
{"defaults", to_json(*defaults_)},
{"runtime_id", runtime_id_.string()},
{"collector", collector_->config_json()},
{"span_sampler", span_sampler_->config_json()},
Expand All @@ -106,8 +104,9 @@ nlohmann::json Tracer::config_json() const {
Span Tracer::create_span() { return create_span(SpanConfig{}); }

Span Tracer::create_span(const SpanConfig& config) {
auto defaults = config_manager_->get_span_defaults();
auto span_data = std::make_unique<SpanData>();
span_data->apply_config(*defaults_, config, clock_);
span_data->apply_config(*defaults, config, clock_);
span_data->trace_id = generator_->trace_id(span_data->start);
span_data->span_id = span_data->trace_id.low;
span_data->parent_id = 0;
Expand All @@ -122,7 +121,7 @@ Span Tracer::create_span(const SpanConfig& config) {
tracer_telemetry_->metrics().tracer.trace_segments_created_new.inc();
const auto segment = std::make_shared<TraceSegment>(
logger_, collector_, tracer_telemetry_,
config_manager_->get_trace_sampler(), span_sampler_, defaults_,
config_manager_->get_trace_sampler(), span_sampler_, defaults,
runtime_id_, sampling_delegation_enabled_,
false /* sampling_decision_was_delegated_to_me */, injection_styles_,
hostname_, nullopt /* origin */, tags_header_max_size_,
Expand Down Expand Up @@ -241,7 +240,8 @@ Expected<Span> Tracer::extract_span(const DictReader& reader,

// We're done extracting fields. Now create the span.
// This is similar to what we do in `create_span`.
span_data->apply_config(*defaults_, config, clock_);
span_data->apply_config(*config_manager_->get_span_defaults(), config,
clock_);
span_data->span_id = generator_->span_id();
span_data->trace_id = *trace_id;
span_data->parent_id = *parent_id;
Expand Down Expand Up @@ -293,8 +293,9 @@ Expected<Span> Tracer::extract_span(const DictReader& reader,
tracer_telemetry_->metrics().tracer.trace_segments_created_continued.inc();
const auto segment = std::make_shared<TraceSegment>(
logger_, collector_, tracer_telemetry_,
config_manager_->get_trace_sampler(), span_sampler_, defaults_,
runtime_id_, sampling_delegation_enabled_, delegate_sampling_decision,
config_manager_->get_trace_sampler(), span_sampler_,
config_manager_->get_span_defaults(), runtime_id_,
sampling_delegation_enabled_, delegate_sampling_decision,
injection_styles_, hostname_, std::move(origin), tags_header_max_size_,
std::move(trace_tags), std::move(sampling_decision),
std::move(additional_w3c_tracestate),
Expand Down
1 change: 0 additions & 1 deletion src/datadog/tracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ class Tracer {
std::shared_ptr<Logger> logger_;
std::shared_ptr<ConfigManager> config_manager_;
std::shared_ptr<Collector> collector_;
std::shared_ptr<const SpanDefaults> defaults_;
RuntimeID runtime_id_;
TracerSignature signature_;
std::shared_ptr<TracerTelemetry> tracer_telemetry_;
Expand Down
5 changes: 4 additions & 1 deletion test/test_remote_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ REMOTE_CONFIG_TEST("response processing") {
"target_files": [
{
"path": "foo/APM_TRACING/30",
"raw": "eyAiaWQiOiAiODI3ZWFjZjhkYmMzYWIxNDM0ZDMyMWNiODFkZmJmN2FmZTY1NGE0YjYxMTFjZjE2NjBiNzFjY2Y4OTc4MTkzOCIsICJyZXZpc2lvbiI6IDE2OTgxNjcxMjYwNjQsICJzY2hlbWFfdmVyc2lvbiI6ICJ2MS4wLjAiLCAiYWN0aW9uIjogImVuYWJsZSIsICJsaWJfY29uZmlnIjogeyAibGlicmFyeV9sYW5ndWFnZSI6ICJhbGwiLCAibGlicmFyeV92ZXJzaW9uIjogImxhdGVzdCIsICJzZXJ2aWNlX25hbWUiOiAidGVzdHN2YyIsICJlbnYiOiAidGVzdCIsICJ0cmFjaW5nX2VuYWJsZWQiOiB0cnVlLCAidHJhY2luZ19zYW1wbGluZ19yYXRlIjogMC42IH0sICJzZXJ2aWNlX3RhcmdldCI6IHsgInNlcnZpY2UiOiAidGVzdHN2YyIsICJlbnYiOiAidGVzdCIgfSB9"
"raw": "eyAiaWQiOiAiODI3ZWFjZjhkYmMzYWIxNDM0ZDMyMWNiODFkZmJmN2FmZTY1NGE0YjYxMTFjZjE2NjBiNzFjY2Y4OTc4MTkzOCIsICJyZXZpc2lvbiI6IDE2OTgxNjcxMjYwNjQsICJzY2hlbWFfdmVyc2lvbiI6ICJ2MS4wLjAiLCAiYWN0aW9uIjogImVuYWJsZSIsICJsaWJfY29uZmlnIjogeyAibGlicmFyeV9sYW5ndWFnZSI6ICJhbGwiLCAibGlicmFyeV92ZXJzaW9uIjogImxhdGVzdCIsICJzZXJ2aWNlX25hbWUiOiAidGVzdHN2YyIsICJlbnYiOiAidGVzdCIsICJ0cmFjaW5nX2VuYWJsZWQiOiB0cnVlLCAidHJhY2luZ19zYW1wbGluZ19yYXRlIjogMC42LCAidHJhY2luZ190YWdzIjogWyJoZWxsbzp3b3JsZCIsICJmb286YmFyIl0gfSwgInNlcnZpY2VfdGFyZ2V0IjogeyAic2VydmljZSI6ICJ0ZXN0c3ZjIiwgImVudiI6ICJ0ZXN0IiB9IH0="
}
]
})";
Expand All @@ -180,10 +180,13 @@ REMOTE_CONFIG_TEST("response processing") {
REQUIRE(!response_json.is_discarded());

const auto old_trace_sampler = config_manager->get_trace_sampler();
const auto old_span_defaults = config_manager->get_span_defaults();
rc.process_response(response_json);
const auto new_trace_sampler = config_manager->get_trace_sampler();
const auto new_span_defaults = config_manager->get_span_defaults();

CHECK(new_trace_sampler != old_trace_sampler);
CHECK(new_span_defaults != old_span_defaults);

SECTION("reset confguration") {
SECTION(
Expand Down