datadog 2.8.0 → 2.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +36 -1
- data/ext/datadog_profiling_native_extension/clock_id.h +2 -2
- data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +64 -54
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
- data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +1 -1
- data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +16 -16
- data/ext/datadog_profiling_native_extension/collectors_stack.c +7 -7
- data/ext/datadog_profiling_native_extension/collectors_thread_context.c +219 -122
- data/ext/datadog_profiling_native_extension/heap_recorder.h +1 -1
- data/ext/datadog_profiling_native_extension/http_transport.c +4 -4
- data/ext/datadog_profiling_native_extension/private_vm_api_access.c +3 -0
- data/ext/datadog_profiling_native_extension/private_vm_api_access.h +3 -1
- data/ext/datadog_profiling_native_extension/profiling.c +10 -8
- data/ext/datadog_profiling_native_extension/ruby_helpers.c +8 -8
- data/ext/datadog_profiling_native_extension/stack_recorder.c +54 -54
- data/ext/datadog_profiling_native_extension/stack_recorder.h +1 -1
- data/ext/datadog_profiling_native_extension/time_helpers.h +1 -1
- data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +47 -0
- data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +31 -0
- data/ext/libdatadog_api/crashtracker.c +3 -0
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +355 -157
- data/lib/datadog/appsec/assets/waf_rules/strict.json +62 -32
- data/lib/datadog/appsec/context.rb +54 -0
- data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +7 -7
- data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +6 -6
- data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +4 -4
- data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +19 -28
- data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +5 -5
- data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +64 -96
- data/lib/datadog/appsec/contrib/rack/reactive/request.rb +10 -10
- data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +5 -5
- data/lib/datadog/appsec/contrib/rack/reactive/response.rb +6 -6
- data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +10 -11
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +43 -49
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +21 -32
- data/lib/datadog/appsec/contrib/rails/patcher.rb +1 -1
- data/lib/datadog/appsec/contrib/rails/reactive/action.rb +6 -6
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +41 -63
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +2 -2
- data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +5 -5
- data/lib/datadog/appsec/event.rb +6 -6
- data/lib/datadog/appsec/ext.rb +3 -1
- data/lib/datadog/appsec/monitor/gateway/watcher.rb +22 -32
- data/lib/datadog/appsec/monitor/reactive/set_user.rb +5 -5
- data/lib/datadog/appsec/processor/rule_loader.rb +0 -3
- data/lib/datadog/appsec.rb +3 -3
- data/lib/datadog/auto_instrument.rb +3 -0
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +39 -11
- data/lib/datadog/core/configuration/components.rb +4 -2
- data/lib/datadog/core/configuration.rb +1 -1
- data/lib/datadog/{tracing → core}/contrib/rails/utils.rb +1 -3
- data/lib/datadog/core/crashtracking/component.rb +1 -3
- data/lib/datadog/core/telemetry/event.rb +87 -3
- data/lib/datadog/core/telemetry/logging.rb +2 -2
- data/lib/datadog/core/telemetry/metric.rb +22 -0
- data/lib/datadog/core/telemetry/worker.rb +33 -0
- data/lib/datadog/di/base.rb +115 -0
- data/lib/datadog/di/code_tracker.rb +7 -4
- data/lib/datadog/di/component.rb +17 -11
- data/lib/datadog/di/configuration/settings.rb +11 -1
- data/lib/datadog/di/contrib/railtie.rb +15 -0
- data/lib/datadog/di/contrib.rb +26 -0
- data/lib/datadog/di/error.rb +5 -0
- data/lib/datadog/di/instrumenter.rb +39 -18
- data/lib/datadog/di/{init.rb → preload.rb} +2 -4
- data/lib/datadog/di/probe_manager.rb +4 -4
- data/lib/datadog/di/probe_notification_builder.rb +16 -2
- data/lib/datadog/di/probe_notifier_worker.rb +5 -6
- data/lib/datadog/di/remote.rb +4 -4
- data/lib/datadog/di/transport.rb +2 -4
- data/lib/datadog/di.rb +5 -108
- data/lib/datadog/kit/appsec/events.rb +3 -3
- data/lib/datadog/kit/identity.rb +4 -4
- data/lib/datadog/profiling/component.rb +55 -53
- data/lib/datadog/profiling/http_transport.rb +1 -26
- data/lib/datadog/tracing/contrib/action_cable/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/action_mailer/integration.rb +6 -2
- data/lib/datadog/tracing/contrib/action_pack/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/action_view/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/active_job/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/active_record/integration.rb +6 -2
- data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +3 -1
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +3 -1
- data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +10 -0
- data/lib/datadog/tracing/contrib/active_support/integration.rb +5 -2
- data/lib/datadog/tracing/contrib/auto_instrument.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/httprb/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/kafka/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/mongodb/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/opensearch/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/presto/integration.rb +3 -0
- data/lib/datadog/tracing/contrib/rack/integration.rb +2 -2
- data/lib/datadog/tracing/contrib/rails/framework.rb +2 -2
- data/lib/datadog/tracing/contrib/rails/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/rest_client/integration.rb +3 -0
- data/lib/datadog/tracing/span.rb +12 -4
- data/lib/datadog/tracing/span_event.rb +123 -3
- data/lib/datadog/tracing/span_operation.rb +6 -0
- data/lib/datadog/tracing/transport/serializable_trace.rb +24 -6
- data/lib/datadog/version.rb +1 -1
- metadata +19 -10
- data/lib/datadog/appsec/reactive/operation.rb +0 -68
- data/lib/datadog/appsec/scope.rb +0 -58
- data/lib/datadog/core/crashtracking/agent_base_url.rb +0 -21
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../../../instrumentation/gateway'
|
4
|
-
require_relative '../../../reactive/
|
4
|
+
require_relative '../../../reactive/engine'
|
5
5
|
require_relative '../../rack/reactive/request_body'
|
6
6
|
require_relative '../reactive/routed'
|
7
7
|
require_relative '../../../event'
|
@@ -23,85 +23,63 @@ module Datadog
|
|
23
23
|
|
24
24
|
def watch_request_dispatch(gateway = Instrumentation.gateway)
|
25
25
|
gateway.watch('sinatra.request.dispatch', :appsec) do |stack, gateway_request|
|
26
|
-
block = false
|
27
|
-
|
28
26
|
event = nil
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
27
|
+
context = gateway_request.env[Datadog::AppSec::Ext::CONTEXT_KEY]
|
28
|
+
engine = AppSec::Reactive::Engine.new
|
29
|
+
|
30
|
+
Rack::Reactive::RequestBody.subscribe(engine, context) do |result|
|
31
|
+
if result.status == :match
|
32
|
+
# TODO: should this hash be an Event instance instead?
|
33
|
+
event = {
|
34
|
+
waf_result: result,
|
35
|
+
trace: context.trace,
|
36
|
+
span: context.span,
|
37
|
+
request: gateway_request,
|
38
|
+
actions: result.actions
|
39
|
+
}
|
40
|
+
|
41
|
+
# We want to keep the trace in case of security event
|
42
|
+
context.trace.keep! if context.trace
|
43
|
+
Datadog::AppSec::Event.tag_and_keep!(context, result)
|
44
|
+
context.waf_runner.events << event
|
48
45
|
end
|
49
|
-
|
50
|
-
block = Rack::Reactive::RequestBody.publish(op, gateway_request)
|
51
46
|
end
|
52
47
|
|
48
|
+
block = Rack::Reactive::RequestBody.publish(engine, gateway_request)
|
53
49
|
next [nil, [[:block, event]]] if block
|
54
50
|
|
55
|
-
|
56
|
-
|
57
|
-
if event
|
58
|
-
res ||= []
|
59
|
-
res << [:monitor, event]
|
60
|
-
end
|
61
|
-
|
62
|
-
[ret, res]
|
51
|
+
stack.call(gateway_request.request)
|
63
52
|
end
|
64
53
|
end
|
65
54
|
|
66
55
|
def watch_request_routed(gateway = Instrumentation.gateway)
|
67
56
|
gateway.watch('sinatra.request.routed', :appsec) do |stack, (gateway_request, gateway_route_params)|
|
68
|
-
block = false
|
69
|
-
|
70
57
|
event = nil
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
58
|
+
context = gateway_request.env[Datadog::AppSec::Ext::CONTEXT_KEY]
|
59
|
+
engine = AppSec::Reactive::Engine.new
|
60
|
+
|
61
|
+
Sinatra::Reactive::Routed.subscribe(engine, context) do |result|
|
62
|
+
if result.status == :match
|
63
|
+
# TODO: should this hash be an Event instance instead?
|
64
|
+
event = {
|
65
|
+
waf_result: result,
|
66
|
+
trace: context.trace,
|
67
|
+
span: context.span,
|
68
|
+
request: gateway_request,
|
69
|
+
actions: result.actions
|
70
|
+
}
|
71
|
+
|
72
|
+
# We want to keep the trace in case of security event
|
73
|
+
context.trace.keep! if context.trace
|
74
|
+
Datadog::AppSec::Event.tag_and_keep!(context, result)
|
75
|
+
context.waf_runner.events << event
|
90
76
|
end
|
91
|
-
|
92
|
-
block = Sinatra::Reactive::Routed.publish(op, [gateway_request, gateway_route_params])
|
93
77
|
end
|
94
78
|
|
79
|
+
block = Sinatra::Reactive::Routed.publish(engine, [gateway_request, gateway_route_params])
|
95
80
|
next [nil, [[:block, event]]] if block
|
96
81
|
|
97
|
-
|
98
|
-
|
99
|
-
if event
|
100
|
-
res ||= []
|
101
|
-
res << [:monitor, event]
|
102
|
-
end
|
103
|
-
|
104
|
-
[ret, res]
|
82
|
+
stack.call(gateway_request.request)
|
105
83
|
end
|
106
84
|
end
|
107
85
|
end
|
@@ -54,7 +54,7 @@ module Datadog
|
|
54
54
|
def dispatch!
|
55
55
|
env = @request.env
|
56
56
|
|
57
|
-
context = env[Datadog::AppSec::Ext::
|
57
|
+
context = env[Datadog::AppSec::Ext::CONTEXT_KEY]
|
58
58
|
|
59
59
|
return super unless context
|
60
60
|
|
@@ -86,7 +86,7 @@ module Datadog
|
|
86
86
|
def process_route(*)
|
87
87
|
env = @request.env
|
88
88
|
|
89
|
-
context = env[Datadog::AppSec::Ext::
|
89
|
+
context = env[Datadog::AppSec::Ext::CONTEXT_KEY]
|
90
90
|
|
91
91
|
return super unless context
|
92
92
|
|
@@ -12,18 +12,18 @@ module Datadog
|
|
12
12
|
].freeze
|
13
13
|
private_constant :ADDRESSES
|
14
14
|
|
15
|
-
def self.publish(
|
15
|
+
def self.publish(engine, data)
|
16
16
|
_request, route_params = data
|
17
17
|
|
18
18
|
catch(:block) do
|
19
|
-
|
19
|
+
engine.publish('sinatra.request.route_params', route_params.params)
|
20
20
|
|
21
21
|
nil
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
def self.subscribe(
|
26
|
-
|
25
|
+
def self.subscribe(engine, context)
|
26
|
+
engine.subscribe(*ADDRESSES) do |*values|
|
27
27
|
Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" }
|
28
28
|
path_params = values[0]
|
29
29
|
|
@@ -32,7 +32,7 @@ module Datadog
|
|
32
32
|
}
|
33
33
|
|
34
34
|
waf_timeout = Datadog.configuration.appsec.waf_timeout
|
35
|
-
result =
|
35
|
+
result = context.run_waf(persistent_data, {}, waf_timeout)
|
36
36
|
|
37
37
|
next if result.status != :match
|
38
38
|
|
data/lib/datadog/appsec/event.rb
CHANGED
@@ -137,16 +137,16 @@ module Datadog
|
|
137
137
|
end
|
138
138
|
# rubocop:enable Metrics/MethodLength
|
139
139
|
|
140
|
-
def tag_and_keep!(
|
140
|
+
def tag_and_keep!(context, waf_result)
|
141
141
|
# We want to keep the trace in case of security event
|
142
|
-
|
142
|
+
context.trace.keep! if context.trace
|
143
143
|
|
144
|
-
if
|
145
|
-
|
146
|
-
|
144
|
+
if context.span
|
145
|
+
context.span.set_tag('appsec.blocked', 'true') if waf_result.actions.key?('block_request')
|
146
|
+
context.span.set_tag('appsec.event', 'true')
|
147
147
|
end
|
148
148
|
|
149
|
-
add_distributed_tags(
|
149
|
+
add_distributed_tags(context.trace)
|
150
150
|
end
|
151
151
|
|
152
152
|
private
|
data/lib/datadog/appsec/ext.rb
CHANGED
@@ -3,8 +3,10 @@
|
|
3
3
|
module Datadog
|
4
4
|
module AppSec
|
5
5
|
module Ext
|
6
|
+
RASP_SQLI = :sql_injection
|
6
7
|
INTERRUPT = :datadog_appsec_interrupt
|
7
|
-
|
8
|
+
CONTEXT_KEY = 'datadog.appsec.context'
|
9
|
+
ACTIVE_CONTEXT_KEY = :datadog_appsec_active_context
|
8
10
|
|
9
11
|
TAG_APPSEC_ENABLED = '_dd.appsec.enabled'
|
10
12
|
TAG_APM_ENABLED = '_dd.apm.enabled'
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative '../../instrumentation/gateway'
|
4
|
-
require_relative '../../reactive/
|
4
|
+
require_relative '../../reactive/engine'
|
5
5
|
require_relative '../reactive/set_user'
|
6
6
|
|
7
7
|
module Datadog
|
@@ -19,42 +19,32 @@ module Datadog
|
|
19
19
|
|
20
20
|
def watch_user_id(gateway = Instrumentation.gateway)
|
21
21
|
gateway.watch('identity.set_user', :appsec) do |stack, user|
|
22
|
-
block = false
|
23
22
|
event = nil
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
23
|
+
context = Datadog::AppSec.active_context
|
24
|
+
engine = AppSec::Reactive::Engine.new
|
25
|
+
|
26
|
+
Monitor::Reactive::SetUser.subscribe(engine, context) do |result|
|
27
|
+
if result.status == :match
|
28
|
+
# TODO: should this hash be an Event instance instead?
|
29
|
+
event = {
|
30
|
+
waf_result: result,
|
31
|
+
trace: context.trace,
|
32
|
+
span: context.span,
|
33
|
+
user: user,
|
34
|
+
actions: result.actions
|
35
|
+
}
|
36
|
+
|
37
|
+
# We want to keep the trace in case of security event
|
38
|
+
context.trace.keep! if context.trace
|
39
|
+
Datadog::AppSec::Event.tag_and_keep!(context, result)
|
40
|
+
context.waf_runner.events << event
|
43
41
|
end
|
44
|
-
|
45
|
-
block = Monitor::Reactive::SetUser.publish(op, user)
|
46
42
|
end
|
47
43
|
|
48
|
-
|
49
|
-
|
50
|
-
ret, res = stack.call(user)
|
51
|
-
|
52
|
-
if event
|
53
|
-
res ||= []
|
54
|
-
res << [:monitor, event]
|
55
|
-
end
|
44
|
+
block = Monitor::Reactive::SetUser.publish(engine, user)
|
45
|
+
throw(Datadog::AppSec::Ext::INTERRUPT, event[:actions]) if block
|
56
46
|
|
57
|
-
|
47
|
+
stack.call(user)
|
58
48
|
end
|
59
49
|
end
|
60
50
|
end
|
@@ -11,16 +11,16 @@ module Datadog
|
|
11
11
|
].freeze
|
12
12
|
private_constant :ADDRESSES
|
13
13
|
|
14
|
-
def self.publish(
|
14
|
+
def self.publish(engine, user)
|
15
15
|
catch(:block) do
|
16
|
-
|
16
|
+
engine.publish('usr.id', user.id)
|
17
17
|
|
18
18
|
nil
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
def self.subscribe(
|
23
|
-
|
22
|
+
def self.subscribe(engine, context)
|
23
|
+
engine.subscribe(*ADDRESSES) do |*values|
|
24
24
|
Datadog.logger.debug { "reacted to #{ADDRESSES.inspect}: #{values.inspect}" }
|
25
25
|
|
26
26
|
user_id = values[0]
|
@@ -30,7 +30,7 @@ module Datadog
|
|
30
30
|
}
|
31
31
|
|
32
32
|
waf_timeout = Datadog.configuration.appsec.waf_timeout
|
33
|
-
result =
|
33
|
+
result = context.run_waf(persistent_data, {}, waf_timeout)
|
34
34
|
|
35
35
|
next if result.status != :match
|
36
36
|
|
data/lib/datadog/appsec.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative 'appsec/configuration'
|
4
4
|
require_relative 'appsec/extensions'
|
5
|
-
require_relative 'appsec/
|
5
|
+
require_relative 'appsec/context'
|
6
6
|
require_relative 'appsec/ext'
|
7
7
|
require_relative 'appsec/utils'
|
8
8
|
|
@@ -14,8 +14,8 @@ module Datadog
|
|
14
14
|
Datadog.configuration.appsec.enabled
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
Datadog::AppSec::
|
17
|
+
def active_context
|
18
|
+
Datadog::AppSec::Context.active
|
19
19
|
end
|
20
20
|
|
21
21
|
def processor
|
@@ -6,6 +6,9 @@
|
|
6
6
|
require_relative '../datadog'
|
7
7
|
require_relative 'tracing/contrib/auto_instrument'
|
8
8
|
|
9
|
+
# DI is not loaded on Ruby 2.5 and JRuby
|
10
|
+
Datadog::DI::Contrib.load_now_or_later if defined?(Datadog::DI::Contrib)
|
11
|
+
|
9
12
|
Datadog::Profiling.start_if_enabled
|
10
13
|
|
11
14
|
module Datadog
|
@@ -19,21 +19,49 @@ module Datadog
|
|
19
19
|
# Whenever there is a conflict (different configurations are provided in different orders), it MUST warn the users
|
20
20
|
# about it and pick a value based on the following priority: code > environment variable > defaults.
|
21
21
|
class AgentSettingsResolver
|
22
|
-
|
23
|
-
|
24
|
-
:ssl,
|
25
|
-
|
26
|
-
:port,
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
22
|
+
# Immutable container for the resulting settings
|
23
|
+
class AgentSettings
|
24
|
+
attr_reader :adapter, :ssl, :hostname, :port, :uds_path, :timeout_seconds
|
25
|
+
|
26
|
+
def initialize(adapter: nil, ssl: nil, hostname: nil, port: nil, uds_path: nil, timeout_seconds: nil)
|
27
|
+
@adapter = adapter
|
28
|
+
@ssl = ssl
|
29
|
+
@hostname = hostname
|
30
|
+
@port = port
|
31
|
+
@uds_path = uds_path
|
32
|
+
@timeout_seconds = timeout_seconds
|
33
33
|
freeze
|
34
34
|
end
|
35
|
+
|
36
|
+
def url
|
37
|
+
case adapter
|
38
|
+
when Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
|
39
|
+
hostname = self.hostname
|
40
|
+
hostname = "[#{hostname}]" if hostname =~ IPV6_REGEXP
|
41
|
+
"#{ssl ? 'https' : 'http'}://#{hostname}:#{port}/"
|
42
|
+
when Datadog::Core::Configuration::Ext::Agent::UnixSocket::ADAPTER
|
43
|
+
"unix://#{uds_path}"
|
44
|
+
else
|
45
|
+
raise ArgumentError, "Unexpected adapter: #{adapter}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def ==(other)
|
50
|
+
self.class == other.class &&
|
51
|
+
adapter == other.adapter &&
|
52
|
+
ssl == other.ssl &&
|
53
|
+
hostname == other.hostname &&
|
54
|
+
port == other.port &&
|
55
|
+
uds_path == other.uds_path &&
|
56
|
+
timeout_seconds == other.timeout_seconds
|
57
|
+
end
|
35
58
|
end
|
36
59
|
|
60
|
+
# IPv6 regular expression from
|
61
|
+
# https://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses
|
62
|
+
# Does not match IPv4 addresses.
|
63
|
+
IPV6_REGEXP = /\A(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\z)/.freeze # rubocop:disable Layout/LineLength
|
64
|
+
|
37
65
|
def self.call(settings, logger: Datadog.logger)
|
38
66
|
new(settings, logger: logger).send(:call)
|
39
67
|
end
|
@@ -105,14 +105,16 @@ module Datadog
|
|
105
105
|
@profiler, profiler_logger_extra = Datadog::Profiling::Component.build_profiler_component(
|
106
106
|
settings: settings,
|
107
107
|
agent_settings: agent_settings,
|
108
|
-
optional_tracer: @tracer
|
108
|
+
optional_tracer: @tracer,
|
109
|
+
logger: @logger,
|
109
110
|
)
|
110
111
|
@environment_logger_extra.merge!(profiler_logger_extra) if profiler_logger_extra
|
111
112
|
|
112
113
|
@runtime_metrics = self.class.build_runtime_metrics_worker(settings)
|
113
114
|
@health_metrics = self.class.build_health_metrics(settings)
|
114
115
|
@appsec = Datadog::AppSec::Component.build_appsec_component(settings, telemetry: telemetry)
|
115
|
-
@dynamic_instrumentation = Datadog::DI::Component.build(settings, agent_settings, telemetry: telemetry)
|
116
|
+
@dynamic_instrumentation = Datadog::DI::Component.build(settings, agent_settings, @logger, telemetry: telemetry)
|
117
|
+
@environment_logger_extra[:dynamic_instrumentation_enabled] = !!@dynamic_instrumentation
|
116
118
|
|
117
119
|
self.class.configure_tracing(settings)
|
118
120
|
end
|
@@ -236,7 +236,7 @@ module Datadog
|
|
236
236
|
rescue ThreadError => e
|
237
237
|
logger_without_components.error(
|
238
238
|
'Detected deadlock during datadog initialization. ' \
|
239
|
-
'Please report this at https://github.com/
|
239
|
+
'Please report this at https://github.com/datadog/dd-trace-rb/blob/master/CONTRIBUTING.md#found-a-bug' \
|
240
240
|
"\n\tSource:\n\t#{Array(e.backtrace).join("\n\t")}"
|
241
241
|
)
|
242
242
|
nil
|
@@ -3,7 +3,6 @@
|
|
3
3
|
require 'libdatadog'
|
4
4
|
|
5
5
|
require_relative 'tag_builder'
|
6
|
-
require_relative 'agent_base_url'
|
7
6
|
require_relative '../utils/only_once'
|
8
7
|
require_relative '../utils/at_fork_monkey_patch'
|
9
8
|
|
@@ -31,8 +30,7 @@ module Datadog
|
|
31
30
|
|
32
31
|
def self.build(settings, agent_settings, logger:)
|
33
32
|
tags = TagBuilder.call(settings)
|
34
|
-
agent_base_url =
|
35
|
-
logger.warn('Missing agent base URL; cannot enable crash tracking') unless agent_base_url
|
33
|
+
agent_base_url = agent_settings.url
|
36
34
|
|
37
35
|
ld_library_path = ::Libdatadog.ld_library_path
|
38
36
|
logger.warn('Missing ld_library_path; cannot enable crash tracking') unless ld_library_path
|
@@ -29,6 +29,22 @@ module Datadog
|
|
29
29
|
def payload
|
30
30
|
{}
|
31
31
|
end
|
32
|
+
|
33
|
+
# Override equality to allow for deduplication
|
34
|
+
# The basic implementation is to check if the other object is an instance of the same class.
|
35
|
+
# This works for events that have no attributes.
|
36
|
+
# For events with attributes, you should override this method to compare the attributes.
|
37
|
+
def ==(other)
|
38
|
+
other.is_a?(self.class)
|
39
|
+
end
|
40
|
+
|
41
|
+
# @see #==
|
42
|
+
alias eql? ==
|
43
|
+
|
44
|
+
# @see #==
|
45
|
+
def hash
|
46
|
+
self.class.hash
|
47
|
+
end
|
32
48
|
end
|
33
49
|
|
34
50
|
# Telemetry class for the 'app-started' event
|
@@ -263,6 +279,8 @@ module Datadog
|
|
263
279
|
|
264
280
|
# Telemetry class for the 'app-client-configuration-change' event
|
265
281
|
class AppClientConfigurationChange < Base
|
282
|
+
attr_reader :changes, :origin
|
283
|
+
|
266
284
|
def type
|
267
285
|
'app-client-configuration-change'
|
268
286
|
end
|
@@ -301,6 +319,16 @@ module Datadog
|
|
301
319
|
|
302
320
|
res
|
303
321
|
end
|
322
|
+
|
323
|
+
def ==(other)
|
324
|
+
other.is_a?(AppClientConfigurationChange) && other.changes == @changes && other.origin == @origin
|
325
|
+
end
|
326
|
+
|
327
|
+
alias eql? ==
|
328
|
+
|
329
|
+
def hash
|
330
|
+
[self.class, @changes, @origin].hash
|
331
|
+
end
|
304
332
|
end
|
305
333
|
|
306
334
|
# Telemetry class for the 'app-heartbeat' event
|
@@ -319,6 +347,8 @@ module Datadog
|
|
319
347
|
|
320
348
|
# Telemetry class for the 'generate-metrics' event
|
321
349
|
class GenerateMetrics < Base
|
350
|
+
attr_reader :namespace, :metric_series
|
351
|
+
|
322
352
|
def type
|
323
353
|
'generate-metrics'
|
324
354
|
end
|
@@ -335,24 +365,54 @@ module Datadog
|
|
335
365
|
series: @metric_series.map(&:to_h)
|
336
366
|
}
|
337
367
|
end
|
368
|
+
|
369
|
+
def ==(other)
|
370
|
+
other.is_a?(GenerateMetrics) && other.namespace == @namespace && other.metric_series == @metric_series
|
371
|
+
end
|
372
|
+
|
373
|
+
alias eql? ==
|
374
|
+
|
375
|
+
def hash
|
376
|
+
[self.class, @namespace, @metric_series].hash
|
377
|
+
end
|
338
378
|
end
|
339
379
|
|
340
|
-
# Telemetry class for the 'logs' event
|
380
|
+
# Telemetry class for the 'logs' event.
|
381
|
+
# Logs with the same content are deduplicated at flush time.
|
341
382
|
class Log < Base
|
342
383
|
LEVELS = {
|
343
384
|
error: 'ERROR',
|
344
385
|
warn: 'WARN',
|
345
386
|
}.freeze
|
346
387
|
|
388
|
+
LEVELS_STRING = LEVELS.values.freeze
|
389
|
+
|
390
|
+
attr_reader :message, :level, :stack_trace, :count
|
391
|
+
|
347
392
|
def type
|
348
393
|
'logs'
|
349
394
|
end
|
350
395
|
|
351
|
-
|
396
|
+
# @param message [String] the log message
|
397
|
+
# @param level [Symbol, String] the log level. Either :error, :warn, 'ERROR', or 'WARN'.
|
398
|
+
# @param stack_trace [String, nil] the stack trace
|
399
|
+
# @param count [Integer] the number of times the log was emitted. Used for deduplication.
|
400
|
+
def initialize(message:, level:, stack_trace: nil, count: 1)
|
352
401
|
super()
|
353
402
|
@message = message
|
354
403
|
@stack_trace = stack_trace
|
355
|
-
|
404
|
+
|
405
|
+
if level.is_a?(String) && LEVELS_STRING.include?(level)
|
406
|
+
# String level is used during object copy for deduplication
|
407
|
+
@level = level
|
408
|
+
elsif level.is_a?(Symbol)
|
409
|
+
# Symbol level is used by the regular log emitter user
|
410
|
+
@level = LEVELS.fetch(level) { |k| raise ArgumentError, "Invalid log level :#{k}" }
|
411
|
+
else
|
412
|
+
raise ArgumentError, "Invalid log level #{level}"
|
413
|
+
end
|
414
|
+
|
415
|
+
@count = count
|
356
416
|
end
|
357
417
|
|
358
418
|
def payload
|
@@ -362,10 +422,24 @@ module Datadog
|
|
362
422
|
message: @message,
|
363
423
|
level: @level,
|
364
424
|
stack_trace: @stack_trace,
|
425
|
+
count: @count,
|
365
426
|
}.compact
|
366
427
|
]
|
367
428
|
}
|
368
429
|
end
|
430
|
+
|
431
|
+
# override equality to allow for deduplication
|
432
|
+
def ==(other)
|
433
|
+
other.is_a?(Log) &&
|
434
|
+
other.message == @message &&
|
435
|
+
other.level == @level && other.stack_trace == @stack_trace && other.count == @count
|
436
|
+
end
|
437
|
+
|
438
|
+
alias eql? ==
|
439
|
+
|
440
|
+
def hash
|
441
|
+
[self.class, @message, @level, @stack_trace, @count].hash
|
442
|
+
end
|
369
443
|
end
|
370
444
|
|
371
445
|
# Telemetry class for the 'distributions' event
|
@@ -395,6 +469,16 @@ module Datadog
|
|
395
469
|
}
|
396
470
|
end
|
397
471
|
end
|
472
|
+
|
473
|
+
def ==(other)
|
474
|
+
other.is_a?(MessageBatch) && other.events == @events
|
475
|
+
end
|
476
|
+
|
477
|
+
alias eql? ==
|
478
|
+
|
479
|
+
def hash
|
480
|
+
[self.class, @events].hash
|
481
|
+
end
|
398
482
|
end
|
399
483
|
end
|
400
484
|
end
|
@@ -41,7 +41,7 @@ module Datadog
|
|
41
41
|
else
|
42
42
|
'REDACTED'
|
43
43
|
end
|
44
|
-
end.join(
|
44
|
+
end.join("\n")
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -49,7 +49,7 @@ module Datadog
|
|
49
49
|
# Annoymous exceptions to be logged as <Class:0x00007f8b1c0b3b40>
|
50
50
|
message = +''
|
51
51
|
message << (exception.class.name || exception.class.inspect)
|
52
|
-
message << ':' << description if description
|
52
|
+
message << ': ' << description if description
|
53
53
|
|
54
54
|
event = Event::Log.new(
|
55
55
|
message: message,
|