From 066310cca923721c43c16cf4d06d9b3a8dc59c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chojnacki?= Date: Mon, 20 Apr 2026 20:12:00 +0200 Subject: [PATCH 1/3] Respect child-scope override for tracing directives tracing_enabled and trust_inbound_span were plain `bool` with a default of `true`, and merge_dir_conf OR'd parent and child together. That silently dropped `DatadogTracing Off` inside a : the enclosing scope's implicit `true` always won the OR, so tracing stayed on for the child. Switch both Directory fields to std::optional so the directive handler's explicit write (true/false) is distinguishable from the default (nullopt). Merge now falls back to the parent only when the child never set the directive; read sites apply the default via .value_or(true). --- mod_datadog/src/common_conf.cpp | 13 +++++++++---- mod_datadog/src/common_conf.h | 8 ++++++-- mod_datadog/src/tracing/hooks.cpp | 8 +++++--- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/mod_datadog/src/common_conf.cpp b/mod_datadog/src/common_conf.cpp index d2a56a53..7a7f326b 100644 --- a/mod_datadog/src/common_conf.cpp +++ b/mod_datadog/src/common_conf.cpp @@ -15,10 +15,15 @@ void* merge_dir_conf(apr_pool_t* pool, void* base, void* add) { void* final_ptr = init_dir_conf(pool, nullptr); auto conf = static_cast(final_ptr); - conf->tracing_enabled = child->tracing_enabled || parent->tracing_enabled; - - conf->trust_inbound_span = - child->trust_inbound_span || parent->trust_inbound_span; + // Tri-state merge: an explicit directive in the child scope wins over + // whatever the parent had (including the default). Only fall back to the + // parent when the child never set the directive. + conf->tracing_enabled = + child->tracing_enabled ? child->tracing_enabled : parent->tracing_enabled; + + conf->trust_inbound_span = child->trust_inbound_span + ? child->trust_inbound_span + : parent->trust_inbound_span; conf->tags = child->tags; auto tmp = parent->tags; diff --git a/mod_datadog/src/common_conf.h b/mod_datadog/src/common_conf.h index 23bd4638..a8e5368a 100644 --- a/mod_datadog/src/common_conf.h +++ b/mod_datadog/src/common_conf.h @@ -2,6 +2,7 @@ #include +#include #include #include @@ -18,8 +19,11 @@ struct Module final { }; struct Directory final { - bool tracing_enabled = true; - bool trust_inbound_span = true; + // `std::nullopt` means "inherit from the enclosing scope"; any concrete + // value (true/false) was set explicitly via a directive and wins over the + // parent during merge. The effective default at read sites is `true`. + std::optional tracing_enabled; + std::optional trust_inbound_span; std::unordered_map tags; // RUM diff --git a/mod_datadog/src/tracing/hooks.cpp b/mod_datadog/src/tracing/hooks.cpp index f84d185b..07db3a55 100644 --- a/mod_datadog/src/tracing/hooks.cpp +++ b/mod_datadog/src/tracing/hooks.cpp @@ -103,7 +103,8 @@ int on_fixups(request_rec* r, Tracer& g_tracer, module* datadog_module) { auto* dir_conf = static_cast( ap_get_module_config(main_r->per_dir_config, datadog_module)); - if (dir_conf == nullptr || !dir_conf->tracing_enabled) return DECLINED; + if (dir_conf == nullptr || !dir_conf->tracing_enabled.value_or(true)) + return DECLINED; void* data = ap_get_module_config(main_r->request_config, datadog_module); if (!data) return DECLINED; @@ -116,7 +117,8 @@ int on_fixups(request_rec* r, Tracer& g_tracer, module* datadog_module) { // Trace request auto* dir_conf = static_cast( ap_get_module_config(r->per_dir_config, datadog_module)); - if (dir_conf == nullptr || !dir_conf->tracing_enabled) return DECLINED; + if (dir_conf == nullptr || !dir_conf->tracing_enabled.value_or(true)) + return DECLINED; void* data = ap_get_module_config(r->request_config, datadog_module); if (data) @@ -127,7 +129,7 @@ int on_fixups(request_rec* r, Tracer& g_tracer, module* datadog_module) { // In case we fail to use the inbound span, then, start a new trace // ¯\_(ツ)_/¯ There is nothing we can do about it. - if (dir_conf->trust_inbound_span) { + if (dir_conf->trust_inbound_span.value_or(true)) { auto extracted_span = g_tracer.extract_span(utils::HeaderReader(r->headers_in), options); if (auto error = extracted_span.if_error()) { From f8e8f974e589773011e20e3fa2bf323332a0e7bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chojnacki?= Date: Tue, 21 Apr 2026 20:56:16 +0200 Subject: [PATCH 2/3] Fully qualify datadog::conf::Directory cast in subrequest path Matches the already-qualified cast on the non-subrequest branch a few lines below. Namespace lookup currently happens to resolve, but would break if another `conf` enters visibility in this TU. --- mod_datadog/src/tracing/hooks.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod_datadog/src/tracing/hooks.cpp b/mod_datadog/src/tracing/hooks.cpp index 07db3a55..dd581ba2 100644 --- a/mod_datadog/src/tracing/hooks.cpp +++ b/mod_datadog/src/tracing/hooks.cpp @@ -101,7 +101,7 @@ int on_fixups(request_rec* r, Tracer& g_tracer, module* datadog_module) { // subrequests/internal redirection? request_rec* main_r = r->prev ? r->prev : r->main; - auto* dir_conf = static_cast( + auto* dir_conf = static_cast( ap_get_module_config(main_r->per_dir_config, datadog_module)); if (dir_conf == nullptr || !dir_conf->tracing_enabled.value_or(true)) return DECLINED; From 8694cdf4a784facbf123f55e4df7bf2372cfdb87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chojnacki?= Date: Wed, 22 Apr 2026 21:40:45 +0200 Subject: [PATCH 3/3] Add braces to multi-line if/return in tracing hooks --- mod_datadog/src/tracing/hooks.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mod_datadog/src/tracing/hooks.cpp b/mod_datadog/src/tracing/hooks.cpp index dd581ba2..b6df5f07 100644 --- a/mod_datadog/src/tracing/hooks.cpp +++ b/mod_datadog/src/tracing/hooks.cpp @@ -103,8 +103,9 @@ int on_fixups(request_rec* r, Tracer& g_tracer, module* datadog_module) { auto* dir_conf = static_cast( ap_get_module_config(main_r->per_dir_config, datadog_module)); - if (dir_conf == nullptr || !dir_conf->tracing_enabled.value_or(true)) + if (dir_conf == nullptr || !dir_conf->tracing_enabled.value_or(true)) { return DECLINED; + } void* data = ap_get_module_config(main_r->request_config, datadog_module); if (!data) return DECLINED; @@ -117,8 +118,9 @@ int on_fixups(request_rec* r, Tracer& g_tracer, module* datadog_module) { // Trace request auto* dir_conf = static_cast( ap_get_module_config(r->per_dir_config, datadog_module)); - if (dir_conf == nullptr || !dir_conf->tracing_enabled.value_or(true)) + if (dir_conf == nullptr || !dir_conf->tracing_enabled.value_or(true)) { return DECLINED; + } void* data = ap_get_module_config(r->request_config, datadog_module); if (data)