Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
9 changes: 9 additions & 0 deletions src/datadog_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,15 @@ struct datadog_main_conf_t {
// `agent_url` is set by the `datadog_agent_url` directive.
std::optional<std::string> agent_url;

// DD_APM_RESOURCE_RENAMING_ENABLED
// Whether generation of http.endpoint is enabled.
ngx_flag_t resource_renaming_enabled{NGX_CONF_UNSET};

// DD_APM_RESOURCE_RENAMING_ALWAYS_SIMPLIFIED_ENDPOINT
// Whether http.endpoint is always calculated, even when http.route is
// present.
ngx_flag_t resource_renaming_always_simplified_endpoint{NGX_CONF_UNSET};

#ifdef WITH_WAF
// DD_APPSEC_ENABLED
ngx_flag_t appsec_enabled{NGX_CONF_UNSET};
Expand Down
19 changes: 19 additions & 0 deletions src/tracing/directives.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,25 @@ constexpr datadog::nginx::directive tracing_directives[] = {
nullptr,
},

{
"datadog_resource_renaming_enabled",
NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
ngx_conf_set_flag_slot,
NGX_HTTP_MAIN_CONF_OFFSET,
offsetof(datadog_main_conf_t, resource_renaming_enabled),
nullptr,
},

{
"datadog_resource_renaming_always_simplified_endpoint",
NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
ngx_conf_set_flag_slot,
NGX_HTTP_MAIN_CONF_OFFSET,
offsetof(datadog_main_conf_t,
resource_renaming_always_simplified_endpoint),
nullptr,
},

// aliases opentracing (legacy)
ALIAS_COMMAND("datadog_tracing", "opentracing", anywhere | NGX_CONF_TAKE1),
ALIAS_COMMAND("datadog_operation_name", "opentracing_operation_name",
Expand Down
23 changes: 23 additions & 0 deletions src/tracing_library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,29 @@ dd::Expected<dd::Tracer> TracingLibrary::make_tracer(
config.agent.url = nginx_conf.agent_url;
}

if (nginx_conf.resource_renaming_enabled != NGX_CONF_UNSET) {
config.resource_renaming_enabled = {nginx_conf.resource_renaming_enabled ==
1};
}
#ifdef WITH_WAF
else {
// we don't have it, in config
// if we also don't have in the environment it defaults to whether appsec
// is enabled
const char *env_renaming =
std::getenv("DD_TRACE_RESOURCE_RENAMING_ENABLED");
if (!env_renaming || !env_renaming[0]) {
config.resource_renaming_enabled = {nginx_conf.appsec_enabled == 1};
}
}
#endif

if (nginx_conf.resource_renaming_always_simplified_endpoint !=
NGX_CONF_UNSET) {
config.resource_renaming_always_simplified_endpoint = {
nginx_conf.resource_renaming_always_simplified_endpoint == 1};
}

// Set sampling rules based on any `datadog_sample_rate` directives.
std::vector<sampling_rule_t> rules = nginx_conf.sampling_rules;
// Sort by descending depth, so that rules in a `location` block come before
Expand Down
38 changes: 26 additions & 12 deletions test/cases/configuration/test_apm_tracing_enabled.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,17 +277,26 @@ def test_distributed_tracing_waf(self):
expected_headers = {
"x-datadog-sampling-priority": "2",
"x-datadog-origin": "rum",
"x-datadog-tags": "_dd.p.dm=-5,_dd.p.ts=02",
"x-datadog-tags": ["_dd.p.dm=-5", "_dd.p.ts=02"],
}

for header_name, expected_value in expected_headers.items():
self.assertIn(header_name, forwarded_headers,
f"Missing header: {header_name}")
self.assertEqual(
forwarded_headers[header_name],
expected_value,
f"Header {header_name} mismatch: expected {expected_value}, got {forwarded_headers[header_name]}",
)
gotten_value = forwarded_headers[header_name]
if isinstance(expected_value, list):
for ev in expected_value:
self.assertIn(
ev,
gotten_value,
f"Header {header_name} missing expected value: {ev}",
)
else:
self.assertEqual(
gotten_value,
expected_value,
f"Header {header_name} mismatch: expected {expected_value}, got {forwarded_headers[header_name]}",
)

# Check traceparent format (trace ID should match, span ID should be different)
self.assertIn("traceparent", forwarded_headers,
Expand Down Expand Up @@ -327,12 +336,17 @@ def test_distributed_tracing_waf(self):
tracestate = forwarded_headers["tracestate"]
# The tracestate should contain the new span ID (same as in traceparent)
expected_span_id = traceparent_parts[2]
expected_tracestate = f"dd=s:2;p:{expected_span_id};o:rum;t.dm:-5;t.ts:02"
self.assertEqual(
tracestate,
expected_tracestate,
f"tracestate mismatch: expected {expected_tracestate}, got {tracestate}",
)
expected_tracestate = [
"dd=s:2", f"p:{expected_span_id}", "o:rum", "t.dm:-5",
"t.ts:02"
]
split_tracestate = tracestate.split(";")
for expected_part in expected_tracestate:
self.assertIn(
expected_part,
split_tracestate,
f"tracestate missing expected part: {expected_part}. Got {tracestate}",
)

span_count = 0

Expand Down
1 change: 1 addition & 0 deletions test/cases/endpoint_renaming/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Endpoint renaming integration tests
38 changes: 38 additions & 0 deletions test/cases/endpoint_renaming/conf/always.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Test configuration for endpoint renaming always mode
# This configuration tests that endpoint renaming works even when http.route is present

load_module /datadog-tests/ngx_http_datadog_module.so;

events {
worker_connections 1024;
}

http {
datadog_agent_url http://agent:8126;
datadog_service_name test-service;

datadog_resource_renaming_enabled on;
datadog_resource_renaming_always_simplified_endpoint on;

server {
listen 80;
server_name localhost;

location / {
return 200 "$datadog_config_json";
}

location /api/users {
return 200 "User endpoint";
}

location /api/products {
return 200 "Product endpoint";
}

location /api/orders {
datadog_tag "http.route" "/api/orders/:id";
return 200 "Order endpoint";
}
}
}
45 changes: 45 additions & 0 deletions test/cases/endpoint_renaming/conf/appsec_enabled.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Test configuration for endpoint renaming with appsec enabled
# This configuration tests that endpoint renaming defaults to enabled (fallback mode)
# when appsec is enabled, without explicit resource_renaming_enabled directive

thread_pool waf_thread_pool threads=2 max_queue=5;

load_module /datadog-tests/ngx_http_datadog_module.so;

events {
worker_connections 1024;
}

http {
datadog_agent_url http://agent:8126;
datadog_service_name test-service;

# Enable appsec - this should enable endpoint renaming by default
datadog_appsec_enabled on;
datadog_waf_thread_pool_name waf_thread_pool;

# No explicit datadog_resource_renaming_enabled directive
# Should default to on (fallback mode) because appsec is enabled

server {
listen 80;
server_name localhost;

location / {
return 200 "$datadog_config_json";
}

location /api/users {
return 200 "User endpoint";
}

location /api/products {
return 200 "Product endpoint";
}

location /api/orders {
datadog_tag "http.route" "/api/orders/:id";
return 200 "Order endpoint";
}
}
}
33 changes: 33 additions & 0 deletions test/cases/endpoint_renaming/conf/disabled.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Test configuration for endpoint renaming disabled (default)
# This configuration tests that endpoint renaming is disabled by default

load_module /datadog-tests/ngx_http_datadog_module.so;

events {
worker_connections 1024;
}

http {
datadog_agent_url http://agent:8126;
datadog_service_name test-service;

# Endpoint renaming should be disabled by default
# No datadog_resource_renaming_enabled directive

server {
listen 80;
server_name localhost;

location / {
return 200 "$datadog_config_json";
}

location /api/users {
return 200 "User endpoint";
}

location /api/products {
return 200 "Product endpoint";
}
}
}
38 changes: 38 additions & 0 deletions test/cases/endpoint_renaming/conf/fallback.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Test configuration for endpoint renaming enabled
# This configuration tests that endpoint renaming works when enabled

load_module /datadog-tests/ngx_http_datadog_module.so;

events {
worker_connections 1024;
}

http {
datadog_agent_url http://agent:8126;
datadog_service_name test-service;

# Enable endpoint renaming (fallback mode)
datadog_resource_renaming_enabled on;

server {
listen 80;
server_name localhost;

location / {
return 200 "$datadog_config_json";
}

location /api/users {
return 200 "User endpoint";
}

location /api/products {
return 200 "Product endpoint";
}

location /api/orders {
datadog_tag "http.route" "/api/orders/:id";
return 200 "Order endpoint";
}
}
}
Loading
Loading