datadog 2.46.0 → 2.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -2
- data/ext/datadog_profiling_native_extension/collectors_stack.c +31 -14
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +1 -1
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +3 -0
- data/ext/libdatadog_extconf_helpers.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +29 -2
- data/lib/datadog/appsec/contrib/rails/patches/render_to_body_patch.rb +8 -7
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +14 -2
- data/lib/datadog/appsec/contrib/sinatra/patches/json_patch.rb +8 -7
- data/lib/datadog/appsec/security_engine/engine.rb +2 -1
- data/lib/datadog/core/configuration/components.rb +11 -10
- data/lib/datadog/core/configuration/components_state.rb +8 -1
- data/lib/datadog/core/configuration/supported_configurations.rb +2 -0
- data/lib/datadog/core/remote/client.rb +44 -3
- data/lib/datadog/core/remote/dispatcher.rb +34 -3
- data/lib/datadog/core/workers/runtime_metrics.rb +1 -1
- data/lib/datadog/di/capture_expression_evaluator.rb +1 -1
- data/lib/datadog/di/component.rb +70 -0
- data/lib/datadog/di/remote.rb +46 -2
- data/lib/datadog/di/serializer.rb +27 -11
- data/lib/datadog/open_feature/configuration.rb +6 -0
- data/lib/datadog/open_feature/hooks/evaluation_telemetry_opt_out_hook.rb +25 -0
- data/lib/datadog/open_feature/provider.rb +22 -3
- data/lib/datadog/profiling/collectors/info.rb +37 -6
- data/lib/datadog/profiling/component.rb +22 -20
- data/lib/datadog/profiling/exporter.rb +3 -5
- data/lib/datadog/tracing/component.rb +7 -2
- data/lib/datadog/tracing/configuration/ext.rb +2 -0
- data/lib/datadog/tracing/configuration/settings.rb +11 -0
- data/lib/datadog/tracing/context_provider.rb +8 -0
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +10 -5
- data/lib/datadog/tracing/contrib/excon/middleware.rb +10 -3
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +10 -4
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +16 -1
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +8 -2
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +10 -4
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +10 -3
- data/lib/datadog/tracing/contrib/utils/quantization/http.rb +102 -0
- data/lib/datadog/tracing/remote.rb +50 -19
- data/lib/datadog/version.rb +1 -1
- metadata +8 -8
- data/lib/datadog/appsec/utils/hash_coercion.rb +0 -23
|
@@ -7,6 +7,7 @@ require_relative "../http"
|
|
|
7
7
|
require_relative "../analytics"
|
|
8
8
|
require_relative "ext"
|
|
9
9
|
require_relative "../http_annotation_helper"
|
|
10
|
+
require_relative "../utils/quantization/http"
|
|
10
11
|
require_relative "../../../core/telemetry/logger"
|
|
11
12
|
|
|
12
13
|
module Datadog
|
|
@@ -45,7 +46,8 @@ module Datadog
|
|
|
45
46
|
|
|
46
47
|
# rubocop:disable Metrics/AbcSize
|
|
47
48
|
def annotate!(span, env, options)
|
|
48
|
-
|
|
49
|
+
path = env[:url].path
|
|
50
|
+
span.resource = resource_name(env, path)
|
|
49
51
|
span.service = service_name(env[:url].host, options)
|
|
50
52
|
span.set_tag(Tracing::Metadata::Ext::TAG_SVC_SRC, Ext::TAG_COMPONENT)
|
|
51
53
|
span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
|
|
@@ -69,7 +71,7 @@ module Datadog
|
|
|
69
71
|
Contrib::Analytics.set_sample_rate(span, options[:analytics_sample_rate])
|
|
70
72
|
end
|
|
71
73
|
|
|
72
|
-
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_URL,
|
|
74
|
+
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_URL, path)
|
|
73
75
|
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD, env[:method].to_s.upcase)
|
|
74
76
|
span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, env[:url].host)
|
|
75
77
|
span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_PORT, env[:url].port)
|
|
@@ -103,8 +105,12 @@ module Datadog
|
|
|
103
105
|
Contrib::HTTP.inject(trace, env[:request_headers])
|
|
104
106
|
end
|
|
105
107
|
|
|
106
|
-
def resource_name(env)
|
|
107
|
-
|
|
108
|
+
def resource_name(env, path)
|
|
109
|
+
Contrib::Utils::Quantization::HTTP.client_resource(
|
|
110
|
+
env[:method].to_s.upcase,
|
|
111
|
+
path,
|
|
112
|
+
enabled: Datadog.configuration.tracing.http_client_resource_name_quantize
|
|
113
|
+
)
|
|
108
114
|
end
|
|
109
115
|
|
|
110
116
|
def build_request_options!(env)
|
|
@@ -34,7 +34,12 @@ module Datadog
|
|
|
34
34
|
span.service = service_name(host, request_options, client_config)
|
|
35
35
|
span.set_tag(Tracing::Metadata::Ext::TAG_SVC_SRC, Ext::TAG_COMPONENT)
|
|
36
36
|
span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
|
|
37
|
-
|
|
37
|
+
quantize_resource = Datadog.configuration.tracing.http_client_resource_name_quantize
|
|
38
|
+
span.resource = Contrib::Utils::Quantization::HTTP.client_resource(
|
|
39
|
+
req.method,
|
|
40
|
+
quantize_resource ? request_uri_path(req) : nil,
|
|
41
|
+
enabled: quantize_resource
|
|
42
|
+
)
|
|
38
43
|
|
|
39
44
|
if Tracing::Distributed::PropagationPolicy.enabled?(
|
|
40
45
|
pin_config: client_config,
|
|
@@ -116,6 +121,16 @@ module Datadog
|
|
|
116
121
|
|
|
117
122
|
private
|
|
118
123
|
|
|
124
|
+
def request_uri_path(request)
|
|
125
|
+
uri = request.uri if request.respond_to?(:uri)
|
|
126
|
+
return uri.path if uri
|
|
127
|
+
return request.path.split(/[?#]/, 2).first if request.path.start_with?("/")
|
|
128
|
+
|
|
129
|
+
URI.parse(request.path).path
|
|
130
|
+
rescue URI::InvalidURIError
|
|
131
|
+
nil
|
|
132
|
+
end
|
|
133
|
+
|
|
119
134
|
def host_and_port(request)
|
|
120
135
|
if request.respond_to?(:uri) && request.uri
|
|
121
136
|
[request.uri.host, request.uri.port]
|
|
@@ -4,6 +4,7 @@ require_relative "../../metadata/ext"
|
|
|
4
4
|
require_relative "../http"
|
|
5
5
|
require_relative "../analytics"
|
|
6
6
|
require_relative "../http_annotation_helper"
|
|
7
|
+
require_relative "../utils/quantization/http"
|
|
7
8
|
require_relative "../../../core/telemetry/logger"
|
|
8
9
|
|
|
9
10
|
module Datadog
|
|
@@ -74,10 +75,15 @@ module Datadog
|
|
|
74
75
|
|
|
75
76
|
http_method = req.header.request_method.upcase
|
|
76
77
|
uri = req.header.request_uri
|
|
78
|
+
path = uri.path
|
|
77
79
|
|
|
78
|
-
span.resource =
|
|
80
|
+
span.resource = Contrib::Utils::Quantization::HTTP.client_resource(
|
|
81
|
+
http_method,
|
|
82
|
+
path,
|
|
83
|
+
enabled: Datadog.configuration.tracing.http_client_resource_name_quantize
|
|
84
|
+
)
|
|
79
85
|
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD, http_method)
|
|
80
|
-
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_URL,
|
|
86
|
+
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_URL, path)
|
|
81
87
|
span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, uri.host)
|
|
82
88
|
span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_PORT, uri.port)
|
|
83
89
|
|
|
@@ -4,6 +4,7 @@ require_relative "../../metadata/ext"
|
|
|
4
4
|
require_relative "../http"
|
|
5
5
|
require_relative "../analytics"
|
|
6
6
|
require_relative "../http_annotation_helper"
|
|
7
|
+
require_relative "../utils/quantization/http"
|
|
7
8
|
require_relative "../../../core/telemetry/logger"
|
|
8
9
|
|
|
9
10
|
module Datadog
|
|
@@ -70,17 +71,22 @@ module Datadog
|
|
|
70
71
|
span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
|
|
71
72
|
span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_REQUEST)
|
|
72
73
|
|
|
74
|
+
uri = req.uri
|
|
75
|
+
path = uri&.path
|
|
73
76
|
if req.verb&.is_a?(String) || req.verb.is_a?(Symbol)
|
|
74
77
|
http_method = req.verb.to_s.upcase
|
|
75
|
-
span.resource =
|
|
78
|
+
span.resource = Contrib::Utils::Quantization::HTTP.client_resource(
|
|
79
|
+
http_method,
|
|
80
|
+
path,
|
|
81
|
+
enabled: Datadog.configuration.tracing.http_client_resource_name_quantize
|
|
82
|
+
)
|
|
76
83
|
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD, http_method)
|
|
77
84
|
else
|
|
78
85
|
logger.debug("service #{req_options[:service_name]} span #{Ext::SPAN_REQUEST} missing request verb")
|
|
79
86
|
end
|
|
80
87
|
|
|
81
|
-
if
|
|
82
|
-
|
|
83
|
-
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_URL, uri.path)
|
|
88
|
+
if uri
|
|
89
|
+
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_URL, path)
|
|
84
90
|
span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, uri.host)
|
|
85
91
|
span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_PORT, uri.port)
|
|
86
92
|
|
|
@@ -6,6 +6,7 @@ require_relative "../../metadata/ext"
|
|
|
6
6
|
require_relative "../http"
|
|
7
7
|
require_relative "../analytics"
|
|
8
8
|
require_relative "ext"
|
|
9
|
+
require_relative "../utils/quantization/http"
|
|
9
10
|
|
|
10
11
|
module Datadog
|
|
11
12
|
module Tracing
|
|
@@ -38,7 +39,13 @@ module Datadog
|
|
|
38
39
|
|
|
39
40
|
def datadog_tag_request(uri, span)
|
|
40
41
|
span.set_tag(Tracing::Metadata::Ext::TAG_SVC_SRC, Ext::TAG_COMPONENT)
|
|
41
|
-
|
|
42
|
+
http_method = method.to_s.upcase
|
|
43
|
+
path = uri.path
|
|
44
|
+
span.resource = Contrib::Utils::Quantization::HTTP.client_resource(
|
|
45
|
+
http_method,
|
|
46
|
+
path,
|
|
47
|
+
enabled: Datadog.configuration.tracing.http_client_resource_name_quantize
|
|
48
|
+
)
|
|
42
49
|
|
|
43
50
|
if datadog_configuration[:peer_service]
|
|
44
51
|
span.set_tag(
|
|
@@ -57,8 +64,8 @@ module Datadog
|
|
|
57
64
|
# Set analytics sample rate
|
|
58
65
|
Contrib::Analytics.set_sample_rate(span, analytics_sample_rate) if analytics_enabled?
|
|
59
66
|
|
|
60
|
-
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_URL,
|
|
61
|
-
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD,
|
|
67
|
+
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_URL, path)
|
|
68
|
+
span.set_tag(Tracing::Metadata::Ext::HTTP::TAG_METHOD, http_method)
|
|
62
69
|
span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_HOST, uri.host)
|
|
63
70
|
span.set_tag(Tracing::Metadata::Ext::NET::TAG_TARGET_PORT, uri.port)
|
|
64
71
|
span.set_tags(
|
|
@@ -20,6 +20,96 @@ module Datadog
|
|
|
20
20
|
|
|
21
21
|
module_function
|
|
22
22
|
|
|
23
|
+
def client_resource(method, path, enabled:)
|
|
24
|
+
return method unless enabled && path
|
|
25
|
+
|
|
26
|
+
resource = method.dup
|
|
27
|
+
resource << (+" ").force_encoding(resource.encoding)
|
|
28
|
+
quantized_path = quantize_path(decode_path(path))
|
|
29
|
+
resource << quantized_path.force_encoding(resource.encoding)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def decode_path(path)
|
|
33
|
+
decoded = String.new(encoding: Encoding::BINARY)
|
|
34
|
+
index = 0
|
|
35
|
+
|
|
36
|
+
while index < path.bytesize
|
|
37
|
+
byte = path.getbyte(index)
|
|
38
|
+
break unless byte
|
|
39
|
+
|
|
40
|
+
if byte == 37 && index + 2 < path.bytesize
|
|
41
|
+
high_byte = path.getbyte(index + 1)
|
|
42
|
+
low_byte = path.getbyte(index + 2)
|
|
43
|
+
if high_byte && low_byte
|
|
44
|
+
high = decode_hex_byte(high_byte)
|
|
45
|
+
low = decode_hex_byte(low_byte)
|
|
46
|
+
if high && low
|
|
47
|
+
decoded << high * 16 + low
|
|
48
|
+
index += 3
|
|
49
|
+
next
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
decoded << byte
|
|
55
|
+
index += 1
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
decoded.force_encoding(path.encoding)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def quantize_path(path)
|
|
62
|
+
slash = (+"/").force_encoding(path.encoding)
|
|
63
|
+
normalized = if path.getbyte(0) == 47
|
|
64
|
+
path
|
|
65
|
+
else
|
|
66
|
+
String.new(encoding: path.encoding) << slash << path
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
output = String.new(encoding: path.encoding)
|
|
70
|
+
index = 1
|
|
71
|
+
replacements = 0
|
|
72
|
+
|
|
73
|
+
while index < normalized.bytesize
|
|
74
|
+
segment_end = index
|
|
75
|
+
allowed = 0
|
|
76
|
+
digits = 0
|
|
77
|
+
specials = 0
|
|
78
|
+
|
|
79
|
+
while segment_end < normalized.bytesize && normalized.getbyte(segment_end) != 47
|
|
80
|
+
byte = normalized.getbyte(segment_end)
|
|
81
|
+
break unless byte
|
|
82
|
+
|
|
83
|
+
if byte.between?(48, 57)
|
|
84
|
+
digits += 1
|
|
85
|
+
elsif byte.between?(65, 90) || byte.between?(97, 122) || byte == 45 || byte == 95
|
|
86
|
+
allowed += 1
|
|
87
|
+
else
|
|
88
|
+
specials += 1
|
|
89
|
+
end
|
|
90
|
+
segment_end += 1
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
output << slash
|
|
94
|
+
segment = normalized.byteslice(index, segment_end - index) || String.new(encoding: path.encoding)
|
|
95
|
+
if normalized.getbyte(index) == 118 && allowed == 1 && digits > 0 && specials.zero?
|
|
96
|
+
output << segment
|
|
97
|
+
elsif specials > 0 || digits > 0
|
|
98
|
+
output << (+"*").force_encoding(path.encoding)
|
|
99
|
+
replacements += 1
|
|
100
|
+
else
|
|
101
|
+
output << segment
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
index = segment_end + 1
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
return normalized.dup if replacements.zero?
|
|
108
|
+
|
|
109
|
+
output << slash if normalized.getbyte(normalized.bytesize - 1) == 47
|
|
110
|
+
output
|
|
111
|
+
end
|
|
112
|
+
|
|
23
113
|
def url(url, options = {})
|
|
24
114
|
url!(url, options)
|
|
25
115
|
rescue
|
|
@@ -118,6 +208,18 @@ module Datadog
|
|
|
118
208
|
|
|
119
209
|
private_class_method :collect_query
|
|
120
210
|
|
|
211
|
+
def decode_hex_byte(byte)
|
|
212
|
+
if byte.between?(48, 57)
|
|
213
|
+
byte - 48
|
|
214
|
+
elsif byte.between?(65, 70)
|
|
215
|
+
byte - 55
|
|
216
|
+
elsif byte.between?(97, 102)
|
|
217
|
+
byte - 87
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
private_class_method :decode_hex_byte
|
|
222
|
+
|
|
121
223
|
# Scans over the query string and obfuscates sensitive data by
|
|
122
224
|
# replacing matches with an opaque value
|
|
123
225
|
def obfuscate_query(query, options = {})
|
|
@@ -62,6 +62,8 @@ module Datadog
|
|
|
62
62
|
|
|
63
63
|
# @type var parsed: Array[[::Datadog::Core::Remote::Configuration::Content, ::Hash[::String, untyped]]]
|
|
64
64
|
parsed = []
|
|
65
|
+
# @type var unparseable_contents: Array[Datadog::Core::Remote::Configuration::Content]
|
|
66
|
+
unparseable_contents = []
|
|
65
67
|
repository.contents.each do |content|
|
|
66
68
|
next unless content.path.product == PRODUCT
|
|
67
69
|
|
|
@@ -76,9 +78,8 @@ module Datadog
|
|
|
76
78
|
# A present but non-object lib_config (e.g. {"lib_config": []}) is a
|
|
77
79
|
# schema violation the customer can fix. Acknowledging it as applied
|
|
78
80
|
# would tell the backend the config was successfully applied when it
|
|
79
|
-
# was not
|
|
80
|
-
#
|
|
81
|
-
# payload is reported errored instead. A null or absent lib_config
|
|
81
|
+
# was not. Reject it per content so the malformed payload is
|
|
82
|
+
# reported errored instead. A null or absent lib_config
|
|
82
83
|
# carries no overrides and is left as a no-op.
|
|
83
84
|
lib_config = config["lib_config"]
|
|
84
85
|
if !lib_config.nil? && !lib_config.is_a?(Hash)
|
|
@@ -92,6 +93,7 @@ module Datadog
|
|
|
92
93
|
description: "Failed to parse APM_TRACING remote config",
|
|
93
94
|
)
|
|
94
95
|
content.errored("#{e.class}: #{e.message}: #{Array(e.backtrace).join("\n")}")
|
|
96
|
+
unparseable_contents << content
|
|
95
97
|
end
|
|
96
98
|
end
|
|
97
99
|
|
|
@@ -117,10 +119,26 @@ module Datadog
|
|
|
117
119
|
# deterministic merge.
|
|
118
120
|
ordered = applicable.sort_by { |content, config| [-config_priority(config), content.path.config_id] }
|
|
119
121
|
merged = merge_lib_configs(ordered.map { |_content, config| config })
|
|
122
|
+
# The applicable configs carrying a non-null dynamic_instrumentation_enabled
|
|
123
|
+
# value: any of their paths can still supply the signal after a later
|
|
124
|
+
# replacement, so the DI component records them all.
|
|
125
|
+
# @type var enable_signal_paths: Array[Datadog::Core::Remote::Configuration::Path]
|
|
126
|
+
enable_signal_paths = Core::Utils::EnumerableCompat.filter_map(ordered) do |pair|
|
|
127
|
+
content, config = pair
|
|
128
|
+
lib_config = config["lib_config"]
|
|
129
|
+
if lib_config.is_a?(Hash) && !lib_config["dynamic_instrumentation_enabled"].nil?
|
|
130
|
+
content.path
|
|
131
|
+
end
|
|
132
|
+
end
|
|
120
133
|
|
|
121
134
|
# Applied even when the set is empty: an emptied repository (last config
|
|
122
135
|
# removed) reverts the tracing overrides to their non-RC values.
|
|
123
|
-
apply_lib_config(
|
|
136
|
+
apply_lib_config(
|
|
137
|
+
merged,
|
|
138
|
+
repository,
|
|
139
|
+
unparseable_contents: unparseable_contents,
|
|
140
|
+
enable_signal_paths: enable_signal_paths,
|
|
141
|
+
)
|
|
124
142
|
|
|
125
143
|
parsed.each { |content, _config| content.applied }
|
|
126
144
|
nil
|
|
@@ -205,8 +223,10 @@ module Datadog
|
|
|
205
223
|
#
|
|
206
224
|
# @param lib_config [Hash[String, untyped]] the lib_config to apply
|
|
207
225
|
# @param repository [Core::Remote::Configuration::Repository, nil] forwarded to DI enablement
|
|
226
|
+
# @param unparseable_contents [Array<Core::Remote::Configuration::Content>] the APM_TRACING contents that failed to parse
|
|
227
|
+
# @param enable_signal_paths [Array<Core::Remote::Configuration::Path>] the paths of the applicable configs carrying the field
|
|
208
228
|
# @return [nil]
|
|
209
|
-
def apply_lib_config(lib_config, repository)
|
|
229
|
+
def apply_lib_config(lib_config, repository, unparseable_contents:, enable_signal_paths:)
|
|
210
230
|
env_vars = Datadog::Tracing::Configuration::Dynamic::OPTIONS.map do |name, env_var, option|
|
|
211
231
|
value = lib_config[name]
|
|
212
232
|
|
|
@@ -218,13 +238,30 @@ module Datadog
|
|
|
218
238
|
[env_var, telemetry_value]
|
|
219
239
|
end
|
|
220
240
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
241
|
+
di_enabled = lib_config["dynamic_instrumentation_enabled"]
|
|
242
|
+
# allow_initialization: false because this runs on the remote-config worker
|
|
243
|
+
# thread, and the default would build the component tree from that thread.
|
|
244
|
+
components = Datadog.send(:components, allow_initialization: false)
|
|
245
|
+
di_component = components&.dynamic_instrumentation
|
|
246
|
+
if di_enabled.nil? && di_component&.rc_enablement_signal_withdrawn?(unparseable_contents)
|
|
247
|
+
di_enabled = false
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Records the parsed carrier paths and the previously recorded paths whose
|
|
251
|
+
# replacements remain unparseable, on every merge including merges that keep
|
|
252
|
+
# the DI state.
|
|
253
|
+
if di_component
|
|
254
|
+
unparseable_recorded_paths = di_component.rc_enablement_signal_paths.select do |path|
|
|
255
|
+
unparseable_contents.any? { |content| content.path == path }
|
|
256
|
+
end
|
|
257
|
+
di_component.record_rc_enablement_signal_paths(enable_signal_paths + unparseable_recorded_paths)
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
unless di_enabled.nil?
|
|
261
|
+
# repository is forwarded for the stopped->started replay in
|
|
262
|
+
# Datadog::DI::Remote.handle_rc_enablement.
|
|
225
263
|
Datadog::DI::Remote.handle_rc_enablement(di_enabled, repository)
|
|
226
264
|
|
|
227
|
-
components = Datadog.send(:components, allow_initialization: false)
|
|
228
265
|
di_products = Datadog::DI::Remote.products +
|
|
229
266
|
Datadog::SymbolDatabase::Remote.deferred_products(Datadog.configuration)
|
|
230
267
|
|
|
@@ -236,7 +273,7 @@ module Datadog
|
|
|
236
273
|
# by DD_DYNAMIC_INSTRUMENTATION_ENABLED=false. Advertising then would
|
|
237
274
|
# report DI as in use when it is not and invite probe configs the
|
|
238
275
|
# tracer must refuse; withdraw the products otherwise.
|
|
239
|
-
if
|
|
276
|
+
if di_component&.started?
|
|
240
277
|
components&.remote&.add_products(*di_products)
|
|
241
278
|
else
|
|
242
279
|
components&.remote&.remove_products(*di_products)
|
|
@@ -249,13 +286,7 @@ module Datadog
|
|
|
249
286
|
Datadog.logger.debug { "APM_TRACING RC: merged dynamic_instrumentation_enabled=#{di_enabled}" }
|
|
250
287
|
end
|
|
251
288
|
|
|
252
|
-
|
|
253
|
-
# worker thread. If components haven't been built yet (e.g. during a
|
|
254
|
-
# teardown/reset window), the default value would synchronously build
|
|
255
|
-
# the entire component tree from this thread. The &. chain matches the
|
|
256
|
-
# pattern used by DI::Remote.handle_rc_enablement in the same dispatch
|
|
257
|
-
# path.
|
|
258
|
-
Datadog.send(:components, allow_initialization: false)&.telemetry&.client_configuration_change!(env_vars)
|
|
289
|
+
components&.telemetry&.client_configuration_change!(env_vars)
|
|
259
290
|
nil
|
|
260
291
|
end
|
|
261
292
|
|
|
@@ -269,7 +300,7 @@ module Datadog
|
|
|
269
300
|
|
|
270
301
|
def receiver(products = [PRODUCT], &block)
|
|
271
302
|
matcher = Core::Remote::Dispatcher::Matcher::Product.new(products)
|
|
272
|
-
[Core::Remote::Dispatcher::Receiver.new(matcher, &block)]
|
|
303
|
+
[Core::Remote::Dispatcher::Receiver.new(matcher, initial_reconcile: true, &block)]
|
|
273
304
|
end
|
|
274
305
|
|
|
275
306
|
private
|
data/lib/datadog/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: datadog
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.47.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Datadog, Inc.
|
|
@@ -49,28 +49,28 @@ dependencies:
|
|
|
49
49
|
requirements:
|
|
50
50
|
- - "~>"
|
|
51
51
|
- !ruby/object:Gem::Version
|
|
52
|
-
version: 1.30.0.
|
|
52
|
+
version: 1.30.0.1.0
|
|
53
53
|
type: :runtime
|
|
54
54
|
prerelease: false
|
|
55
55
|
version_requirements: !ruby/object:Gem::Requirement
|
|
56
56
|
requirements:
|
|
57
57
|
- - "~>"
|
|
58
58
|
- !ruby/object:Gem::Version
|
|
59
|
-
version: 1.30.0.
|
|
59
|
+
version: 1.30.0.1.0
|
|
60
60
|
- !ruby/object:Gem::Dependency
|
|
61
61
|
name: libdatadog
|
|
62
62
|
requirement: !ruby/object:Gem::Requirement
|
|
63
63
|
requirements:
|
|
64
64
|
- - "~>"
|
|
65
65
|
- !ruby/object:Gem::Version
|
|
66
|
-
version: 46.
|
|
66
|
+
version: 46.1.0.1.1
|
|
67
67
|
type: :runtime
|
|
68
68
|
prerelease: false
|
|
69
69
|
version_requirements: !ruby/object:Gem::Requirement
|
|
70
70
|
requirements:
|
|
71
71
|
- - "~>"
|
|
72
72
|
- !ruby/object:Gem::Version
|
|
73
|
-
version: 46.
|
|
73
|
+
version: 46.1.0.1.1
|
|
74
74
|
- !ruby/object:Gem::Dependency
|
|
75
75
|
name: logger
|
|
76
76
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -342,7 +342,6 @@ files:
|
|
|
342
342
|
- lib/datadog/appsec/thread_safe_ref.rb
|
|
343
343
|
- lib/datadog/appsec/trace_keeper.rb
|
|
344
344
|
- lib/datadog/appsec/utils.rb
|
|
345
|
-
- lib/datadog/appsec/utils/hash_coercion.rb
|
|
346
345
|
- lib/datadog/appsec/utils/http.rb
|
|
347
346
|
- lib/datadog/appsec/utils/http/body.rb
|
|
348
347
|
- lib/datadog/appsec/utils/http/body_reader.rb
|
|
@@ -611,6 +610,7 @@ files:
|
|
|
611
610
|
- lib/datadog/open_feature/ext.rb
|
|
612
611
|
- lib/datadog/open_feature/flag_evaluation/aggregator.rb
|
|
613
612
|
- lib/datadog/open_feature/flag_evaluation/writer.rb
|
|
613
|
+
- lib/datadog/open_feature/hooks/evaluation_telemetry_opt_out_hook.rb
|
|
614
614
|
- lib/datadog/open_feature/hooks/flag_eval_evp_hook.rb
|
|
615
615
|
- lib/datadog/open_feature/hooks/flag_eval_metrics_hook.rb
|
|
616
616
|
- lib/datadog/open_feature/hooks/span_enrichment_hook.rb
|
|
@@ -1199,8 +1199,8 @@ licenses:
|
|
|
1199
1199
|
- Apache-2.0
|
|
1200
1200
|
metadata:
|
|
1201
1201
|
allowed_push_host: https://rubygems.org
|
|
1202
|
-
changelog_uri: https://github.com/DataDog/dd-trace-rb/blob/v2.
|
|
1203
|
-
source_code_uri: https://github.com/DataDog/dd-trace-rb/tree/v2.
|
|
1202
|
+
changelog_uri: https://github.com/DataDog/dd-trace-rb/blob/v2.47.0/CHANGELOG.md
|
|
1203
|
+
source_code_uri: https://github.com/DataDog/dd-trace-rb/tree/v2.47.0
|
|
1204
1204
|
post_install_message: 'JRuby support in the datadog gem is deprecated. Details: https://dtdg.co/jruby-deprecation'
|
|
1205
1205
|
rdoc_options: []
|
|
1206
1206
|
require_paths:
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Datadog
|
|
4
|
-
module AppSec
|
|
5
|
-
module Utils
|
|
6
|
-
# A module for coercing arbitrary objects into hashes.
|
|
7
|
-
module HashCoercion
|
|
8
|
-
# A best effort to coerce an object to a hash with methods known to various
|
|
9
|
-
# frameworks with a fallback to standard library.
|
|
10
|
-
#
|
|
11
|
-
# @param object [Object] The object to coerce.
|
|
12
|
-
# @return [Hash, nil] The coerced `Hash` or `nil` if the object is not coercible.
|
|
13
|
-
def self.coerce(object)
|
|
14
|
-
return object.as_json if object.respond_to?(:as_json)
|
|
15
|
-
return object.to_hash if object.respond_to?(:to_hash)
|
|
16
|
-
return object.to_h if object.respond_to?(:to_h)
|
|
17
|
-
|
|
18
|
-
nil
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|