ddtrace 1.11.1 → 1.12.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +73 -1
- data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +6 -4
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +34 -16
- data/ext/ddtrace_profiling_native_extension/extconf.rb +19 -3
- data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +2 -2
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +38 -4
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +489 -133
- data/lib/datadog/appsec/assets/waf_rules/strict.json +2 -47
- data/lib/datadog/appsec/configuration/settings.rb +2 -10
- data/lib/datadog/appsec/configuration.rb +3 -9
- data/lib/datadog/appsec/contrib/rack/ext.rb +0 -1
- data/lib/datadog/appsec/contrib/rack/gateway/request.rb +17 -3
- data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +27 -45
- data/lib/datadog/appsec/contrib/rack/integration.rb +0 -5
- data/lib/datadog/appsec/contrib/rack/reactive/request.rb +7 -1
- data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +34 -26
- data/lib/datadog/appsec/contrib/rails/ext.rb +0 -1
- data/lib/datadog/appsec/contrib/rails/framework.rb +1 -13
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +9 -27
- data/lib/datadog/appsec/contrib/rails/integration.rb +0 -5
- data/lib/datadog/appsec/contrib/rails/patcher.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/ext.rb +0 -1
- data/lib/datadog/appsec/contrib/sinatra/framework.rb +1 -13
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +18 -36
- data/lib/datadog/appsec/contrib/sinatra/integration.rb +0 -5
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +5 -4
- data/lib/datadog/appsec/event.rb +37 -37
- data/lib/datadog/appsec/ext.rb +1 -0
- data/lib/datadog/appsec/extensions.rb +2 -6
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +9 -28
- data/lib/datadog/appsec/processor/rule_merger.rb +13 -7
- data/lib/datadog/appsec/processor.rb +0 -45
- data/lib/datadog/appsec/remote.rb +6 -0
- data/lib/datadog/appsec/response.rb +13 -9
- data/lib/datadog/appsec/scope.rb +61 -0
- data/lib/datadog/appsec.rb +6 -0
- data/lib/datadog/ci/ext/environment.rb +40 -4
- data/lib/datadog/core/configuration/settings.rb +74 -14
- data/lib/datadog/core/configuration.rb +5 -1
- data/lib/datadog/core/remote/client/capabilities.rb +1 -1
- data/lib/datadog/core/remote/client.rb +5 -1
- data/lib/datadog/core/telemetry/collector.rb +2 -1
- data/lib/datadog/core/telemetry/v1/dependency.rb +2 -1
- data/lib/datadog/kit/appsec/events.rb +58 -13
- data/lib/datadog/kit/identity.rb +29 -10
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +2 -0
- data/lib/datadog/profiling/component.rb +69 -29
- data/lib/datadog/profiling.rb +2 -1
- data/lib/datadog/tracing/buffer.rb +0 -1
- data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +9 -1
- data/lib/datadog/tracing/contrib/aws/ext.rb +11 -1
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +7 -0
- data/lib/datadog/tracing/contrib/aws/parsed_context.rb +4 -0
- data/lib/datadog/tracing/contrib/aws/service/base.rb +16 -0
- data/lib/datadog/tracing/contrib/aws/service/dynamodb.rb +22 -0
- data/lib/datadog/tracing/contrib/aws/service/eventbridge.rb +22 -0
- data/lib/datadog/tracing/contrib/aws/service/kinesis.rb +32 -0
- data/lib/datadog/tracing/contrib/aws/service/s3.rb +22 -0
- data/lib/datadog/tracing/contrib/aws/service/sns.rb +30 -0
- data/lib/datadog/tracing/contrib/aws/service/sqs.rb +27 -0
- data/lib/datadog/tracing/contrib/aws/service/states.rb +40 -0
- data/lib/datadog/tracing/contrib/aws/services.rb +18 -0
- data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +5 -2
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +4 -2
- data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +5 -2
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +5 -2
- data/lib/datadog/tracing/contrib/patcher.rb +0 -1
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +5 -2
- data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/presto/instrumentation.rb +4 -2
- data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +10 -2
- data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +9 -1
- data/lib/datadog/tracing/contrib/racecar/event.rb +3 -1
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +3 -1
- data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/redis/tags.rb +4 -1
- data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +6 -1
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +4 -1
- data/lib/datadog/tracing/contrib/roda/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/sequel/database.rb +4 -1
- data/lib/datadog/tracing/contrib/sequel/dataset.rb +4 -1
- data/lib/datadog/tracing/contrib/sequel/utils.rb +4 -1
- data/lib/datadog/tracing/contrib/status_code_matcher.rb +0 -1
- data/lib/datadog/tracing/correlation.rb +0 -1
- data/lib/datadog/tracing/distributed/headers/ext.rb +1 -1
- data/lib/datadog/tracing/event.rb +0 -2
- data/lib/datadog/tracing/pipeline.rb +0 -2
- data/lib/datadog/tracing/runtime/metrics.rb +0 -2
- data/lib/datadog/tracing/sampling/rate_by_service_sampler.rb +0 -1
- data/lib/datadog/tracing/sampling/rate_sampler.rb +0 -2
- data/lib/datadog/tracing/sampling/rule.rb +0 -2
- data/lib/datadog/tracing/sampling/rule_sampler.rb +0 -2
- data/lib/datadog/tracing/span_operation.rb +0 -1
- data/lib/datadog/tracing/sync_writer.rb +0 -2
- data/lib/datadog/tracing/trace_operation.rb +0 -1
- data/lib/datadog/tracing/tracer.rb +0 -1
- data/lib/datadog/tracing/workers/trace_writer.rb +0 -1
- data/lib/datadog/tracing/workers.rb +0 -2
- data/lib/datadog/tracing/writer.rb +0 -2
- data/lib/ddtrace/version.rb +1 -1
- metadata +18 -19
- data/lib/datadog/appsec/contrib/configuration/settings.rb +0 -20
- data/lib/datadog/appsec/contrib/rack/configuration/settings.rb +0 -22
- data/lib/datadog/appsec/contrib/rails/configuration/settings.rb +0 -22
- data/lib/datadog/appsec/contrib/sinatra/configuration/settings.rb +0 -22
@@ -36,30 +36,34 @@ module Datadog
|
|
36
36
|
Response.new(
|
37
37
|
status: 403,
|
38
38
|
headers: { 'Content-Type' => content_type },
|
39
|
-
body: [Datadog::AppSec::Assets.blocked(format:
|
39
|
+
body: [Datadog::AppSec::Assets.blocked(format: CONTENT_TYPE_TO_FORMAT[content_type])]
|
40
40
|
)
|
41
41
|
end
|
42
42
|
|
43
43
|
private
|
44
44
|
|
45
|
-
|
46
|
-
'text/plain' => :text,
|
47
|
-
'text/html' => :html,
|
45
|
+
CONTENT_TYPE_TO_FORMAT = {
|
48
46
|
'application/json' => :json,
|
47
|
+
'text/html' => :html,
|
48
|
+
'text/plain' => :text,
|
49
49
|
}.freeze
|
50
50
|
|
51
|
-
DEFAULT_CONTENT_TYPE = '
|
51
|
+
DEFAULT_CONTENT_TYPE = 'application/json'
|
52
52
|
|
53
53
|
def content_type(env)
|
54
54
|
return DEFAULT_CONTENT_TYPE unless env.key?('HTTP_ACCEPT')
|
55
55
|
|
56
|
-
|
56
|
+
accept_types = env['HTTP_ACCEPT'].split(',').map(&:strip)
|
57
57
|
|
58
|
-
accepted.
|
59
|
-
match = FORMAT_MAP.keys.find { |type| range === type }
|
58
|
+
accepted = accept_types.map { |m| Utils::HTTP::MediaRange.new(m) }.sort!.reverse!
|
60
59
|
|
61
|
-
|
60
|
+
accepted.each do |range|
|
61
|
+
type_match = CONTENT_TYPE_TO_FORMAT.keys.find { |type| range === type }
|
62
|
+
|
63
|
+
return type_match if type_match
|
62
64
|
end
|
65
|
+
|
66
|
+
DEFAULT_CONTENT_TYPE
|
63
67
|
rescue Datadog::AppSec::Utils::HTTP::MediaRange::ParseError
|
64
68
|
DEFAULT_CONTENT_TYPE
|
65
69
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'processor'
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module AppSec
|
7
|
+
# Capture context essential to consistently call processor and report via traces
|
8
|
+
class Scope
|
9
|
+
attr_reader :trace, :service_entry_span, :processor_context
|
10
|
+
|
11
|
+
def initialize(trace, service_entry_span, processor_context)
|
12
|
+
@trace = trace
|
13
|
+
@service_entry_span = service_entry_span
|
14
|
+
@processor_context = processor_context
|
15
|
+
end
|
16
|
+
|
17
|
+
def finalize
|
18
|
+
@processor_context.finalize
|
19
|
+
end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
def activate_scope(trace, service_entry_span, processor)
|
23
|
+
raise ActiveScopeError, 'another scope is active, nested scopes are not supported' if active_scope
|
24
|
+
|
25
|
+
context = Datadog::AppSec::Processor::Context.new(processor)
|
26
|
+
|
27
|
+
self.active_scope = new(trace, service_entry_span, context)
|
28
|
+
end
|
29
|
+
|
30
|
+
def deactivate_scope
|
31
|
+
raise InactiveScopeError, 'no scope is active, nested scopes are not supported' unless active_scope
|
32
|
+
|
33
|
+
scope = active_scope
|
34
|
+
|
35
|
+
reset_active_scope
|
36
|
+
|
37
|
+
scope.finalize
|
38
|
+
end
|
39
|
+
|
40
|
+
def active_scope
|
41
|
+
Thread.current[:datadog_appsec_active_scope]
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def active_scope=(scope)
|
47
|
+
raise ArgumentError, 'not a Datadog::AppSec::Scope' unless scope.instance_of?(Scope)
|
48
|
+
|
49
|
+
Thread.current[:datadog_appsec_active_scope] = scope
|
50
|
+
end
|
51
|
+
|
52
|
+
def reset_active_scope
|
53
|
+
Thread.current[:datadog_appsec_active_scope] = nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class InactiveScopeError < StandardError; end
|
58
|
+
class ActiveScopeError < StandardError; end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/datadog/appsec.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
require_relative 'appsec/configuration'
|
4
4
|
require_relative 'appsec/extensions'
|
5
|
+
require_relative 'appsec/scope'
|
6
|
+
require_relative 'appsec/ext'
|
5
7
|
|
6
8
|
module Datadog
|
7
9
|
# Namespace for Datadog AppSec instrumentation
|
@@ -13,6 +15,10 @@ module Datadog
|
|
13
15
|
Datadog.configuration.appsec.enabled
|
14
16
|
end
|
15
17
|
|
18
|
+
def active_scope
|
19
|
+
Datadog::AppSec::Scope.active_scope
|
20
|
+
end
|
21
|
+
|
16
22
|
def processor
|
17
23
|
appsec_component = components.appsec
|
18
24
|
|
@@ -19,6 +19,8 @@ module Datadog
|
|
19
19
|
TAG_PROVIDER_NAME = 'ci.provider.name'
|
20
20
|
TAG_STAGE_NAME = 'ci.stage.name'
|
21
21
|
TAG_WORKSPACE_PATH = 'ci.workspace_path'
|
22
|
+
TAG_NODE_LABELS = 'ci.node.labels'
|
23
|
+
TAG_NODE_NAME = 'ci.node.name'
|
22
24
|
TAG_CI_ENV_VARS = '_dd.ci.env_vars'
|
23
25
|
|
24
26
|
PROVIDERS = [
|
@@ -33,7 +35,8 @@ module Datadog
|
|
33
35
|
['JENKINS_URL', :extract_jenkins],
|
34
36
|
['TEAMCITY_VERSION', :extract_teamcity],
|
35
37
|
['TRAVIS', :extract_travis],
|
36
|
-
['BITRISE_BUILD_SLUG', :extract_bitrise]
|
38
|
+
['BITRISE_BUILD_SLUG', :extract_bitrise],
|
39
|
+
['CF_BUILD_ID', :extract_codefresh]
|
37
40
|
].freeze
|
38
41
|
|
39
42
|
module_function
|
@@ -196,7 +199,7 @@ module Datadog
|
|
196
199
|
end
|
197
200
|
|
198
201
|
def extract_buildkite(env)
|
199
|
-
{
|
202
|
+
tags = {
|
200
203
|
Core::Git::Ext::TAG_BRANCH => env['BUILDKITE_BRANCH'],
|
201
204
|
Core::Git::Ext::TAG_COMMIT_SHA => env['BUILDKITE_COMMIT'],
|
202
205
|
Core::Git::Ext::TAG_REPOSITORY_URL => env['BUILDKITE_REPO'],
|
@@ -211,11 +214,21 @@ module Datadog
|
|
211
214
|
Core::Git::Ext::TAG_COMMIT_AUTHOR_NAME => env['BUILDKITE_BUILD_AUTHOR'],
|
212
215
|
Core::Git::Ext::TAG_COMMIT_AUTHOR_EMAIL => env['BUILDKITE_BUILD_AUTHOR_EMAIL'],
|
213
216
|
Core::Git::Ext::TAG_COMMIT_MESSAGE => env['BUILDKITE_MESSAGE'],
|
217
|
+
TAG_NODE_NAME => env['BUILDKITE_AGENT_ID'],
|
214
218
|
TAG_CI_ENV_VARS => {
|
215
219
|
'BUILDKITE_BUILD_ID' => env['BUILDKITE_BUILD_ID'],
|
216
220
|
'BUILDKITE_JOB_ID' => env['BUILDKITE_JOB_ID']
|
217
221
|
}.to_json
|
218
222
|
}
|
223
|
+
|
224
|
+
extra_tags = env
|
225
|
+
.select { |key| key.start_with?('BUILDKITE_AGENT_META_DATA_') }
|
226
|
+
.map { |key, value| "#{key.to_s.sub('BUILDKITE_AGENT_META_DATA_', '').downcase}:#{value}" }
|
227
|
+
.sort_by(&:length)
|
228
|
+
|
229
|
+
tags[TAG_NODE_LABELS] = extra_tags.to_json unless extra_tags.empty?
|
230
|
+
|
231
|
+
tags
|
219
232
|
end
|
220
233
|
|
221
234
|
def extract_circle_ci(env)
|
@@ -274,7 +287,6 @@ module Datadog
|
|
274
287
|
def extract_gitlab(env)
|
275
288
|
commit_author_name, commit_author_email = extract_name_email(env['CI_COMMIT_AUTHOR'])
|
276
289
|
|
277
|
-
url = env['CI_PIPELINE_URL']
|
278
290
|
{
|
279
291
|
Core::Git::Ext::TAG_BRANCH => env['CI_COMMIT_REF_NAME'],
|
280
292
|
Core::Git::Ext::TAG_COMMIT_SHA => env['CI_COMMIT_SHA'],
|
@@ -289,9 +301,11 @@ module Datadog
|
|
289
301
|
TAG_PIPELINE_ID => env['CI_PIPELINE_ID'],
|
290
302
|
TAG_PIPELINE_NAME => env['CI_PROJECT_PATH'],
|
291
303
|
TAG_PIPELINE_NUMBER => env['CI_PIPELINE_IID'],
|
292
|
-
TAG_PIPELINE_URL =>
|
304
|
+
TAG_PIPELINE_URL => env['CI_PIPELINE_URL'],
|
293
305
|
TAG_PROVIDER_NAME => 'gitlab',
|
294
306
|
TAG_WORKSPACE_PATH => env['CI_PROJECT_DIR'],
|
307
|
+
TAG_NODE_LABELS => env['CI_RUNNER_TAGS'],
|
308
|
+
TAG_NODE_NAME => env['CI_RUNNER_ID'],
|
295
309
|
Core::Git::Ext::TAG_COMMIT_MESSAGE => env['CI_COMMIT_MESSAGE'],
|
296
310
|
TAG_CI_ENV_VARS => {
|
297
311
|
'CI_PROJECT_URL' => env['CI_PROJECT_URL'],
|
@@ -308,6 +322,9 @@ module Datadog
|
|
308
322
|
name = name.gsub("/#{normalize_ref(branch)}", '') if branch
|
309
323
|
name = name.split('/').reject { |v| v.nil? || v.include?('=') }.join('/')
|
310
324
|
end
|
325
|
+
|
326
|
+
node_labels = env['NODE_LABELS'].split.to_json unless env['NODE_LABELS'].nil?
|
327
|
+
|
311
328
|
{
|
312
329
|
Core::Git::Ext::TAG_BRANCH => branch,
|
313
330
|
Core::Git::Ext::TAG_COMMIT_SHA => env['GIT_COMMIT'],
|
@@ -319,6 +336,8 @@ module Datadog
|
|
319
336
|
TAG_PIPELINE_URL => env['BUILD_URL'],
|
320
337
|
TAG_PROVIDER_NAME => 'jenkins',
|
321
338
|
TAG_WORKSPACE_PATH => env['WORKSPACE'],
|
339
|
+
TAG_NODE_LABELS => node_labels,
|
340
|
+
TAG_NODE_NAME => env['NODE_NAME'],
|
322
341
|
TAG_CI_ENV_VARS => {
|
323
342
|
'DD_CUSTOM_TRACE_ID' => env['DD_CUSTOM_TRACE_ID']
|
324
343
|
}.to_json
|
@@ -380,6 +399,23 @@ module Datadog
|
|
380
399
|
}
|
381
400
|
end
|
382
401
|
|
402
|
+
def extract_codefresh(env)
|
403
|
+
branch, tag = branch_or_tag(env['CF_BRANCH'])
|
404
|
+
|
405
|
+
{
|
406
|
+
TAG_PROVIDER_NAME => 'codefresh',
|
407
|
+
TAG_PIPELINE_ID => env['CF_BUILD_ID'],
|
408
|
+
TAG_PIPELINE_NAME => env['CF_PIPELINE_NAME'],
|
409
|
+
TAG_PIPELINE_URL => env['CF_BUILD_URL'],
|
410
|
+
TAG_JOB_NAME => env['CF_STEP_NAME'],
|
411
|
+
Core::Git::Ext::TAG_BRANCH => branch,
|
412
|
+
Core::Git::Ext::TAG_TAG => tag,
|
413
|
+
TAG_CI_ENV_VARS => {
|
414
|
+
'CF_BUILD_ID' => env['CF_BUILD_ID'],
|
415
|
+
}.to_json
|
416
|
+
}
|
417
|
+
end
|
418
|
+
|
383
419
|
def extract_user_defined_git(env)
|
384
420
|
{
|
385
421
|
Core::Git::Ext::TAG_REPOSITORY_URL => env[Core::Git::Ext::ENV_REPOSITORY_URL],
|
@@ -154,6 +154,9 @@ module Datadog
|
|
154
154
|
# @default `DD_ENV` environment variable, otherwise `nil`
|
155
155
|
# @return [String,nil]
|
156
156
|
option :env do |o|
|
157
|
+
# DEV-2.0: Remove this conversion for symbol.
|
158
|
+
o.setter { |v| v.to_s if v }
|
159
|
+
|
157
160
|
# NOTE: env also gets set as a side effect of tags. See the WORKAROUND note in #initialize for details.
|
158
161
|
o.default { ENV.fetch(Core::Environment::Ext::ENV_ENVIRONMENT, nil) }
|
159
162
|
o.lazy
|
@@ -202,12 +205,23 @@ module Datadog
|
|
202
205
|
|
203
206
|
# @public_api
|
204
207
|
settings :advanced do
|
208
|
+
# @deprecated This setting is ignored when CPU Profiling 2.0 is in use, and will be removed on dd-trace-rb 2.0.
|
209
|
+
#
|
205
210
|
# This should never be reduced, as it can cause the resulting profiles to become biased.
|
206
211
|
# The default should be enough for most services, allowing 16 threads to be sampled around 30 times
|
207
212
|
# per second for a 60 second period.
|
208
|
-
|
209
|
-
|
210
|
-
|
213
|
+
option :max_events do |o|
|
214
|
+
o.default 32768
|
215
|
+
o.on_set do |value|
|
216
|
+
if value != 32768
|
217
|
+
Datadog.logger.warn(
|
218
|
+
'The profiling.advanced.max_events setting has been deprecated for removal. It no longer does ' \
|
219
|
+
'anything unless you the `force_enable_legacy_profiler` option is in use. ' \
|
220
|
+
'Please remove it from your Datadog.configure block.'
|
221
|
+
)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
211
225
|
|
212
226
|
# Controls the maximum number of frames for each thread sampled. Can be tuned to avoid omitted frames in the
|
213
227
|
# produced profiles. Increasing this may increase the overhead of profiling.
|
@@ -250,28 +264,39 @@ module Datadog
|
|
250
264
|
end
|
251
265
|
end
|
252
266
|
|
253
|
-
#
|
254
|
-
#
|
255
|
-
# Note that setting this to "false" (or not setting it) will not prevent the new profiler from
|
256
|
-
# being automatically used.
|
257
|
-
# This option will be deprecated for removal once the legacy profiler is removed.
|
267
|
+
# @deprecated No longer does anything, and will be removed on dd-trace-rb 2.0.
|
258
268
|
#
|
259
|
-
#
|
269
|
+
# This was used prior to the GA of the new CPU Profiling 2.0 profiler. Using CPU Profiling 2.0 is now the
|
270
|
+
# default and this doesn't do anything.
|
260
271
|
option :force_enable_new_profiler do |o|
|
261
|
-
o.
|
262
|
-
|
272
|
+
o.on_set do
|
273
|
+
Datadog.logger.warn(
|
274
|
+
'The profiling.advanced.force_enable_new_profiler setting has been deprecated for removal and no ' \
|
275
|
+
'longer does anything. Please remove it from your Datadog.configure block.'
|
276
|
+
)
|
277
|
+
end
|
263
278
|
end
|
264
279
|
|
265
|
-
#
|
280
|
+
# @deprecated Will be removed for dd-trace-rb 2.0.
|
266
281
|
#
|
267
|
-
#
|
282
|
+
# Forces enabling the *legacy* non-CPU Profiling 2.0 profiler.
|
268
283
|
# Do not use unless instructed to by support.
|
269
|
-
# This option will be deprecated for removal once the legacy profiler is removed.
|
270
284
|
#
|
271
285
|
# @default `DD_PROFILING_FORCE_ENABLE_LEGACY` environment variable, otherwise `false`
|
272
286
|
option :force_enable_legacy_profiler do |o|
|
273
287
|
o.default { env_to_bool('DD_PROFILING_FORCE_ENABLE_LEGACY', false) }
|
274
288
|
o.lazy
|
289
|
+
o.on_set do |value|
|
290
|
+
if value
|
291
|
+
Datadog.logger.warn(
|
292
|
+
'The profiling.advanced.force_enable_legacy_profiler setting has been deprecated for removal. ' \
|
293
|
+
'Do not use unless instructed to by support. ' \
|
294
|
+
'If you needed to use it due to incompatibilities with the CPU Profiling 2.0 profiler, consider ' \
|
295
|
+
'using the profiling.advanced.no_signals_workaround_enabled setting instead. ' \
|
296
|
+
'See <https://dtdg.co/ruby-profiler-troubleshooting> for details.'
|
297
|
+
)
|
298
|
+
end
|
299
|
+
end
|
275
300
|
end
|
276
301
|
|
277
302
|
# Forces enabling of profiling of time/resources spent in Garbage Collection.
|
@@ -317,6 +342,30 @@ module Datadog
|
|
317
342
|
o.default { env_to_bool('DD_PROFILING_SKIP_MYSQL2_CHECK', false) }
|
318
343
|
o.lazy
|
319
344
|
end
|
345
|
+
|
346
|
+
# The profiler gathers data by sending `SIGPROF` unix signals to Ruby application threads.
|
347
|
+
#
|
348
|
+
# Sending `SIGPROF` is a common profiling approach, and may cause system calls from native
|
349
|
+
# extensions/libraries to be interrupted with a system
|
350
|
+
# [EINTR error code.](https://man7.org/linux/man-pages/man7/signal.7.html#:~:text=Interruption%20of%20system%20calls%20and%20library%20functions%20by%20signal%20handlers)
|
351
|
+
# Rarely, native extensions or libraries called by them may have missing or incorrect error handling for the
|
352
|
+
# `EINTR` error code.
|
353
|
+
#
|
354
|
+
# The "no signals" workaround, when enabled, enables an alternative mode for the profiler where it does not
|
355
|
+
# send `SIGPROF` unix signals. The downside of this approach is that the profiler data will have lower
|
356
|
+
# quality.
|
357
|
+
#
|
358
|
+
# This workaround is automatically enabled when gems that are known to have issues handling
|
359
|
+
# `EINTR` error codes are detected. If you suspect you may be seeing an issue due to the profiler's use of
|
360
|
+
# signals, you can try manually enabling this mode as a fallback.
|
361
|
+
# Please also report these issues to us on <https://github.com/DataDog/dd-trace-rb/issues/new>, so we can
|
362
|
+
# work with the gem authors to fix them!
|
363
|
+
#
|
364
|
+
# @default `DD_PROFILING_NO_SIGNALS_WORKAROUND_ENABLED` environment variable as a boolean, otherwise `:auto`
|
365
|
+
option :no_signals_workaround_enabled do |o|
|
366
|
+
o.default { env_to_bool('DD_PROFILING_NO_SIGNALS_WORKAROUND_ENABLED', :auto) }
|
367
|
+
o.lazy
|
368
|
+
end
|
320
369
|
end
|
321
370
|
|
322
371
|
# @public_api
|
@@ -353,6 +402,9 @@ module Datadog
|
|
353
402
|
# @default `DD_SERVICE` environment variable, otherwise the program name (e.g. `'ruby'`, `'rails'`, `'pry'`)
|
354
403
|
# @return [String]
|
355
404
|
option :service do |o|
|
405
|
+
# DEV-2.0: Remove this conversion for symbol.
|
406
|
+
o.setter { |v| v.to_s if v }
|
407
|
+
|
356
408
|
# NOTE: service also gets set as a side effect of tags. See the WORKAROUND note in #initialize for details.
|
357
409
|
o.default { ENV.fetch(Core::Environment::Ext::ENV_SERVICE, Core::Environment::Ext::FALLBACK_SERVICE_NAME) }
|
358
410
|
o.lazy
|
@@ -497,6 +549,14 @@ module Datadog
|
|
497
549
|
o.default { env_to_float(Core::Remote::Ext::ENV_POLL_INTERVAL_SECONDS, 5.0) }
|
498
550
|
o.lazy
|
499
551
|
end
|
552
|
+
|
553
|
+
# Declare service name to bind to remote configuration. Use when
|
554
|
+
# DD_SERVICE does not match the correct integration for which remote
|
555
|
+
# configuration applies.
|
556
|
+
#
|
557
|
+
# @default `nil`.
|
558
|
+
# @return [String,nil]
|
559
|
+
option :service
|
500
560
|
end
|
501
561
|
|
502
562
|
# TODO: Tracing should manage its own settings.
|
@@ -208,7 +208,11 @@ module Datadog
|
|
208
208
|
# Used internally to ensure a clean environment between test runs.
|
209
209
|
def reset!
|
210
210
|
safely_synchronize do |write_components|
|
211
|
-
|
211
|
+
if components?
|
212
|
+
@components.shutdown!
|
213
|
+
@temp_logger = nil # Reset to ensure instance and log level are reset for next run
|
214
|
+
end
|
215
|
+
|
212
216
|
write_components.call(nil)
|
213
217
|
configuration.reset!
|
214
218
|
end
|
@@ -23,7 +23,7 @@ module Datadog
|
|
23
23
|
private
|
24
24
|
|
25
25
|
def register(settings)
|
26
|
-
if settings.appsec.enabled
|
26
|
+
if settings.respond_to?(:appsec) && settings.appsec.enabled
|
27
27
|
register_capabilities(Datadog::AppSec::Remote.capabilities)
|
28
28
|
register_products(Datadog::AppSec::Remote.products)
|
29
29
|
register_receivers(Datadog::AppSec::Remote.receivers)
|
@@ -136,7 +136,7 @@ module Datadog
|
|
136
136
|
runtime_id: Core::Environment::Identity.id,
|
137
137
|
language: Core::Environment::Identity.lang,
|
138
138
|
tracer_version: tracer_version_semver2,
|
139
|
-
service:
|
139
|
+
service: service_name,
|
140
140
|
env: Datadog.configuration.env,
|
141
141
|
tags: client_tracer_tags,
|
142
142
|
}
|
@@ -167,6 +167,10 @@ module Datadog
|
|
167
167
|
}
|
168
168
|
end
|
169
169
|
|
170
|
+
def service_name
|
171
|
+
Datadog.configuration.remote.service || Datadog.configuration.service
|
172
|
+
end
|
173
|
+
|
170
174
|
def tracer_version_semver2
|
171
175
|
@tracer_version_semver2 ||= Core::Environment::Identity.tracer_version_semver2
|
172
176
|
end
|
@@ -56,7 +56,8 @@ module Datadog
|
|
56
56
|
def dependencies
|
57
57
|
Gem.loaded_specs.collect do |name, loaded_gem|
|
58
58
|
Datadog::Core::Telemetry::V1::Dependency.new(
|
59
|
-
|
59
|
+
# `hash` should be used when `version` is not available
|
60
|
+
name: name, version: loaded_gem.version.to_s, hash: nil
|
60
61
|
)
|
61
62
|
end
|
62
63
|
end
|
@@ -17,9 +17,10 @@ module Datadog
|
|
17
17
|
|
18
18
|
# @param name [String] Module name
|
19
19
|
# @param version [String] Version of resolved module
|
20
|
-
# @param hash [String] Dependency hash
|
20
|
+
# @param hash [String] Dependency hash, in case `version` is not available
|
21
21
|
def initialize(name:, version: nil, hash: nil)
|
22
22
|
raise ArgumentError, ERROR_NIL_NAME_MESSAGE if name.nil?
|
23
|
+
raise ArgumentError, 'if both :version and :hash exist, use :version only' if version && hash
|
23
24
|
|
24
25
|
@hash = hash
|
25
26
|
@name = name
|
@@ -14,38 +14,68 @@ module Datadog
|
|
14
14
|
#
|
15
15
|
# This method is experimental and may change in the future.
|
16
16
|
#
|
17
|
-
# @param trace [TraceOperation] Trace to attach data to.
|
17
|
+
# @param trace [TraceOperation] Trace to attach data to. Defaults to
|
18
|
+
# active trace.
|
19
|
+
# @param span [SpanOperation] Span to attach data to. Defaults to
|
20
|
+
# active span on trace. Note that this should be a service entry span.
|
21
|
+
# When AppSec is enabled, the expected span and trace are automatically
|
22
|
+
# used as defaults.
|
18
23
|
# @param user [Hash<Symbol, String>] User information to pass to
|
19
24
|
# Datadog::Kit::Identity.set_user. Must contain at least :id as key.
|
20
25
|
# @param others [Hash<String || Symbol, String>] Additional free-form
|
21
26
|
# event information to attach to the trace.
|
22
|
-
def self.track_login_success(trace, user:, **others)
|
23
|
-
|
27
|
+
def self.track_login_success(trace = nil, span = nil, user:, **others)
|
28
|
+
if (appsec_scope = Datadog::AppSec.active_scope)
|
29
|
+
trace = appsec_scope.trace
|
30
|
+
span = appsec_scope.service_entry_span
|
31
|
+
end
|
32
|
+
|
33
|
+
trace ||= Datadog::Tracing.active_trace
|
34
|
+
span ||= trace.active_span || Datadog::Tracing.active_span
|
35
|
+
|
36
|
+
raise ArgumentError, "span #{span.span_id} does not belong to trace #{trace.id}" if trace.id != span.trace_id
|
37
|
+
|
38
|
+
track(LOGIN_SUCCESS_EVENT, trace, span, **others)
|
24
39
|
|
25
40
|
user_options = user.dup
|
26
41
|
user_id = user_options.delete(:id)
|
27
42
|
|
28
43
|
raise ArgumentError, 'missing required key: :user => { :id }' if user_id.nil?
|
29
44
|
|
30
|
-
Kit::Identity.set_user(trace, id: user_id, **user_options)
|
45
|
+
Kit::Identity.set_user(trace, span, id: user_id, **user_options)
|
31
46
|
end
|
32
47
|
|
33
48
|
# Attach login failure event information to the trace
|
34
49
|
#
|
35
50
|
# This method is experimental and may change in the future.
|
36
51
|
#
|
37
|
-
# @param trace [TraceOperation] Trace to attach data to.
|
52
|
+
# @param trace [TraceOperation] Trace to attach data to. Defaults to
|
53
|
+
# active trace.
|
54
|
+
# @param span [SpanOperation] Span to attach data to. Defaults to
|
55
|
+
# active span on trace. Note that this should be a service entry span.
|
56
|
+
# When AppSec is enabled, the expected span and trace are automatically
|
57
|
+
# used as defaults.
|
38
58
|
# @param user_id [String] User id that attempted login
|
39
59
|
# @param user_exists [bool] Whether the user id that did a login attempt exists.
|
40
60
|
# @param others [Hash<String || Symbol, String>] Additional free-form
|
41
61
|
# event information to attach to the trace.
|
42
|
-
def self.track_login_failure(trace, user_id:, user_exists:, **others)
|
43
|
-
|
62
|
+
def self.track_login_failure(trace = nil, span = nil, user_id:, user_exists:, **others)
|
63
|
+
if (appsec_scope = Datadog::AppSec.active_scope)
|
64
|
+
trace = appsec_scope.trace
|
65
|
+
span = appsec_scope.service_entry_span
|
66
|
+
end
|
67
|
+
|
68
|
+
trace ||= Datadog::Tracing.active_trace
|
69
|
+
span ||= trace.active_span || Datadog::Tracing.active_span
|
70
|
+
|
71
|
+
raise ArgumentError, "span #{span.span_id} does not belong to trace #{trace.id}" if trace.id != span.trace_id
|
72
|
+
|
73
|
+
track(LOGIN_FAILURE_EVENT, trace, span, **others)
|
44
74
|
|
45
75
|
raise ArgumentError, 'user_id cannot be nil' if user_id.nil?
|
46
76
|
|
47
|
-
|
48
|
-
|
77
|
+
span.set_tag('appsec.events.users.login.failure.usr.id', user_id)
|
78
|
+
span.set_tag('appsec.events.users.login.failure.usr.exists', user_exists)
|
49
79
|
end
|
50
80
|
|
51
81
|
# Attach custom event information to the trace
|
@@ -53,17 +83,32 @@ module Datadog
|
|
53
83
|
# This method is experimental and may change in the future.
|
54
84
|
#
|
55
85
|
# @param event [String] Mandatory. Event code.
|
56
|
-
# @param trace [TraceOperation] Trace to attach data to.
|
86
|
+
# @param trace [TraceOperation] Trace to attach data to. Defaults to
|
87
|
+
# active trace.
|
88
|
+
# @param span [SpanOperation] Span to attach data to. Defaults to
|
89
|
+
# active span on trace. Note that this should be a service entry span.
|
90
|
+
# When AppSec is enabled, the expected span and trace are automatically
|
91
|
+
# used as defaults.
|
57
92
|
# @param others [Hash<Symbol, String>] Additional free-form
|
58
93
|
# event information to attach to the trace. Key must not
|
59
94
|
# be :track.
|
60
|
-
def self.track(event, trace, **others)
|
61
|
-
|
95
|
+
def self.track(event, trace = nil, span = nil, **others)
|
96
|
+
if (appsec_scope = Datadog::AppSec.active_scope)
|
97
|
+
trace = appsec_scope.trace
|
98
|
+
span = appsec_scope.service_entry_span
|
99
|
+
end
|
100
|
+
|
101
|
+
trace ||= Datadog::Tracing.active_trace
|
102
|
+
span ||= trace.active_span || Datadog::Tracing.active_span
|
103
|
+
|
104
|
+
raise ArgumentError, "span #{span.span_id} does not belong to trace #{trace.id}" if trace.id != span.trace_id
|
105
|
+
|
106
|
+
span.set_tag("appsec.events.#{event}.track", 'true')
|
62
107
|
|
63
108
|
others.each do |k, v|
|
64
109
|
raise ArgumentError, 'key cannot be :track' if k.to_sym == :track
|
65
110
|
|
66
|
-
|
111
|
+
span.set_tag("appsec.events.#{event}.#{k}", v) unless v.nil?
|
67
112
|
end
|
68
113
|
|
69
114
|
trace.keep!
|
data/lib/datadog/kit/identity.rb
CHANGED
@@ -8,7 +8,12 @@ module Datadog
|
|
8
8
|
module Identity
|
9
9
|
# Attach user information to the trace
|
10
10
|
#
|
11
|
-
# @param trace [TraceOperation] Trace to attach data to.
|
11
|
+
# @param trace [TraceOperation] Trace to attach data to. Defaults to
|
12
|
+
# active trace.
|
13
|
+
# @param span [SpanOperation] Span to attach data to. Defaults to
|
14
|
+
# active span on trace. Note that this should be a service entry span.
|
15
|
+
# When AppSec is enabled, the expected span and trace are automatically
|
16
|
+
# used as defaults.
|
12
17
|
# @param id [String] Mandatory. Username or client id extracted
|
13
18
|
# from the access token or Authorization header in the inbound request
|
14
19
|
# from outside the system.
|
@@ -29,7 +34,10 @@ module Datadog
|
|
29
34
|
#
|
30
35
|
# rubocop:disable Metrics/CyclomaticComplexity
|
31
36
|
# rubocop:disable Metrics/PerceivedComplexity
|
32
|
-
|
37
|
+
# rubocop:disable Metrics/AbcSize
|
38
|
+
def self.set_user(
|
39
|
+
trace = nil, span = nil, id:, email: nil, name: nil, session_id: nil, role: nil, scope: nil, **others
|
40
|
+
)
|
33
41
|
raise ArgumentError, 'missing required key: :id' if id.nil?
|
34
42
|
|
35
43
|
# enforce types
|
@@ -45,24 +53,35 @@ module Datadog
|
|
45
53
|
raise TypeError, "#{k.inspect} must be a String" unless v.nil? || v.is_a?(String)
|
46
54
|
end
|
47
55
|
|
56
|
+
if (appsec_scope = Datadog::AppSec.active_scope)
|
57
|
+
trace = appsec_scope.trace
|
58
|
+
span = appsec_scope.service_entry_span
|
59
|
+
end
|
60
|
+
|
61
|
+
trace ||= Datadog::Tracing.active_trace
|
62
|
+
span ||= trace.active_span || Datadog::Tracing.active_span
|
63
|
+
|
64
|
+
raise ArgumentError, "span #{span.span_id} does not belong to trace #{trace.id}" if trace.id != span.trace_id
|
65
|
+
|
48
66
|
# set tags once data is known consistent
|
49
67
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
68
|
+
span.set_tag('usr.id', id)
|
69
|
+
span.set_tag('usr.email', email) unless email.nil?
|
70
|
+
span.set_tag('usr.name', name) unless name.nil?
|
71
|
+
span.set_tag('usr.session_id', session_id) unless session_id.nil?
|
72
|
+
span.set_tag('usr.role', role) unless role.nil?
|
73
|
+
span.set_tag('usr.scope', scope) unless scope.nil?
|
56
74
|
|
57
75
|
others.each do |k, v|
|
58
|
-
|
76
|
+
span.set_tag("usr.#{k}", v) unless v.nil?
|
59
77
|
end
|
60
78
|
|
61
|
-
if
|
79
|
+
if appsec_scope
|
62
80
|
user = ::Datadog::AppSec::Instrumentation::Gateway::User.new(id)
|
63
81
|
::Datadog::AppSec::Instrumentation.gateway.push('identity.set_user', user)
|
64
82
|
end
|
65
83
|
end
|
84
|
+
# rubocop:enable Metrics/AbcSize
|
66
85
|
# rubocop:enable Metrics/PerceivedComplexity
|
67
86
|
# rubocop:enable Metrics/CyclomaticComplexity
|
68
87
|
end
|
@@ -20,6 +20,7 @@ module Datadog
|
|
20
20
|
endpoint_collection_enabled:,
|
21
21
|
gc_profiling_enabled:,
|
22
22
|
allocation_counting_enabled:,
|
23
|
+
no_signals_workaround_enabled:,
|
23
24
|
thread_context_collector: ThreadContext.new(
|
24
25
|
recorder: recorder,
|
25
26
|
max_frames: max_frames,
|
@@ -43,6 +44,7 @@ module Datadog
|
|
43
44
|
gc_profiling_enabled,
|
44
45
|
idle_sampling_helper,
|
45
46
|
allocation_counting_enabled,
|
47
|
+
no_signals_workaround_enabled,
|
46
48
|
dynamic_sampling_rate_enabled,
|
47
49
|
)
|
48
50
|
@worker_thread = nil
|