Skip to content

Commit 96fa034

Browse files
authored
Add configuration for HTTP error ranges (#4991)
1 parent 65125a4 commit 96fa034

File tree

43 files changed

+504
-118
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+504
-118
lines changed

.github/forced-tests-list.cfg

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@
1010

1111
# Example :
1212
# tests/parametric/test_config_consistency.py::Test_Stable_Config_Default::test_config_precedence
13+
14+
tests/test_config_consistency.py::Test_Config_HttpClientErrorStatuses_FeatureFlagCustom
15+
tests/test_config_consistency.py::Test_Config_HttpServerErrorStatuses_FeatureFlagCustom

.github/workflows/system-tests.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ jobs:
108108
TELEMETRY_APP_STARTED_PRODUCTS_DISABLED,
109109
TELEMETRY_DEPENDENCY_LOADED_TEST_FOR_DEPENDENCY_COLLECTION_DISABLED,
110110
TELEMETRY_LOG_GENERATION_DISABLED,
111-
TELEMETRY_METRIC_GENERATION_DISABLED
111+
TELEMETRY_METRIC_GENERATION_DISABLED,
112+
TRACING_CONFIG_NONDEFAULT
112113
needs:
113114
- build
114115
uses: DataDog/system-tests/.github/workflows/system-tests.yml@38d5f42dd9e6e0629d01d475a245eca7a13aeac7 # Automated: This reference is automatically updated.

lib/datadog/core/configuration/supported_configurations.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,10 @@ module Configuration
195195
"DD_TRACE_HTTPRB_SERVICE_NAME" => {version: ["A"]},
196196
"DD_TRACE_HTTP_ANALYTICS_ENABLED" => {version: ["A"]},
197197
"DD_TRACE_HTTP_ANALYTICS_SAMPLE_RATE" => {version: ["A"]},
198+
"DD_TRACE_HTTP_CLIENT_ERROR_STATUSES" => {version: ["A"]},
198199
"DD_TRACE_HTTP_ENABLED" => {version: ["A"]},
199200
"DD_TRACE_HTTP_ERROR_STATUS_CODES" => {version: ["A"]},
201+
"DD_TRACE_HTTP_SERVER_ERROR_STATUSES" => {version: ["A"]},
200202
"DD_TRACE_KAFKA_ANALYTICS_ENABLED" => {version: ["A"]},
201203
"DD_TRACE_KAFKA_ANALYTICS_SAMPLE_RATE" => {version: ["A"]},
202204
"DD_TRACE_KAFKA_ENABLED" => {version: ["A"]},

lib/datadog/tracing/configuration/ext.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ module ClientIp
104104
ENV_ENABLED = 'DD_TRACE_CLIENT_IP_ENABLED'
105105
ENV_HEADER_NAME = 'DD_TRACE_CLIENT_IP_HEADER'
106106
end
107+
108+
# @public_api
109+
module HTTPErrorStatuses
110+
ENV_SERVER_ERROR_STATUSES = 'DD_TRACE_HTTP_SERVER_ERROR_STATUSES'
111+
ENV_CLIENT_ERROR_STATUSES = 'DD_TRACE_HTTP_CLIENT_ERROR_STATUSES'
112+
end
107113
end
108114
end
109115
end

lib/datadog/tracing/configuration/settings.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
require_relative '../../tracing/configuration/ext'
44
require_relative '../../core/environment/variable_helpers'
5+
require_relative '../contrib/status_range_matcher'
6+
require_relative '../contrib/status_range_env_parser'
57
require_relative 'http'
68

79
module Datadog
@@ -490,6 +492,46 @@ def self.extended(base)
490492
o.env Tracing::Configuration::Ext::Distributed::ENV_X_DATADOG_TAGS_MAX_LENGTH
491493
o.default 512
492494
end
495+
496+
# HTTP error statuses configuration
497+
# @public_api
498+
settings :http_error_statuses do
499+
# Defines the range of status codes to be considered errors on http.server span kinds.
500+
# Once set, only the values within the specified range are considered errors.
501+
#
502+
# Format of env var: comma-separated list of values like 500,501,502 or ranges like 500-599 (e.g. `500,502,504-510`)
503+
#
504+
# @default `DD_TRACE_HTTP_SERVER_ERROR_STATUSES` environment variable, otherwise `500..599`.
505+
# @return [Tracing::Contrib::StatusRangeMatcher]
506+
option :server do |o|
507+
o.env Tracing::Configuration::Ext::HTTPErrorStatuses::ENV_SERVER_ERROR_STATUSES
508+
o.default 500..599
509+
o.setter do |v|
510+
Tracing::Contrib::StatusRangeMatcher.new(v) if v
511+
end
512+
o.env_parser do |values|
513+
Tracing::Contrib::StatusRangeEnvParser.call(values)
514+
end
515+
end
516+
517+
# Defines the range of status codes to be considered errors on http.client span kinds.
518+
# Once set, only the values within the specified range are considered errors.
519+
#
520+
# Format of env var: comma-separated list of values like 400,401,402 or ranges like 400-499 (e.g. `400,402,404-410`)
521+
#
522+
# @default `DD_TRACE_HTTP_CLIENT_ERROR_STATUSES` environment variable, otherwise `400..499`.
523+
# @return [Tracing::Contrib::StatusRangeMatcher]
524+
option :client do |o|
525+
o.env Tracing::Configuration::Ext::HTTPErrorStatuses::ENV_CLIENT_ERROR_STATUSES
526+
o.default 400..499
527+
o.setter do |v|
528+
Tracing::Contrib::StatusRangeMatcher.new(v) if v
529+
end
530+
o.env_parser do |values|
531+
Tracing::Contrib::StatusRangeEnvParser.call(values)
532+
end
533+
end
534+
end
493535
end
494536
end
495537
end

lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ def finish_processing(payload)
7777

7878
exception = payload[:exception_object]
7979
if exception.nil?
80-
# [christian] in some cases :status is not defined,
81-
# rather than firing an error, simply acknowledge we don't know it.
82-
status = payload.fetch(:status, '?').to_s
83-
span.status = 1 if status.start_with?('5')
80+
status = payload[:status]
81+
if status && Datadog.configuration.tracing.http_error_statuses.server.include?(status)
82+
span.status = Tracing::Metadata::Ext::Errors::STATUS
83+
end
8484
elsif Utils.exception_is_error?(exception)
8585
span.set_error(exception)
8686
end

lib/datadog/tracing/contrib/action_pack/utils.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ def self.exception_is_error?(exception)
1313
# Gets the equivalent status code for the exception (not all are 5XX)
1414
# You can add custom errors via `config.action_dispatch.rescue_responses`
1515
status = ::ActionDispatch::ExceptionWrapper.status_code_for_exception(exception.class.name)
16-
# Only 5XX exceptions are actually errors (e.g. don't flag 404s)
17-
status.to_s.start_with?('5')
16+
Datadog.configuration.tracing.http_error_statuses.server.include?(status)
1817
else
1918
true
2019
end

lib/datadog/tracing/contrib/aws/instrumentation.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ def annotate!(span, context)
3636
span.name = Ext::SPAN_COMMAND
3737
span.resource = context.safely(:resource)
3838

39-
# Set error on the span if the Response Status Code is in error range
40-
if Tracing::Metadata::Ext::HTTP::ERROR_RANGE.cover?(context.safely(:status_code))
39+
# DEV-3.0: This was previously checking against a 500..599 range.
40+
# To not introduce breaking change, this was changed to use `http_error_statuses.server`,
41+
# but `aws` is a client library, this check should use `http_error_statuses.client` instead.
42+
if Datadog.configuration.tracing.http_error_statuses.server.include?(context.safely(:status_code))
4143
# At this point we do not have any additional diagnostics
4244
# besides the HTTP status code which is recorded in the span tags
4345
# later in this method.

lib/datadog/tracing/contrib/ethon/easy_patch.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ def complete
5757
set_span_error_message("Request has failed: #{message}")
5858
else
5959
@datadog_span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_STATUS_CODE, response_code)
60-
if Tracing::Metadata::Ext::HTTP::ERROR_RANGE.cover?(response_code)
60+
# DEV-3.0: This was previously checking against a 500..599 range.
61+
# To not introduce breaking change, this was changed to use `http_error_statuses.server`,
62+
# but `ethon` is a client library, this check should use `http_error_statuses.client` instead.
63+
if Datadog.configuration.tracing.http_error_statuses.server.include?(response_code)
6164
set_span_error_message("Request has failed with HTTP error: #{response_code}")
6265
end
6366
end

lib/datadog/tracing/contrib/excon/configuration/settings.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,17 @@ class Settings < Contrib::Configuration::Settings
4141

4242
option :error_status_codes do |o|
4343
o.env Ext::ENV_ERROR_STATUS_CODES
44-
o.default 400...600
45-
o.setter do |v|
46-
Tracing::Contrib::StatusRangeMatcher.new(v) if v
44+
o.setter do |value|
45+
if value.nil?
46+
# Fallback to global config, which is defaulted to client (400..499) + server (500..599)
47+
# DEV-3.0: `excon` is a client library, this should fall back to `http_error_statuses.client` only.
48+
# We cannot change it without causing a breaking change.
49+
client_global_error_statuses = Datadog.configuration.tracing.http_error_statuses.client
50+
server_global_error_statuses = Datadog.configuration.tracing.http_error_statuses.server
51+
client_global_error_statuses + server_global_error_statuses
52+
else
53+
Tracing::Contrib::StatusRangeMatcher.new(value)
54+
end
4755
end
4856
o.env_parser do |v|
4957
Tracing::Contrib::StatusRangeEnvParser.call(v) if v

0 commit comments

Comments
 (0)