Skip to content

Commit ffea35c

Browse files
fix: Apply "version" tag only when the span service name matches the default service name (#157)
* test: Add unit test to assert that when a span has an overridden service name that does not match the tracer default, then no "version" tag is added * feat: Implement consistency for "version" tag - Apply version tag to a span only if its service name matches the default service name Issues: APMAPI-517 * code review from dmehala - Make the logic used to apply `version` tag more explicit. - Removed unused variable in test. --------- Co-authored-by: Damien Mehala <[email protected]>
1 parent 6fe4dd9 commit ffea35c

File tree

2 files changed

+74
-5
lines changed

2 files changed

+74
-5
lines changed

src/datadog/span_data.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,19 @@ Optional<StringView> SpanData::version() const {
3737

3838
void SpanData::apply_config(const SpanDefaults& defaults,
3939
const SpanConfig& config, const Clock& clock) {
40-
service = config.service.value_or(defaults.service);
40+
std::string version;
41+
if (config.service) {
42+
service = *config.service;
43+
version = config.version.value_or("");
44+
} else {
45+
service = defaults.service;
46+
version = defaults.version;
47+
}
48+
49+
if (!version.empty()) {
50+
tags.insert_or_assign(tags::version, version);
51+
}
52+
4153
name = config.name.value_or(defaults.name);
4254

4355
for (const auto& item : defaults.tags) {
@@ -47,10 +59,7 @@ void SpanData::apply_config(const SpanDefaults& defaults,
4759
if (!environment.empty()) {
4860
tags.insert_or_assign(tags::environment, environment);
4961
}
50-
std::string version = config.version.value_or(defaults.version);
51-
if (!version.empty()) {
52-
tags.insert_or_assign(tags::version, version);
53-
}
62+
5463
for (const auto& [key, value] : config.tags) {
5564
tags.insert_or_assign(key, value);
5665
}

test/test_tracer.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,18 @@ TEST_CASE("tracer span defaults") {
9090
REQUIRE(overrides.name != config.name);
9191
REQUIRE(overrides.tags != config.tags);
9292

93+
// Test behaviors when the config overrides the service but leaves other
94+
// fields empty
95+
SpanConfig overrides_with_empty_values;
96+
overrides_with_empty_values.service = "barsvc";
97+
98+
REQUIRE(overrides_with_empty_values.service != config.service);
99+
REQUIRE(overrides_with_empty_values.service_type != config.service_type);
100+
REQUIRE(overrides_with_empty_values.environment != config.environment);
101+
REQUIRE(overrides_with_empty_values.version != config.version);
102+
REQUIRE(overrides_with_empty_values.name != config.name);
103+
REQUIRE(overrides_with_empty_values.tags != config.tags);
104+
93105
// Some of the sections below create a span from extracted trace context.
94106
const std::unordered_map<std::string, std::string> headers{
95107
{"x-datadog-trace-id", "123"}, {"x-datadog-parent-id", "456"}};
@@ -117,6 +129,9 @@ TEST_CASE("tracer span defaults") {
117129
REQUIRE(root.version() == config.version);
118130
REQUIRE(root.name == config.name);
119131
REQUIRE_THAT(root.tags, ContainsSubset(*config.tags));
132+
133+
REQUIRE(root.tags.count(tags::version) == 1);
134+
REQUIRE(root.tags.find(tags::version)->second == config.version);
120135
}
121136

122137
SECTION("can be overridden in a root span") {
@@ -141,6 +156,9 @@ TEST_CASE("tracer span defaults") {
141156
REQUIRE(root.version() == overrides.version);
142157
REQUIRE(root.name == overrides.name);
143158
REQUIRE_THAT(root.tags, ContainsSubset(overrides.tags));
159+
160+
REQUIRE(root.tags.count(tags::version) == 1);
161+
REQUIRE(root.tags.find(tags::version)->second == overrides.version);
144162
}
145163

146164
SECTION("are honored in an extracted span") {
@@ -165,6 +183,9 @@ TEST_CASE("tracer span defaults") {
165183
REQUIRE(span.version() == config.version);
166184
REQUIRE(span.name == config.name);
167185
REQUIRE_THAT(span.tags, ContainsSubset(*config.tags));
186+
187+
REQUIRE(span.tags.count(tags::version) == 1);
188+
REQUIRE(span.tags.find(tags::version)->second == config.version);
168189
}
169190

170191
SECTION("can be overridden in an extracted span") {
@@ -189,6 +210,9 @@ TEST_CASE("tracer span defaults") {
189210
REQUIRE(span.version() == overrides.version);
190211
REQUIRE(span.name == overrides.name);
191212
REQUIRE_THAT(span.tags, ContainsSubset(overrides.tags));
213+
214+
REQUIRE(span.tags.count(tags::version) == 1);
215+
REQUIRE(span.tags.find(tags::version)->second == overrides.version);
192216
}
193217

194218
SECTION("are honored in a child span") {
@@ -216,6 +240,9 @@ TEST_CASE("tracer span defaults") {
216240
REQUIRE(child.version() == config.version);
217241
REQUIRE(child.name == config.name);
218242
REQUIRE_THAT(child.tags, ContainsSubset(*config.tags));
243+
244+
REQUIRE(child.tags.count(tags::version) == 1);
245+
REQUIRE(child.tags.find(tags::version)->second == config.version);
219246
}
220247

221248
SECTION("can be overridden in a child span") {
@@ -243,6 +270,39 @@ TEST_CASE("tracer span defaults") {
243270
REQUIRE(child.version() == overrides.version);
244271
REQUIRE(child.name == overrides.name);
245272
REQUIRE_THAT(child.tags, ContainsSubset(overrides.tags));
273+
274+
REQUIRE(child.tags.count(tags::version) == 1);
275+
REQUIRE(child.tags.find(tags::version)->second == overrides.version);
276+
}
277+
278+
SECTION("can be overridden in a child span with empty values") {
279+
{
280+
auto parent = tracer.create_span();
281+
parent.create_child(overrides_with_empty_values);
282+
}
283+
REQUIRE(logger->error_count() == 0);
284+
285+
// Get the finished span from the collector and verify that its
286+
// properties have the configured default values.
287+
REQUIRE(collector->chunks.size() == 1);
288+
const auto& chunk = collector->chunks.front();
289+
// One span for the parent, and another for the child.
290+
REQUIRE(chunk.size() == 2);
291+
// The parent will be first, so the child is last.
292+
auto& child_ptr = chunk.back();
293+
REQUIRE(child_ptr);
294+
const auto& child = *child_ptr;
295+
296+
REQUIRE(child.service ==
297+
overrides_with_empty_values.service); // only service is set
298+
REQUIRE(child.service_type == config.service_type);
299+
REQUIRE(child.environment() == config.environment);
300+
REQUIRE(child.version() == nullopt); // version is not inherited since the
301+
// service name is different
302+
REQUIRE(child.name == config.name);
303+
REQUIRE_THAT(child.tags, ContainsSubset(*config.tags));
304+
305+
REQUIRE(child.tags.count(tags::version) == 0);
246306
}
247307
}
248308

0 commit comments

Comments
 (0)