datadog 2.31.0 → 2.32.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.
Files changed (173) hide show
  1. checksums.yaml +4 -4
  2. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +17 -7
  3. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +11 -4
  4. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +6 -0
  5. data/ext/datadog_profiling_native_extension/extconf.rb +5 -4
  6. data/ext/datadog_profiling_native_extension/http_transport.c +10 -5
  7. data/ext/libdatadog_api/di.c +48 -0
  8. data/ext/libdatadog_api/extconf.rb +7 -4
  9. data/ext/libdatadog_extconf_helpers.rb +37 -0
  10. data/lib/datadog/ai_guard/configuration.rb +105 -2
  11. data/lib/datadog/ai_guard/evaluation.rb +1 -0
  12. data/lib/datadog/ai_guard/ext.rb +1 -0
  13. data/lib/datadog/appsec/autoload.rb +1 -1
  14. data/lib/datadog/appsec/component.rb +1 -1
  15. data/lib/datadog/appsec/configuration.rb +414 -1
  16. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +2 -1
  17. data/lib/datadog/appsec/contrib/rack/gateway/request.rb +1 -1
  18. data/lib/datadog/appsec/contrib/rails/patcher.rb +2 -2
  19. data/lib/datadog/appsec/metrics/telemetry.rb +13 -1
  20. data/lib/datadog/appsec/security_engine/runner.rb +1 -1
  21. data/lib/datadog/appsec/trace_keeper.rb +18 -6
  22. data/lib/datadog/appsec/utils/http/url_encoded.rb +2 -2
  23. data/lib/datadog/core/configuration/components.rb +1 -1
  24. data/lib/datadog/core/configuration/settings.rb +3 -0
  25. data/lib/datadog/core/configuration/supported_configurations.rb +2 -0
  26. data/lib/datadog/core/configuration.rb +1 -1
  27. data/lib/datadog/core/contrib/rails/utils.rb +1 -1
  28. data/lib/datadog/core/crashtracking/component.rb +3 -3
  29. data/lib/datadog/core/diagnostics/environment_logger.rb +3 -1
  30. data/lib/datadog/core/environment/container.rb +2 -2
  31. data/lib/datadog/core/feature_flags.rb +1 -1
  32. data/lib/datadog/core/metrics/client.rb +5 -5
  33. data/lib/datadog/core/remote/client.rb +1 -1
  34. data/lib/datadog/core/remote/component.rb +2 -2
  35. data/lib/datadog/core/runtime/metrics.rb +1 -1
  36. data/lib/datadog/core/telemetry/emitter.rb +1 -1
  37. data/lib/datadog/core/telemetry/event/app_started.rb +2 -2
  38. data/lib/datadog/core/transport/http.rb +2 -0
  39. data/lib/datadog/core/utils.rb +1 -1
  40. data/lib/datadog/core/workers/async.rb +1 -1
  41. data/lib/datadog/core.rb +1 -1
  42. data/lib/datadog/data_streams/configuration.rb +40 -1
  43. data/lib/datadog/data_streams/pathway_context.rb +1 -1
  44. data/lib/datadog/data_streams/processor.rb +1 -1
  45. data/lib/datadog/data_streams.rb +1 -1
  46. data/lib/datadog/di/base.rb +8 -5
  47. data/lib/datadog/di/code_tracker.rb +179 -1
  48. data/lib/datadog/di/component.rb +1 -1
  49. data/lib/datadog/di/configuration.rb +235 -2
  50. data/lib/datadog/di/instrumenter.rb +46 -26
  51. data/lib/datadog/di/probe_builder.rb +1 -1
  52. data/lib/datadog/di/probe_file_loader.rb +2 -2
  53. data/lib/datadog/di/probe_manager.rb +6 -6
  54. data/lib/datadog/di/probe_notification_builder.rb +1 -1
  55. data/lib/datadog/di/probe_notifier_worker.rb +2 -2
  56. data/lib/datadog/di/remote.rb +6 -6
  57. data/lib/datadog/di/serializer.rb +1 -1
  58. data/lib/datadog/di/transport/input.rb +3 -3
  59. data/lib/datadog/error_tracking/configuration.rb +55 -2
  60. data/lib/datadog/kit/enable_core_dumps.rb +1 -1
  61. data/lib/datadog/open_feature/component.rb +18 -1
  62. data/lib/datadog/open_feature/evaluation_engine.rb +3 -3
  63. data/lib/datadog/open_feature/exposures/reporter.rb +1 -1
  64. data/lib/datadog/open_feature/exposures/worker.rb +1 -1
  65. data/lib/datadog/open_feature/hooks/flag_eval_hook.rb +49 -0
  66. data/lib/datadog/open_feature/metrics/flag_eval_metrics.rb +149 -0
  67. data/lib/datadog/open_feature/provider.rb +19 -1
  68. data/lib/datadog/open_feature/remote.rb +1 -1
  69. data/lib/datadog/open_feature/transport.rb +1 -1
  70. data/lib/datadog/opentelemetry/metrics.rb +3 -3
  71. data/lib/datadog/opentelemetry/sdk/configurator.rb +1 -1
  72. data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +1 -1
  73. data/lib/datadog/profiling/collectors/code_provenance.rb +35 -9
  74. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +31 -2
  75. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +8 -2
  76. data/lib/datadog/profiling/collectors/info.rb +16 -3
  77. data/lib/datadog/profiling/component.rb +3 -5
  78. data/lib/datadog/profiling/exporter.rb +37 -12
  79. data/lib/datadog/profiling/ext.rb +0 -2
  80. data/lib/datadog/profiling/flush.rb +21 -12
  81. data/lib/datadog/profiling/http_transport.rb +12 -1
  82. data/lib/datadog/profiling/load_native_extension.rb +1 -1
  83. data/lib/datadog/profiling/profiler.rb +13 -1
  84. data/lib/datadog/profiling/scheduler.rb +2 -2
  85. data/lib/datadog/profiling/tasks/exec.rb +8 -3
  86. data/lib/datadog/profiling/tasks/help.rb +1 -0
  87. data/lib/datadog/profiling/tasks/setup.rb +2 -2
  88. data/lib/datadog/single_step_instrument.rb +1 -1
  89. data/lib/datadog/symbol_database/configuration.rb +65 -0
  90. data/lib/datadog/symbol_database/extractor.rb +915 -0
  91. data/lib/datadog/symbol_database/file_hash.rb +46 -0
  92. data/lib/datadog/symbol_database/logger.rb +43 -0
  93. data/lib/datadog/symbol_database/scope.rb +98 -0
  94. data/lib/datadog/symbol_database/service_version.rb +57 -0
  95. data/lib/datadog/symbol_database/symbol.rb +66 -0
  96. data/lib/datadog/symbol_database/transport/http/endpoint.rb +28 -0
  97. data/lib/datadog/symbol_database/transport/http.rb +45 -0
  98. data/lib/datadog/symbol_database/transport.rb +54 -0
  99. data/lib/datadog/symbol_database/uploader.rb +166 -0
  100. data/lib/datadog/symbol_database.rb +49 -0
  101. data/lib/datadog/tracing/buffer.rb +3 -3
  102. data/lib/datadog/tracing/configuration/settings.rb +1 -1
  103. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +5 -3
  104. data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +1 -1
  105. data/lib/datadog/tracing/contrib/active_job/events/discard.rb +1 -1
  106. data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +1 -1
  107. data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +1 -1
  108. data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +1 -1
  109. data/lib/datadog/tracing/contrib/active_job/events/perform.rb +1 -1
  110. data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +1 -1
  111. data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +1 -1
  112. data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +1 -1
  113. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +2 -2
  114. data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +1 -1
  115. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +1 -1
  116. data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
  117. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +1 -1
  118. data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +2 -2
  119. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +1 -1
  120. data/lib/datadog/tracing/contrib/component.rb +1 -1
  121. data/lib/datadog/tracing/contrib/configuration/resolver.rb +7 -4
  122. data/lib/datadog/tracing/contrib/dalli/quantize.rb +1 -1
  123. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +1 -1
  124. data/lib/datadog/tracing/contrib/excon/middleware.rb +2 -2
  125. data/lib/datadog/tracing/contrib/extensions.rb +9 -0
  126. data/lib/datadog/tracing/contrib/faraday/middleware.rb +2 -2
  127. data/lib/datadog/tracing/contrib/grape/endpoint.rb +5 -5
  128. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +2 -2
  129. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +2 -2
  130. data/lib/datadog/tracing/contrib/http/instrumentation.rb +2 -2
  131. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -2
  132. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +2 -2
  133. data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +2 -2
  134. data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +2 -2
  135. data/lib/datadog/tracing/contrib/karafka/patcher.rb +1 -1
  136. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +3 -3
  137. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +1 -1
  138. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +3 -3
  139. data/lib/datadog/tracing/contrib/rack/patcher.rb +1 -1
  140. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  141. data/lib/datadog/tracing/contrib/rails/log_injection.rb +1 -1
  142. data/lib/datadog/tracing/contrib/rails/runner.rb +1 -1
  143. data/lib/datadog/tracing/contrib/rake/instrumentation.rb +2 -2
  144. data/lib/datadog/tracing/contrib/redis/quantize.rb +1 -1
  145. data/lib/datadog/tracing/contrib/redis/tags.rb +1 -1
  146. data/lib/datadog/tracing/contrib/sidekiq/utils.rb +1 -1
  147. data/lib/datadog/tracing/contrib/stripe/request.rb +1 -1
  148. data/lib/datadog/tracing/contrib.rb +8 -0
  149. data/lib/datadog/tracing/diagnostics/environment_logger.rb +3 -1
  150. data/lib/datadog/tracing/distributed/baggage.rb +59 -5
  151. data/lib/datadog/tracing/distributed/datadog.rb +11 -11
  152. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +1 -1
  153. data/lib/datadog/tracing/distributed/propagation.rb +2 -2
  154. data/lib/datadog/tracing/distributed/trace_context.rb +74 -32
  155. data/lib/datadog/tracing/event.rb +1 -1
  156. data/lib/datadog/tracing/metadata/tagging.rb +2 -2
  157. data/lib/datadog/tracing/pipeline.rb +1 -1
  158. data/lib/datadog/tracing/remote.rb +1 -1
  159. data/lib/datadog/tracing/sampling/rule.rb +1 -1
  160. data/lib/datadog/tracing/sampling/rule_sampler.rb +2 -2
  161. data/lib/datadog/tracing/sampling/span/rule_parser.rb +2 -2
  162. data/lib/datadog/tracing/span_operation.rb +3 -3
  163. data/lib/datadog/tracing/trace_operation.rb +4 -4
  164. data/lib/datadog/tracing/tracer.rb +5 -5
  165. data/lib/datadog/tracing/transport/io/client.rb +1 -1
  166. data/lib/datadog/tracing/workers.rb +2 -1
  167. data/lib/datadog/version.rb +1 -1
  168. metadata +18 -9
  169. data/lib/datadog/ai_guard/configuration/settings.rb +0 -113
  170. data/lib/datadog/appsec/configuration/settings.rb +0 -423
  171. data/lib/datadog/data_streams/configuration/settings.rb +0 -49
  172. data/lib/datadog/di/configuration/settings.rb +0 -243
  173. data/lib/datadog/error_tracking/configuration/settings.rb +0 -63
@@ -1,11 +1,424 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'configuration/settings'
3
+ require_relative '../core/utils/duration'
4
+ require_relative 'sample_rate'
4
5
 
5
6
  module Datadog
6
7
  module AppSec
7
8
  # Configuration for AppSec
8
9
  module Configuration
10
+ # Settings
11
+ module Settings
12
+ # rubocop:disable Layout/LineLength
13
+ DEFAULT_OBFUSCATOR_KEY_REGEX = '(?i)pass|pw(?:or)?d|secret|(?:api|private|public|access)[_-]?key|token|consumer[_-]?(?:id|key|secret)|sign(?:ed|ature)|bearer|authorization|jsessionid|phpsessid|asp\.net[_-]sessionid|sid|jwt'
14
+ DEFAULT_OBFUSCATOR_VALUE_REGEX = '(?i)(?:p(?:ass)?w(?:or)?d|pass(?:[_-]?phrase)?|secret(?:[_-]?key)?|(?:(?:api|private|public|access)[_-]?)key(?:[_-]?id)?|(?:(?:auth|access|id|refresh)[_-]?)?token|consumer[_-]?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?|jsessionid|phpsessid|asp\.net(?:[_-]|-)sessionid|sid|jwt)(?:\s*=[^;]|"\s*:\s*"[^"]+")|bearer\s+[a-z0-9\._\-]+|token:[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|ey[I-L][\w=-]+\.ey[I-L][\w=-]+(?:\.[\w.+\/=-]+)?|[\-]{5}BEGIN[a-z\s]+PRIVATE\sKEY[\-]{5}[^\-]+[\-]{5}END[a-z\s]+PRIVATE\sKEY|ssh-rsa\s*[a-z0-9\/\.+]{100,}'
15
+ # rubocop:enable Layout/LineLength
16
+
17
+ DISABLED_AUTO_USER_INSTRUMENTATION_MODE = 'disabled'
18
+ ANONYMIZATION_AUTO_USER_INSTRUMENTATION_MODE = 'anonymization'
19
+ IDENTIFICATION_AUTO_USER_INSTRUMENTATION_MODE = 'identification'
20
+ AUTO_USER_INSTRUMENTATION_MODES = [
21
+ DISABLED_AUTO_USER_INSTRUMENTATION_MODE,
22
+ ANONYMIZATION_AUTO_USER_INSTRUMENTATION_MODE,
23
+ IDENTIFICATION_AUTO_USER_INSTRUMENTATION_MODE
24
+ ].freeze
25
+ AUTO_USER_INSTRUMENTATION_MODES_ALIASES = {
26
+ 'ident' => IDENTIFICATION_AUTO_USER_INSTRUMENTATION_MODE,
27
+ 'anon' => ANONYMIZATION_AUTO_USER_INSTRUMENTATION_MODE,
28
+ }.freeze
29
+
30
+ # NOTE: These two constants are deprecated
31
+ SAFE_TRACK_USER_EVENTS_MODE = 'safe'
32
+ EXTENDED_TRACK_USER_EVENTS_MODE = 'extended'
33
+ APPSEC_VALID_TRACK_USER_EVENTS_MODE = [
34
+ SAFE_TRACK_USER_EVENTS_MODE, EXTENDED_TRACK_USER_EVENTS_MODE
35
+ ].freeze
36
+ APPSEC_VALID_TRACK_USER_EVENTS_ENABLED_VALUES = ['1', 'true'].concat(
37
+ APPSEC_VALID_TRACK_USER_EVENTS_MODE
38
+ ).freeze
39
+
40
+ def self.extended(base)
41
+ base = base.singleton_class unless base.is_a?(Class)
42
+ add_settings!(base)
43
+ end
44
+
45
+ # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/BlockLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
46
+ def self.add_settings!(base)
47
+ base.class_eval do
48
+ settings :appsec do
49
+ option :enabled do |o|
50
+ o.type :bool
51
+ o.env 'DD_APPSEC_ENABLED'
52
+ o.default false
53
+ end
54
+
55
+ define_method(:instrument) do |integration_name|
56
+ if enabled
57
+ registered_integration = Datadog::AppSec::Contrib::Integration.registry[integration_name]
58
+ if registered_integration
59
+ klass = registered_integration.klass
60
+ if klass.loaded? && klass.compatible?
61
+ instance = klass.new
62
+ instance.patcher.patch unless instance.patcher.patched?
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ # RASP or Runtime Application Self-Protection
69
+ # is a collection of techniques and heuristics aimed at detecting malicious inputs and preventing
70
+ # any potential side-effects on the application resulting from the use of said malicious inputs.
71
+ option :rasp_enabled do |o|
72
+ o.type :bool, nilable: true
73
+ o.env 'DD_APPSEC_RASP_ENABLED'
74
+ o.default true
75
+ end
76
+
77
+ option :ruleset do |o|
78
+ o.env 'DD_APPSEC_RULES'
79
+ o.default :recommended
80
+ end
81
+
82
+ option :ip_passlist do |o|
83
+ o.default []
84
+
85
+ o.setter do |value|
86
+ next value if value.nil? || value.empty?
87
+
88
+ Datadog::Core.log_deprecation(disallowed_next_major: false) do
89
+ 'The ip_passlist setting is deprecated and will be removed in the next release. ' \
90
+ 'Please migrate this configuration to your service settings via the Datadog UI'
91
+ end
92
+
93
+ value
94
+ end
95
+ end
96
+
97
+ option :ip_denylist do |o|
98
+ o.type :array
99
+ o.default []
100
+
101
+ o.setter do |value|
102
+ next value if value.nil? || value.empty?
103
+
104
+ Datadog::Core.log_deprecation(disallowed_next_major: false) do
105
+ 'The ip_denylist setting is deprecated and will be removed in the next release. ' \
106
+ 'Please migrate this configuration to your service settings via the Datadog UI'
107
+ end
108
+
109
+ value
110
+ end
111
+ end
112
+
113
+ option :user_id_denylist do |o|
114
+ o.type :array
115
+ o.default []
116
+
117
+ o.setter do |value|
118
+ next value if value.nil? || value.empty?
119
+
120
+ Datadog::Core.log_deprecation(disallowed_next_major: false) do
121
+ 'The user_id_denylist setting is deprecated and will be removed in the next release. ' \
122
+ 'Please migrate this configuration to your service settings via the Datadog UI'
123
+ end
124
+
125
+ value
126
+ end
127
+ end
128
+
129
+ option :waf_timeout do |o|
130
+ o.env 'DD_APPSEC_WAF_TIMEOUT' # us
131
+ o.default 5_000
132
+ o.setter do |v|
133
+ Datadog::Core::Utils::Duration.call(v.to_s, base: :us)
134
+ end
135
+ end
136
+
137
+ option :waf_debug do |o|
138
+ o.env 'DD_APPSEC_WAF_DEBUG'
139
+ o.default false
140
+ o.type :bool
141
+ end
142
+
143
+ option :trace_rate_limit do |o|
144
+ o.type :int
145
+ o.env 'DD_APPSEC_TRACE_RATE_LIMIT' # trace/s
146
+ o.default 100
147
+ end
148
+
149
+ option :obfuscator_key_regex do |o|
150
+ o.type :string
151
+ o.env 'DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP'
152
+ o.default DEFAULT_OBFUSCATOR_KEY_REGEX
153
+ end
154
+
155
+ option :obfuscator_value_regex do |o|
156
+ o.type :string
157
+ o.env 'DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP'
158
+ o.default DEFAULT_OBFUSCATOR_VALUE_REGEX
159
+ end
160
+
161
+ settings :block do
162
+ settings :templates do
163
+ option :html do |o|
164
+ o.env 'DD_APPSEC_HTTP_BLOCKED_TEMPLATE_HTML'
165
+ o.type :string, nilable: true
166
+ o.setter do |value|
167
+ if value
168
+ unless File.exist?(value)
169
+ raise(ArgumentError,
170
+ "appsec.templates.html: file not found: #{value}")
171
+ end
172
+
173
+ File.binread(value) || ''
174
+ end
175
+ end
176
+ end
177
+
178
+ option :json do |o|
179
+ o.env 'DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON'
180
+ o.type :string, nilable: true
181
+ o.setter do |value|
182
+ if value
183
+ unless File.exist?(value)
184
+ raise(ArgumentError,
185
+ "appsec.templates.json: file not found: #{value}")
186
+ end
187
+
188
+ File.binread(value) || ''
189
+ end
190
+ end
191
+ end
192
+
193
+ option :text do |o|
194
+ o.env 'DD_APPSEC_HTTP_BLOCKED_TEMPLATE_TEXT'
195
+ o.type :string, nilable: true
196
+ o.setter do |value|
197
+ if value
198
+ unless File.exist?(value)
199
+ raise(ArgumentError,
200
+ "appsec.templates.text: file not found: #{value}")
201
+ end
202
+
203
+ File.binread(value) || ''
204
+ end
205
+ end
206
+ end
207
+ end
208
+ end
209
+
210
+ settings :stack_trace do
211
+ option :enabled do |o|
212
+ o.type :bool
213
+ o.env 'DD_APPSEC_STACK_TRACE_ENABLED'
214
+ o.default true
215
+ end
216
+
217
+ # The maximum number of stack trace frames to collect for each stack trace.
218
+ #
219
+ # If the stack trace exceeds this limit, the frames are dropped from the middle of the stack trace:
220
+ # 75% of the frames are kept from the top of the stack trace and 25% from the bottom
221
+ # (this percentage is also configurable).
222
+ #
223
+ # Minimum value is 10.
224
+ # Set to zero if you don't want any frames to be dropped.
225
+ #
226
+ # Default value is 32
227
+ option :max_depth do |o|
228
+ o.type :int
229
+ o.env 'DD_APPSEC_MAX_STACK_TRACE_DEPTH'
230
+ o.default 32
231
+
232
+ o.setter do |value|
233
+ value = 0 if value < 0
234
+ value
235
+ end
236
+ end
237
+
238
+ # The percentage of frames to keep from the top of the stack trace.
239
+ #
240
+ # Default value is 75
241
+ option :top_percentage do |o|
242
+ o.type :int
243
+ o.env 'DD_APPSEC_MAX_STACK_TRACE_DEPTH_TOP_PERCENT'
244
+ o.default 75
245
+
246
+ o.setter do |value|
247
+ value = 100 if value > 100
248
+ value = 0 if value.negative?
249
+ value
250
+ end
251
+ end
252
+
253
+ # Maximum number of stack traces to collect per span.
254
+ #
255
+ # Set to zero if you want to collect all stack traces.
256
+ #
257
+ # Default value is 2
258
+ option :max_stack_traces do |o|
259
+ o.type :int
260
+ o.env 'DD_APPSEC_MAX_STACK_TRACES'
261
+ o.default 2
262
+
263
+ o.setter do |value|
264
+ value = 0 if value < 0
265
+ value
266
+ end
267
+ end
268
+ end
269
+
270
+ settings :auto_user_instrumentation do
271
+ define_method(:enabled?) { get_option(:mode) != DISABLED_AUTO_USER_INSTRUMENTATION_MODE }
272
+
273
+ option :mode do |o|
274
+ o.type :string
275
+ o.env 'DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE'
276
+ o.default IDENTIFICATION_AUTO_USER_INSTRUMENTATION_MODE
277
+ o.setter do |value|
278
+ mode = AUTO_USER_INSTRUMENTATION_MODES_ALIASES.fetch(value, value)
279
+ next mode if AUTO_USER_INSTRUMENTATION_MODES.include?(mode)
280
+
281
+ Datadog.logger.warn(
282
+ 'The appsec.auto_user_instrumentation.mode value provided is not supported. ' \
283
+ "Supported values are: #{AUTO_USER_INSTRUMENTATION_MODES.join(" | ")}. " \
284
+ "Using value: #{DISABLED_AUTO_USER_INSTRUMENTATION_MODE}."
285
+ )
286
+
287
+ DISABLED_AUTO_USER_INSTRUMENTATION_MODE
288
+ end
289
+ end
290
+ end
291
+
292
+ # DEV-3.0: Remove `track_user_events.enabled` and `track_user_events.mode` options
293
+ settings :track_user_events do
294
+ option :enabled do |o|
295
+ o.default true
296
+ o.type :bool
297
+ o.env 'DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING'
298
+ o.env_parser do |env_value|
299
+ if env_value == 'disabled'
300
+ false
301
+ else
302
+ APPSEC_VALID_TRACK_USER_EVENTS_ENABLED_VALUES.include?(env_value.strip.downcase)
303
+ end
304
+ end
305
+ o.after_set do |_, _, precedence|
306
+ unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
307
+ Core.log_deprecation(key: :appsec_track_user_events_enabled) do
308
+ 'The appsec.track_user_events.enabled setting is deprecated. ' \
309
+ 'Please remove it from your Datadog.configure block and use ' \
310
+ 'appsec.auto_user_instrumentation.mode instead.'
311
+ end
312
+ end
313
+ end
314
+ end
315
+
316
+ option :mode do |o|
317
+ o.type :string
318
+ o.env 'DD_APPSEC_AUTOMATED_USER_EVENTS_TRACKING'
319
+ o.default SAFE_TRACK_USER_EVENTS_MODE
320
+ o.setter do |v|
321
+ if APPSEC_VALID_TRACK_USER_EVENTS_MODE.include?(v)
322
+ v
323
+ elsif v == 'disabled'
324
+ SAFE_TRACK_USER_EVENTS_MODE
325
+ else
326
+ Datadog.logger.warn(
327
+ 'The appsec.track_user_events.mode value provided is not supported.' \
328
+ "Supported values are: #{APPSEC_VALID_TRACK_USER_EVENTS_MODE.join(" | ")}." \
329
+ "Using default value: #{SAFE_TRACK_USER_EVENTS_MODE}."
330
+ )
331
+
332
+ SAFE_TRACK_USER_EVENTS_MODE
333
+ end
334
+ end
335
+ o.after_set do |_, _, precedence|
336
+ unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
337
+ Core.log_deprecation(key: :appsec_track_user_events_mode) do
338
+ 'The appsec.track_user_events.mode setting is deprecated. ' \
339
+ 'Please remove it from your Datadog.configure block and use ' \
340
+ 'appsec.auto_user_instrumentation.mode instead.'
341
+ end
342
+ end
343
+ end
344
+ end
345
+ end
346
+
347
+ settings :api_security do
348
+ define_method(:enabled?) { get_option(:enabled) }
349
+
350
+ option :enabled do |o|
351
+ o.type :bool
352
+ o.env 'DD_API_SECURITY_ENABLED'
353
+ o.default true
354
+ end
355
+
356
+ settings :endpoint_collection do
357
+ # Enables reporting of application routes at application start via telemetry
358
+ option :enabled do |o|
359
+ o.type :bool, nilable: true
360
+ o.env 'DD_API_SECURITY_ENDPOINT_COLLECTION_ENABLED'
361
+ o.default true
362
+ end
363
+ end
364
+
365
+ # NOTE: Unfortunately, we have to go with Float due to other libs
366
+ # setup, even tho we don't plan to support sub-second delays.
367
+ #
368
+ # WARNING: The value will be converted to Integer.
369
+ option :sample_delay do |o|
370
+ o.type :float
371
+ o.env 'DD_API_SECURITY_SAMPLE_DELAY'
372
+ o.default 30
373
+ o.setter do |value|
374
+ value.to_i
375
+ end
376
+ end
377
+
378
+ # DEV-3.0: Remove `api_security.sample_rate` option
379
+ option :sample_rate do |o|
380
+ o.type :float
381
+ o.env 'DD_API_SECURITY_REQUEST_SAMPLE_RATE'
382
+ o.default 0.1
383
+ o.setter do |value|
384
+ value = 1 if value > 1
385
+ SampleRate.new(value)
386
+ end
387
+ o.after_set do |_, _, precedence|
388
+ next if precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
389
+
390
+ Core.log_deprecation(key: :appsec_api_security_sample_rate) do
391
+ 'The appsec.api_security.sample_rate setting is deprecated. ' \
392
+ 'Please remove it from your Datadog.configure block and use ' \
393
+ 'appsec.api_security.sample_delay instead.'
394
+ end
395
+ end
396
+ end
397
+
398
+ settings :downstream_body_analysis do
399
+ option :sample_rate do |o|
400
+ o.type :float
401
+ o.env 'DD_API_SECURITY_DOWNSTREAM_BODY_ANALYSIS_SAMPLE_RATE'
402
+ o.default 0.5
403
+ end
404
+
405
+ option :max_requests do |o|
406
+ o.type :int
407
+ o.env 'DD_API_SECURITY_MAX_DOWNSTREAM_REQUEST_BODY_ANALYSIS'
408
+ o.default 1
409
+ end
410
+ end
411
+ end
412
+
413
+ option :sca_enabled do |o|
414
+ o.type :bool, nilable: true
415
+ o.env 'DD_APPSEC_SCA_ENABLED'
416
+ end
417
+ end
418
+ end
419
+ end
420
+ # rubocop:enable Metrics/AbcSize,Metrics/MethodLength,Metrics/BlockLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
421
+ end
9
422
  end
10
423
  end
11
424
  end
@@ -18,9 +18,10 @@ module Datadog
18
18
  return result unless AppSec.enabled?
19
19
  return result if @_datadog_appsec_skip_track_login_event
20
20
  return result unless Configuration.auto_user_instrumentation_enabled?
21
- return result unless AppSec.active_context
22
21
 
23
22
  context = AppSec.active_context
23
+ return result unless context
24
+
24
25
  if context.trace.nil? || context.span.nil?
25
26
  Datadog.logger.debug { 'AppSec: unable to track signin events, due to missing trace or span' }
26
27
  return result
@@ -25,7 +25,7 @@ module Datadog
25
25
  def query
26
26
  ::Rack::Utils.parse_query(request.query_string)
27
27
  rescue => e
28
- Datadog.logger.debug { "AppSec: Failed to parse request query string: #{e.class}: #{e}" }
28
+ Datadog.logger.debug { "AppSec: Failed to parse request query string: #{e.class}: #{e.message}" }
29
29
  AppSec.telemetry.report(e, description: 'AppSec: Failed to parse request query string')
30
30
 
31
31
  {}
@@ -138,7 +138,7 @@ module Datadog
138
138
  end
139
139
  rescue => e
140
140
  error_message = 'Failed to get application routes'
141
- Datadog.logger.error("#{error_message}, #{e.class}: #{e}")
141
+ Datadog.logger.error("#{error_message}, #{e.class}: #{e.message}")
142
142
  AppSec.telemetry.report(e, description: error_message)
143
143
  end
144
144
  end
@@ -148,7 +148,7 @@ module Datadog
148
148
  Datadog::AppSec::Contrib::Rails::Patcher.report_routes_via_telemetry(::Rails.application.routes.routes)
149
149
  rescue => e
150
150
  error_message = 'Failed to get application routes'
151
- Datadog.logger.error("#{error_message}, #{e.class}: #{e}")
151
+ Datadog.logger.error("#{error_message}, #{e.class}: #{e.message}")
152
152
  AppSec.telemetry.report(e, description: error_message)
153
153
  end
154
154
  end
@@ -5,6 +5,11 @@ module Datadog
5
5
  module Metrics
6
6
  # A class responsible for reporting WAF and RASP telemetry metrics.
7
7
  module Telemetry
8
+ ACTION_BLOCK = 'block_request'
9
+ ACTION_REDIRECT = 'redirect_request'
10
+ BLOCK_SUCCESS = 'success'
11
+ BLOCK_IRRELEVANT = 'irrelevant'
12
+
8
13
  module_function
9
14
 
10
15
  def report_rasp(type, result, phase: nil)
@@ -19,8 +24,15 @@ module Datadog
19
24
  namespace = Ext::TELEMETRY_METRICS_NAMESPACE
20
25
 
21
26
  AppSec.telemetry.inc(namespace, 'rasp.rule.eval', 1, tags: tags)
22
- AppSec.telemetry.inc(namespace, 'rasp.rule.match', 1, tags: tags) if result.match?
23
27
  AppSec.telemetry.inc(namespace, 'rasp.timeout', 1, tags: tags) if result.timeout?
28
+
29
+ if result.match?
30
+ blocked = result.actions.key?(ACTION_BLOCK) || result.actions.key?(ACTION_REDIRECT)
31
+ # NOTE: Mutates tags to avoid an extra hash allocation. Keep this the last .inc call.
32
+ tags[:block] = blocked ? BLOCK_SUCCESS : BLOCK_IRRELEVANT
33
+
34
+ AppSec.telemetry.inc(namespace, 'rasp.rule.match', 1, tags: tags)
35
+ end
24
36
  end
25
37
  end
26
38
  end
@@ -79,7 +79,7 @@ module Datadog
79
79
  def try_run(persistent_data, ephemeral_data, timeout)
80
80
  waf_context.run(persistent_data, ephemeral_data, timeout)
81
81
  rescue WAF::LibDDWAFError => e
82
- Datadog.logger.debug { "#{@debug_tag} execution error: #{e} backtrace: #{e.backtrace&.first(3)}" }
82
+ Datadog.logger.debug { "#{@debug_tag} execution error: #{e.class}: #{e.message} backtrace: #{e.backtrace&.first(3)}" }
83
83
  AppSec.telemetry.report(e, description: 'libddwaf-rb internal low-level error')
84
84
 
85
85
  WAF::Result.new(
@@ -7,16 +7,28 @@ module Datadog
7
7
  def self.keep!(trace)
8
8
  return unless trace
9
9
 
10
+ previous_dm = trace.get_tag(Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER)
11
+
10
12
  # NOTE: This action will not set correct decision maker value, so the
11
13
  # trace keeping must be done with additional steps below
12
14
  trace.keep!
13
15
 
14
- # Propagate to downstream services the information that
15
- # the current distributed trace is containing at least one ASM event.
16
- trace.set_tag(
17
- Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER,
18
- Tracing::Sampling::Ext::Decision::ASM
19
- )
16
+ # NOTE: Preserve decision maker if already set by another product.
17
+ # As `trace.keep!` resets `_dd.p.dm` to `MANUAL`, we restore the
18
+ # previous value when another product has already claimed the
19
+ # decision maker.
20
+ if previous_dm.nil? || previous_dm == Tracing::Sampling::Ext::Decision::MANUAL
21
+ trace.set_tag(
22
+ Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER,
23
+ Tracing::Sampling::Ext::Decision::ASM
24
+ )
25
+ else
26
+ trace.set_tag(
27
+ Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER,
28
+ previous_dm,
29
+ )
30
+ end
31
+
20
32
  trace.set_distributed_source(Ext::PRODUCT_BIT)
21
33
  end
22
34
  end
@@ -30,8 +30,8 @@ module Datadog
30
30
  #
31
31
  # @type var key: ::String
32
32
  # @type var value: ::String
33
- key, value = pair.split('=', 2).map! do |value|
34
- CGI.unescape(value)
33
+ key, value = pair.split('=', 2).map! do |val|
34
+ CGI.unescape(val)
35
35
  end #: [::String, ::String]
36
36
 
37
37
  if (stored = memo[key])
@@ -98,7 +98,7 @@ module Datadog
98
98
  agent_info: agent_info
99
99
  )
100
100
  rescue => e
101
- logger.warn("Failed to initialize Data Streams Monitoring: #{e.class}: #{e}")
101
+ logger.warn("Failed to initialize Data Streams Monitoring: #{e.class}: #{e.message}")
102
102
  nil
103
103
  end
104
104
  end
@@ -13,6 +13,7 @@ require_relative '../../profiling/ext'
13
13
 
14
14
  require_relative '../../tracing/configuration/settings'
15
15
  require_relative '../../opentelemetry/configuration/settings'
16
+ require_relative '../../symbol_database/configuration'
16
17
 
17
18
  module Datadog
18
19
  module Core
@@ -1111,6 +1112,8 @@ module Datadog
1111
1112
  extend Datadog::Tracing::Configuration::Settings
1112
1113
 
1113
1114
  extend Datadog::OpenTelemetry::Configuration::Settings
1115
+
1116
+ extend Datadog::SymbolDatabase::Configuration::Settings
1114
1117
  end
1115
1118
  # standard:enable Metrics/BlockLength
1116
1119
  end
@@ -67,6 +67,7 @@ module Datadog
67
67
  "DD_INSTRUMENTATION_INSTALL_TIME",
68
68
  "DD_INSTRUMENTATION_INSTALL_TYPE",
69
69
  "DD_INSTRUMENTATION_TELEMETRY_ENABLED",
70
+ "DD_INTERNAL_FORCE_SYMBOL_DATABASE_UPLOAD",
70
71
  "DD_LOGS_INJECTION",
71
72
  "DD_METRICS_OTEL_ENABLED",
72
73
  "DD_METRIC_AGENT_PORT",
@@ -104,6 +105,7 @@ module Datadog
104
105
  "DD_SITE",
105
106
  "DD_SPAN_SAMPLING_RULES",
106
107
  "DD_SPAN_SAMPLING_RULES_FILE",
108
+ "DD_SYMBOL_DATABASE_UPLOAD_ENABLED",
107
109
  "DD_TAGS",
108
110
  "DD_TELEMETRY_AGENTLESS_URL",
109
111
  "DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED",
@@ -238,7 +238,7 @@ module Datadog
238
238
  yield write_components
239
239
  rescue ThreadError => e
240
240
  logger_without_components.error(
241
- "Detected deadlock during datadog initialization: #{e.class}: #{e}. " \
241
+ "Detected deadlock during datadog initialization: #{e.class}: #{e.message}. " \
242
242
  'Please report this at https://github.com/datadog/dd-trace-rb/blob/master/CONTRIBUTING.md#found-a-bug' \
243
243
  "\n\tSource:\n\t#{Array(e.backtrace).join("\n\t")}"
244
244
  )
@@ -14,7 +14,7 @@ module Datadog
14
14
  end
15
15
  application_name&.underscore
16
16
  rescue => e
17
- Datadog.logger.debug("Failed to extract Rails application name: #{e.class}: #{e}")
17
+ Datadog.logger.debug("Failed to extract Rails application name: #{e.class}: #{e.message}")
18
18
  nil
19
19
  end
20
20
 
@@ -55,7 +55,7 @@ module Datadog
55
55
  # Unhandled exception report triggering means that the application is already in a bad state
56
56
  # We don't want to swallow non-StandardError exceptions here; we would rather just let the
57
57
  # application crash
58
- Datadog.logger.debug { "Crashtracker failed to report unhandled exception: #{e.class}: #{e}" }
58
+ Datadog.logger.debug { "Crashtracker failed to report unhandled exception: #{e.class}: #{e.message}" }
59
59
  end
60
60
  end
61
61
 
@@ -130,7 +130,7 @@ module Datadog
130
130
  self.class._native_stop
131
131
  logger.debug('Crash tracking stopped successfully')
132
132
  rescue => e
133
- logger.error("Failed to stop crash tracking: #{e.class}: #{e}")
133
+ logger.error("Failed to stop crash tracking: #{e.class}: #{e.message}")
134
134
  end
135
135
 
136
136
  private
@@ -149,7 +149,7 @@ module Datadog
149
149
  )
150
150
  logger.debug("Crash tracking action: #{action} successful")
151
151
  rescue => e
152
- logger.error("Failed to #{action} crash tracking: #{e.class}: #{e}")
152
+ logger.error("Failed to #{action} crash tracking: #{e.class}: #{e.message}")
153
153
  end
154
154
  end
155
155
  end
@@ -52,7 +52,9 @@ module Datadog
52
52
  log_configuration!('CORE', data.to_json)
53
53
  end
54
54
  rescue => e
55
- logger.warn("Failed to collect core environment information: #{e} Location: #{Array(e.backtrace).first}")
55
+ logger.warn(
56
+ "Failed to collect core environment information: #{e.class}: #{e.message} Location: #{Array(e.backtrace).first}"
57
+ )
56
58
  end
57
59
  end
58
60
 
@@ -108,7 +108,7 @@ module Datadog
108
108
  end
109
109
  rescue => e
110
110
  Datadog.logger.debug(
111
- "Error while checking cgroup namespace. Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
111
+ "Error while checking cgroup namespace. Cause: #{e.class}: #{e.message} Location: #{Array(e.backtrace).first}"
112
112
  )
113
113
  false
114
114
  end
@@ -172,7 +172,7 @@ module Datadog
172
172
  @entry = Entry.new # Empty entry if no valid cgroup entry is found
173
173
  rescue => e
174
174
  Datadog.logger.debug(
175
- "Error while reading container entry. Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
175
+ "Error while reading container entry. Cause: #{e.class}: #{e.message} Location: #{Array(e.backtrace).first}"
176
176
  )
177
177
  @entry = Entry.new unless defined?(@entry)
178
178
  @entry