Skip to content

Commit 5175648

Browse files
[OTel] Add DD_TAGS resource-attribute test for OTLP trace metrics (#7283)
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 1733c7b commit 5175648

6 files changed

Lines changed: 113 additions & 6 deletions

File tree

manifests/golang.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1468,6 +1468,7 @@ manifest:
14681468
: "irrelevant (\"Go tracer decided to always set _dd1.sr.eausr: 1 for truthy analytics.event inputs, else 0\")"
14691469
tests/parametric/test_otel_span_with_baggage.py::Test_Otel_Span_With_Baggage: missing_feature
14701470
tests/parametric/test_otlp_trace_metrics.py: missing_feature
1471+
tests/parametric/test_otlp_trace_metrics.py::Test_FR08_AdditionalTags: 'missing_feature (DD_TAGS are not yet emitted as datadog.<key> resource attributes; support coming in a future PR)'
14711472
tests/parametric/test_parametric_endpoints.py::TestRemoteConfigApplyEndpoint: incomplete_test_app (POST /trace/remote-config/apply only implemented in the python parametric app)
14721473
tests/parametric/test_parametric_endpoints.py::Test_Parametric_DDSpan_Add_Link: missing_feature (add_link endpoint is not implemented)
14731474
tests/parametric/test_parametric_endpoints.py::Test_Parametric_DDSpan_Set_Resource: missing_feature (does not support setting a resource name after span creation)

manifests/java.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3925,6 +3925,7 @@ manifest:
39253925
- declaration: missing_feature (OTel resource naming implemented in 1.24.0)
39263926
component_version: <=1.23.0
39273927
tests/parametric/test_otlp_trace_metrics.py: missing_feature
3928+
tests/parametric/test_otlp_trace_metrics.py::Test_FR08_AdditionalTags: 'missing_feature (DD_TAGS are not yet emitted as datadog.<key> resource attributes; support coming in a future PR)'
39283929
tests/parametric/test_parametric_endpoints.py::TestRemoteConfigApplyEndpoint: incomplete_test_app (POST /trace/remote-config/apply only implemented in the python parametric app)
39293930
tests/parametric/test_parametric_endpoints.py::Test_Parametric_DDSpan_Add_Link: incomplete_test_app (add_link endpoint is not implemented)
39303931
tests/parametric/test_parametric_endpoints.py::Test_Parametric_DDTrace_Baggage: # Modified by easy win activation script

manifests/nodejs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2202,6 +2202,7 @@ manifest:
22022202
tests/parametric/test_otlp_trace_metrics.py: *ref_5_111_0
22032203
tests/parametric/test_otlp_trace_metrics.py::Test_FR05_Sampling_Independence::test_fr05_1_metrics_computed_before_sampling: missing_feature (nodejs does not drop sampled-out traces when client-side stats are computed)
22042204
tests/parametric/test_otlp_trace_metrics.py::Test_FR06_Otel_Resource_Attributes::test_fr06_10_hostname: irrelevant (DD_HOSTNAME is only supported in Python)
2205+
tests/parametric/test_otlp_trace_metrics.py::Test_FR08_AdditionalTags: 'missing_feature (DD_TAGS are not yet emitted as datadog.<key> resource attributes; support coming in a future PR)'
22052206
tests/parametric/test_otlp_trace_metrics.py::Test_FR08_Datadog_Attributes::test_fr08_5_top_level_child_different_service: missing_feature (nodejs does not tag child spans with a different service than their parent as top-level)
22062207
tests/parametric/test_parametric_endpoints.py::TestRemoteConfigApplyEndpoint: incomplete_test_app (POST /trace/remote-config/apply only implemented in the python parametric app)
22072208
tests/parametric/test_parametric_endpoints.py::Test_Parametric_DDSpan_Set_Resource: incomplete_test_app (set_resource endpoint is not implemented)

manifests/python.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,6 +2001,7 @@ manifest:
20012001
tests/parametric/test_otel_tracer.py::Test_Otel_Tracer: v2.8.0
20022002
tests/parametric/test_otlp_trace_metrics.py: v4.13.0-dev
20032003
tests/parametric/test_otlp_trace_metrics.py::Test_FR06_Otel_Span_Attributes::test_fr06_7_rpc_status_code: missing_feature (Requires libdatadog v38, will be added in future release)
2004+
tests/parametric/test_otlp_trace_metrics.py::Test_FR08_AdditionalTags: 'missing_feature (DD_TAGS are not yet emitted as datadog.<key> resource attributes; support coming in a future PR)'
20042005
tests/parametric/test_parametric_endpoints.py::Test_Parametric_DDTrace_Baggage: v2.16.0
20052006
tests/parametric/test_parametric_endpoints.py::Test_Parametric_FFE_Start: v4.0.0
20062007
tests/parametric/test_parametric_endpoints.py::Test_Parametric_Otel_Baggage: v2.16.0

manifests/ruby.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2375,6 +2375,7 @@ manifest:
23752375
tests/parametric/test_otlp_trace_metrics.py::Test_FR06_Otel_Resource_Attributes: missing_feature
23762376
tests/parametric/test_otlp_trace_metrics.py::Test_FR06_Otel_Span_Attributes: missing_feature
23772377
tests/parametric/test_otlp_trace_metrics.py::Test_FR07_Otel_Semantics_Mode: missing_feature
2378+
tests/parametric/test_otlp_trace_metrics.py::Test_FR08_AdditionalTags: missing_feature
23782379
tests/parametric/test_otlp_trace_metrics.py::Test_FR08_Datadog_Attributes: missing_feature
23792380
tests/parametric/test_otlp_trace_metrics.py::Test_FR09_Red_Metric_Derivation: missing_feature
23802381
tests/parametric/test_otlp_trace_metrics.py::Test_FR15_Client_Computed_Stats_Header::test_fr15_1_header_set_when_enabled: missing_feature

tests/parametric/test_otlp_trace_metrics.py

Lines changed: 108 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
FR06 OTel semantic-convention attributes wherever applicable Test_FR06_Otel_Span_Attributes,
1515
Test_FR06_Otel_Resource_Attributes
1616
FR07 DD_TRACE_OTEL_SEMANTICS_ENABLED=true -> only OTel attributes Test_FR07_Otel_Semantics_Mode
17-
FR08 DD_TRACE_OTEL_SEMANTICS_ENABLED=false (default) -> datadog.* allowed Test_FR08_Datadog_Attributes
17+
FR08 DD_TRACE_OTEL_SEMANTICS_ENABLED=false (default) -> datadog.* allowed Test_FR08_Datadog_Attributes,
18+
DD_TAGS / OTEL_RESOURCE_ATTRIBUTES / DD_TRACE_STATS_ADDITIONAL_TAGS Test_FR08_AdditionalTags
1819
FR09 Derive request/span count, error count, and duration Test_FR09_Red_Metric_Derivation
1920
FR10 Transport over OTLP HTTP/JSON (set in _BASE_ENVVARS, exercised by every test)
2021
FR11 SDKs without client-side stats are out of scope (handled by manifests / @features gating)
@@ -157,6 +158,8 @@ def _attr_value(item: dict) -> Any: # noqa: ANN401
157158
return int(value["intValue"])
158159
if "doubleValue" in value:
159160
return value["doubleValue"]
161+
if "arrayValue" in value:
162+
return [_attr_value({"value": element}) for element in value["arrayValue"].get("values", [])]
160163
return None
161164

162165

@@ -1162,11 +1165,8 @@ def test_fr08_9_top_level_not_mixed_with_measured(
11621165
test_agent: TestAgentAPI,
11631166
test_library: APMLibrary,
11641167
):
1165-
"""A top-level and a non-top-level span with identical dimensions bucket separately.
1166-
1167-
The measured child (selected per FR04) shares every aggregation dimension with its top-level root,
1168-
yet the two must yield separate data points -- one datadog.span.top_level=true, one false -- rather
1169-
than being merged into a single bucket mislabeled false.
1168+
"""A top-level and a non-top-level (measured) span with identical dimensions must bucket separately,
1169+
each keeping its own datadog.span.top_level flag rather than merging into one bucket mislabeled false.
11701170
"""
11711171
with test_library as t:
11721172
with (
@@ -1190,6 +1190,108 @@ def test_fr08_9_top_level_not_mixed_with_measured(
11901190
)
11911191

11921192

1193+
@scenarios.parametric
1194+
@features.client_side_stats_supported
1195+
class Test_FR08_AdditionalTags:
1196+
"""FR08: DD_TAGS (tracer_dd_tags) / OTEL_RESOURCE_ATTRIBUTES surface as resource attributes and
1197+
DD_TRACE_STATS_ADDITIONAL_TAGS (additional_metric_tags) as data-point attributes (support pending in some SDKs).
1198+
"""
1199+
1200+
@pytest.mark.parametrize(
1201+
"library_env",
1202+
[
1203+
{
1204+
**DEFAULT_ENVVARS,
1205+
"DD_TAGS": (
1206+
"team:apm,tier:backend,"
1207+
"service:ignored-svc,env:ignored-env,version:ignored-ver,"
1208+
"runtime_id:ignored-rid,runtime-id:ignored-rid2"
1209+
),
1210+
}
1211+
],
1212+
)
1213+
def test_fr08_10_dd_tags_resource_attributes(
1214+
self,
1215+
otlp_trace_metrics_library_env: dict[str, str], # noqa: ARG002
1216+
test_agent: TestAgentAPI,
1217+
test_library: APMLibrary,
1218+
):
1219+
"""Global DD_TAGS surface as the tracer_dd_tags resource-attribute container (repeated key:value
1220+
strings) in default mode; reserved service/env/version/runtime_id/runtime-id keys are ignored.
1221+
"""
1222+
with test_library as t:
1223+
with t.dd_start_span(name="web.request", service=SERVICE, typestr="web"):
1224+
pass
1225+
t.dd_flush()
1226+
1227+
metrics = test_agent.wait_for_num_otlp_metrics(num=1)
1228+
resource_attrs = _resource_attributes(metrics)
1229+
tracer_dd_tags = resource_attrs.get("tracer_dd_tags") or []
1230+
assert "team:apm" in tracer_dd_tags, f"Expected team:apm in tracer_dd_tags, got: {resource_attrs}"
1231+
assert "tier:backend" in tracer_dd_tags, f"Expected tier:backend in tracer_dd_tags, got: {resource_attrs}"
1232+
for reserved in ("service", "env", "version", "runtime_id", "runtime-id"):
1233+
assert not any(str(entry).startswith(f"{reserved}:") for entry in tracer_dd_tags), (
1234+
f"Reserved DD_TAGS key {reserved!r} must be ignored, got: {tracer_dd_tags}"
1235+
)
1236+
assert resource_attrs.get("service.name") == SERVICE, (
1237+
f"DD_TAGS service must not override configured service.name={SERVICE}, got: {resource_attrs}"
1238+
)
1239+
1240+
@pytest.mark.parametrize(
1241+
"library_env",
1242+
[{**DEFAULT_ENVVARS, "OTEL_RESOURCE_ATTRIBUTES": "team=apm,deployment.region=us-east-1"}],
1243+
)
1244+
def test_fr08_11_otel_resource_attributes_env(
1245+
self,
1246+
otlp_trace_metrics_library_env: dict[str, str], # noqa: ARG002
1247+
test_agent: TestAgentAPI,
1248+
test_library: APMLibrary,
1249+
):
1250+
"""OTEL_RESOURCE_ATTRIBUTES is an alias for DD_TAGS, so its entries also surface in the
1251+
tracer_dd_tags resource-attribute container.
1252+
"""
1253+
with test_library as t:
1254+
with t.dd_start_span(name="web.request", service=SERVICE, typestr="web"):
1255+
pass
1256+
t.dd_flush()
1257+
1258+
metrics = test_agent.wait_for_num_otlp_metrics(num=1)
1259+
tracer_dd_tags = _resource_attributes(metrics).get("tracer_dd_tags") or []
1260+
assert "team:apm" in tracer_dd_tags, f"Expected team:apm in tracer_dd_tags, got: {tracer_dd_tags}"
1261+
assert "deployment.region:us-east-1" in tracer_dd_tags, (
1262+
f"Expected deployment.region:us-east-1 in tracer_dd_tags, got: {tracer_dd_tags}"
1263+
)
1264+
1265+
@pytest.mark.parametrize(
1266+
"library_env",
1267+
[{**DEFAULT_ENVVARS, "DD_TRACE_STATS_ADDITIONAL_TAGS": "customer.tier,region"}],
1268+
)
1269+
def test_fr08_12_stats_additional_tags(
1270+
self,
1271+
otlp_trace_metrics_library_env: dict[str, str], # noqa: ARG002
1272+
test_agent: TestAgentAPI,
1273+
test_library: APMLibrary,
1274+
):
1275+
"""Span tags named in DD_TRACE_STATS_ADDITIONAL_TAGS surface as the additional_metric_tags
1276+
data-point container (repeated key:value strings), since their values vary per span.
1277+
"""
1278+
with test_library as t:
1279+
with t.dd_start_span(name="web.request", service=SERVICE, typestr="web") as span:
1280+
span.set_meta("customer.tier", "gold")
1281+
span.set_meta("region", "us-east-1")
1282+
t.dd_flush()
1283+
1284+
metrics = test_agent.wait_for_num_otlp_metrics(num=1)
1285+
attrs = _data_point_attrs(_duration_data_points(metrics)[0])
1286+
additional_metric_tags = attrs.get("additional_metric_tags") or []
1287+
assert "customer.tier:gold" in additional_metric_tags, (
1288+
f"Expected customer.tier:gold in additional_metric_tags, got: {attrs}"
1289+
)
1290+
assert "region:us-east-1" in additional_metric_tags, (
1291+
f"Expected region:us-east-1 in additional_metric_tags, got: {attrs}"
1292+
)
1293+
1294+
11931295
@scenarios.parametric
11941296
@features.client_side_stats_supported
11951297
class Test_FR09_Red_Metric_Derivation:

0 commit comments

Comments
 (0)