From 9afd9b64ae4b0afdb0c958276e76256704d9a9b7 Mon Sep 17 00:00:00 2001 From: Damien MEHALA Date: Fri, 24 Oct 2025 17:26:45 +0200 Subject: [PATCH 1/2] fix(ingress-nginx): filter out healthcheck traces --- src/tracing_library.cpp | 44 ++++++++++++------- test/cases/ingress-nginx/conf/main.conf | 4 ++ test/cases/ingress-nginx/test_rules.py | 24 ++++++++++ .../test_otel_drop_in_support.py | 7 +++ 4 files changed, 63 insertions(+), 16 deletions(-) diff --git a/src/tracing_library.cpp b/src/tracing_library.cpp index 71b0a866..57a7fc64 100644 --- a/src/tracing_library.cpp +++ b/src/tracing_library.cpp @@ -31,23 +31,24 @@ extern "C" { namespace datadog { namespace nginx { -inline constexpr std::string_view integration_name_from_flavor( - flavor nginx_flavor) { +inline constexpr std::string_view +integration_name_from_flavor(flavor nginx_flavor) { switch (nginx_flavor) { - case flavor::vanilla: - return "nginx"; - case flavor::openresty: - return "nginx:openresty"; - case flavor::ingress_nginx: - return "nginx:ingress-nginx"; + case flavor::vanilla: + return "nginx"; + case flavor::openresty: + return "nginx:openresty"; + case flavor::ingress_nginx: + return "nginx:ingress-nginx"; } static_assert(true, "unknown NGINX flavor"); std::abort(); } -dd::Expected TracingLibrary::make_tracer( - const datadog_main_conf_t &nginx_conf, std::shared_ptr logger) { +dd::Expected +TracingLibrary::make_tracer(const datadog_main_conf_t &nginx_conf, + std::shared_ptr logger) { dd::TracerConfig config; config.logger = std::move(logger); config.agent.event_scheduler = std::make_shared(); @@ -97,8 +98,8 @@ dd::Expected TracingLibrary::make_tracer( (nginx_conf.appsec_enabled != NGX_CONF_UNSET); security::register_with_remote_cfg( config.agent, - !has_custom_ruleset, // no custom ruleset => ruleset via rem cfg - !appsec_enabling_explicit); // no explicit => control via rem cfg + !has_custom_ruleset, // no custom ruleset => ruleset via rem cfg + !appsec_enabling_explicit); // no explicit => control via rem cfg } #endif @@ -119,6 +120,17 @@ dd::Expected TracingLibrary::make_tracer( .resource = "GET /is-dynamic-lb-initialized", .tags = {}}, .mechanism = datadog::tracing::SamplingMechanism::RULE}); + + // TODO(@dmehala): Disable tracing if `stub_status on;`. + final_config->trace_sampler.rules.emplace_back( + datadog::tracing::TraceSamplerRule{ + .rate = datadog::tracing::Rate::zero(), + .matcher = + datadog::tracing::SpanMatcher{.service = "*", + .name = "*", + .resource = "GET /nginx_status", + .tags = {}}, + .mechanism = datadog::tracing::SamplingMechanism::RULE}); } if (!final_config) { @@ -145,7 +157,7 @@ namespace { class SpanContextJSONWriter : public dd::DictWriter { rapidjson::Document output_object_; - public: +public: SpanContextJSONWriter() : output_object_() { output_object_.SetObject(); } void set(std::string_view key, std::string_view value) override { @@ -193,7 +205,7 @@ std::string span_property(std::string_view key, const dd::Span &span) { return not_found; } -} // namespace +} // namespace NginxVariableFamily TracingLibrary::span_variables() { return {.prefix = "datadog_", .resolve = span_property}; @@ -246,5 +258,5 @@ bool TracingLibrary::trace_locations_by_default() { return false; } bool TracingLibrary::bagage_span_tags_by_default() { return true; } -} // namespace nginx -} // namespace datadog +} // namespace nginx +} // namespace datadog diff --git a/test/cases/ingress-nginx/conf/main.conf b/test/cases/ingress-nginx/conf/main.conf index c61ac85c..61287194 100644 --- a/test/cases/ingress-nginx/conf/main.conf +++ b/test/cases/ingress-nginx/conf/main.conf @@ -21,5 +21,9 @@ http { location /is-dynamic-lb-initialized { proxy_pass http://http:8080; } + + location /nginx_status { + proxy_pass http://http:8080; + } } } diff --git a/test/cases/ingress-nginx/test_rules.py b/test/cases/ingress-nginx/test_rules.py index 0e1452ee..94762ab1 100644 --- a/test/cases/ingress-nginx/test_rules.py +++ b/test/cases/ingress-nginx/test_rules.py @@ -35,3 +35,27 @@ def test_healthcheck(self): response = json.loads(body) self.assertEqual(response["headers"]["x-datadog-sampling-priority"], "1") + + def test_healthcheck_stubstatus(self): + # Healthcheck request MUST not be generated traces. + conf_path = Path(__file__).parent / "conf" / "main.conf" + conf_text = conf_path.read_text() + + status, log_lines = self.orch.nginx_replace_config( + conf_text, conf_path.name) + self.assertEqual(status, 0, log_lines) + + status, _, body = self.orch.send_nginx_http_request( + "/nginx_status") + self.assertEqual(status, 200) + + response = json.loads(body) + self.assertEqual(response["headers"]["x-datadog-sampling-priority"], + "-1") + + status, _, body = self.orch.send_nginx_http_request("/") + self.assertEqual(status, 200) + + response = json.loads(body) + self.assertEqual(response["headers"]["x-datadog-sampling-priority"], + "1") diff --git a/test/cases/opentelemetry/test_otel_drop_in_support.py b/test/cases/opentelemetry/test_otel_drop_in_support.py index 92f07663..db3f399a 100644 --- a/test/cases/opentelemetry/test_otel_drop_in_support.py +++ b/test/cases/opentelemetry/test_otel_drop_in_support.py @@ -137,6 +137,13 @@ def test_directives(self): "service": "*", "tags": {}, }) + rules.append({ + "name": "*", + "resource": "GET /nginx_status", + "sample_rate": 0.0, + "service": "*", + "tags": {}, + }) pattern = { "service": "foo", From 724f09b38ed0c78299902e5995be40f118547cbf Mon Sep 17 00:00:00 2001 From: Damien Mehala Date: Sun, 26 Oct 2025 17:32:31 -0400 Subject: [PATCH 2/2] fix: format --- src/tracing_library.cpp | 33 +++++++++++++------------- test/cases/ingress-nginx/test_rules.py | 3 +-- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/tracing_library.cpp b/src/tracing_library.cpp index 57a7fc64..bce4ca3b 100644 --- a/src/tracing_library.cpp +++ b/src/tracing_library.cpp @@ -31,24 +31,23 @@ extern "C" { namespace datadog { namespace nginx { -inline constexpr std::string_view -integration_name_from_flavor(flavor nginx_flavor) { +inline constexpr std::string_view integration_name_from_flavor( + flavor nginx_flavor) { switch (nginx_flavor) { - case flavor::vanilla: - return "nginx"; - case flavor::openresty: - return "nginx:openresty"; - case flavor::ingress_nginx: - return "nginx:ingress-nginx"; + case flavor::vanilla: + return "nginx"; + case flavor::openresty: + return "nginx:openresty"; + case flavor::ingress_nginx: + return "nginx:ingress-nginx"; } static_assert(true, "unknown NGINX flavor"); std::abort(); } -dd::Expected -TracingLibrary::make_tracer(const datadog_main_conf_t &nginx_conf, - std::shared_ptr logger) { +dd::Expected TracingLibrary::make_tracer( + const datadog_main_conf_t &nginx_conf, std::shared_ptr logger) { dd::TracerConfig config; config.logger = std::move(logger); config.agent.event_scheduler = std::make_shared(); @@ -98,8 +97,8 @@ TracingLibrary::make_tracer(const datadog_main_conf_t &nginx_conf, (nginx_conf.appsec_enabled != NGX_CONF_UNSET); security::register_with_remote_cfg( config.agent, - !has_custom_ruleset, // no custom ruleset => ruleset via rem cfg - !appsec_enabling_explicit); // no explicit => control via rem cfg + !has_custom_ruleset, // no custom ruleset => ruleset via rem cfg + !appsec_enabling_explicit); // no explicit => control via rem cfg } #endif @@ -157,7 +156,7 @@ namespace { class SpanContextJSONWriter : public dd::DictWriter { rapidjson::Document output_object_; -public: + public: SpanContextJSONWriter() : output_object_() { output_object_.SetObject(); } void set(std::string_view key, std::string_view value) override { @@ -205,7 +204,7 @@ std::string span_property(std::string_view key, const dd::Span &span) { return not_found; } -} // namespace +} // namespace NginxVariableFamily TracingLibrary::span_variables() { return {.prefix = "datadog_", .resolve = span_property}; @@ -258,5 +257,5 @@ bool TracingLibrary::trace_locations_by_default() { return false; } bool TracingLibrary::bagage_span_tags_by_default() { return true; } -} // namespace nginx -} // namespace datadog +} // namespace nginx +} // namespace datadog diff --git a/test/cases/ingress-nginx/test_rules.py b/test/cases/ingress-nginx/test_rules.py index 94762ab1..81236d0c 100644 --- a/test/cases/ingress-nginx/test_rules.py +++ b/test/cases/ingress-nginx/test_rules.py @@ -45,8 +45,7 @@ def test_healthcheck_stubstatus(self): conf_text, conf_path.name) self.assertEqual(status, 0, log_lines) - status, _, body = self.orch.send_nginx_http_request( - "/nginx_status") + status, _, body = self.orch.send_nginx_http_request("/nginx_status") self.assertEqual(status, 200) response = json.loads(body)