ddtrace 1.5.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -1
- data/LICENSE-3rdparty.csv +1 -0
- data/lib/datadog/appsec/assets/waf_rules/recommended.json +1169 -275
- data/lib/datadog/appsec/assets/waf_rules/risky.json +78 -78
- data/lib/datadog/appsec/assets/waf_rules/strict.json +278 -88
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +25 -18
- data/lib/datadog/appsec/contrib/rack/reactive/request.rb +11 -11
- data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +11 -11
- data/lib/datadog/appsec/contrib/rack/reactive/response.rb +11 -11
- data/lib/datadog/appsec/contrib/rack/request.rb +3 -0
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +2 -1
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +7 -6
- data/lib/datadog/appsec/contrib/rails/reactive/action.rb +11 -11
- data/lib/datadog/appsec/contrib/rails/request.rb +3 -0
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +14 -12
- data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +11 -11
- data/lib/datadog/appsec/event.rb +0 -8
- data/lib/datadog/appsec/instrumentation/gateway.rb +16 -2
- data/lib/datadog/appsec/processor.rb +18 -2
- data/lib/datadog/core/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +1 -1
- data/lib/datadog/tracing/contrib/utils/quantization/http.rb +14 -6
- data/lib/ddtrace/transport/traces.rb +2 -0
- data/lib/ddtrace/version.rb +1 -1
- metadata +3 -3
@@ -16,8 +16,10 @@ module Datadog
|
|
16
16
|
module Watcher
|
17
17
|
# rubocop:disable Metrics/AbcSize
|
18
18
|
# rubocop:disable Metrics/MethodLength
|
19
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
20
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
19
21
|
def self.watch
|
20
|
-
Instrumentation.gateway.watch('rack.request') do |stack, request|
|
22
|
+
Instrumentation.gateway.watch('rack.request', :appsec) do |stack, request|
|
21
23
|
block = false
|
22
24
|
event = nil
|
23
25
|
waf_context = request.env['datadog.waf.context']
|
@@ -26,23 +28,24 @@ module Datadog
|
|
26
28
|
trace = active_trace
|
27
29
|
span = active_span
|
28
30
|
|
29
|
-
Rack::Reactive::Request.subscribe(op, waf_context) do |
|
30
|
-
|
31
|
-
if record
|
31
|
+
Rack::Reactive::Request.subscribe(op, waf_context) do |result, _block|
|
32
|
+
if result.status == :match
|
32
33
|
# TODO: should this hash be an Event instance instead?
|
33
34
|
event = {
|
34
35
|
waf_result: result,
|
35
36
|
trace: trace,
|
36
37
|
span: span,
|
37
38
|
request: request,
|
38
|
-
|
39
|
+
actions: result.actions
|
39
40
|
}
|
40
41
|
|
42
|
+
span.set_tag('appsec.event', 'true') if span
|
43
|
+
|
41
44
|
waf_context.events << event
|
42
45
|
end
|
43
46
|
end
|
44
47
|
|
45
|
-
|
48
|
+
_result, block = Rack::Reactive::Request.publish(op, request)
|
46
49
|
end
|
47
50
|
|
48
51
|
next [nil, [[:block, event]]] if block
|
@@ -57,7 +60,7 @@ module Datadog
|
|
57
60
|
[ret, res]
|
58
61
|
end
|
59
62
|
|
60
|
-
Instrumentation.gateway.watch('rack.response') do |stack, response|
|
63
|
+
Instrumentation.gateway.watch('rack.response', :appsec) do |stack, response|
|
61
64
|
block = false
|
62
65
|
event = nil
|
63
66
|
waf_context = response.instance_eval { @waf_context }
|
@@ -66,23 +69,24 @@ module Datadog
|
|
66
69
|
trace = active_trace
|
67
70
|
span = active_span
|
68
71
|
|
69
|
-
Rack::Reactive::Response.subscribe(op, waf_context) do |
|
70
|
-
|
71
|
-
if record
|
72
|
+
Rack::Reactive::Response.subscribe(op, waf_context) do |result, _block|
|
73
|
+
if result.status == :match
|
72
74
|
# TODO: should this hash be an Event instance instead?
|
73
75
|
event = {
|
74
76
|
waf_result: result,
|
75
77
|
trace: trace,
|
76
78
|
span: span,
|
77
79
|
response: response,
|
78
|
-
|
80
|
+
actions: result.actions
|
79
81
|
}
|
80
82
|
|
83
|
+
span.set_tag('appsec.event', 'true') if span
|
84
|
+
|
81
85
|
waf_context.events << event
|
82
86
|
end
|
83
87
|
end
|
84
88
|
|
85
|
-
|
89
|
+
_result, block = Rack::Reactive::Response.publish(op, response)
|
86
90
|
end
|
87
91
|
|
88
92
|
next [nil, [[:block, event]]] if block
|
@@ -97,7 +101,7 @@ module Datadog
|
|
97
101
|
[ret, res]
|
98
102
|
end
|
99
103
|
|
100
|
-
Instrumentation.gateway.watch('rack.request.body') do |stack, request|
|
104
|
+
Instrumentation.gateway.watch('rack.request.body', :appsec) do |stack, request|
|
101
105
|
block = false
|
102
106
|
event = nil
|
103
107
|
waf_context = request.env['datadog.waf.context']
|
@@ -106,23 +110,24 @@ module Datadog
|
|
106
110
|
trace = active_trace
|
107
111
|
span = active_span
|
108
112
|
|
109
|
-
Rack::Reactive::RequestBody.subscribe(op, waf_context) do |
|
110
|
-
|
111
|
-
if record
|
113
|
+
Rack::Reactive::RequestBody.subscribe(op, waf_context) do |result, _block|
|
114
|
+
if result.status == :match
|
112
115
|
# TODO: should this hash be an Event instance instead?
|
113
116
|
event = {
|
114
117
|
waf_result: result,
|
115
118
|
trace: trace,
|
116
119
|
span: span,
|
117
120
|
request: request,
|
118
|
-
|
121
|
+
actions: result.actions
|
119
122
|
}
|
120
123
|
|
124
|
+
span.set_tag('appsec.event', 'true') if span
|
125
|
+
|
121
126
|
waf_context.events << event
|
122
127
|
end
|
123
128
|
end
|
124
129
|
|
125
|
-
|
130
|
+
_result, block = Rack::Reactive::RequestBody.publish(op, request)
|
126
131
|
end
|
127
132
|
|
128
133
|
next [nil, [[:block, event]]] if block
|
@@ -137,6 +142,8 @@ module Datadog
|
|
137
142
|
[ret, res]
|
138
143
|
end
|
139
144
|
end
|
145
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
146
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
140
147
|
# rubocop:enable Metrics/MethodLength
|
141
148
|
# rubocop:enable Metrics/AbcSize
|
142
149
|
|
@@ -54,27 +54,27 @@ module Datadog
|
|
54
54
|
}
|
55
55
|
|
56
56
|
waf_timeout = Datadog::AppSec.settings.waf_timeout
|
57
|
-
|
57
|
+
result = waf_context.run(waf_args, waf_timeout)
|
58
58
|
|
59
59
|
Datadog.logger.debug { "WAF TIMEOUT: #{result.inspect}" } if result.timeout
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
when :monitor
|
61
|
+
case result.status
|
62
|
+
when :match
|
64
63
|
Datadog.logger.debug { "WAF: #{result.inspect}" }
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
yield [
|
69
|
-
|
70
|
-
|
64
|
+
|
65
|
+
block = result.actions.include?('block')
|
66
|
+
|
67
|
+
yield [result, block]
|
68
|
+
|
69
|
+
throw(:block, [result, true]) if block
|
70
|
+
when :ok
|
71
71
|
Datadog.logger.debug { "WAF OK: #{result.inspect}" }
|
72
72
|
when :invalid_call
|
73
73
|
Datadog.logger.debug { "WAF CALL ERROR: #{result.inspect}" }
|
74
74
|
when :invalid_rule, :invalid_flow, :no_rule
|
75
75
|
Datadog.logger.debug { "WAF RULE ERROR: #{result.inspect}" }
|
76
76
|
else
|
77
|
-
Datadog.logger.debug { "WAF UNKNOWN: #{
|
77
|
+
Datadog.logger.debug { "WAF UNKNOWN: #{result.status.inspect} #{result.inspect}" }
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
@@ -32,27 +32,27 @@ module Datadog
|
|
32
32
|
}
|
33
33
|
|
34
34
|
waf_timeout = Datadog::AppSec.settings.waf_timeout
|
35
|
-
|
35
|
+
result = waf_context.run(waf_args, waf_timeout)
|
36
36
|
|
37
37
|
Datadog.logger.debug { "WAF TIMEOUT: #{result.inspect}" } if result.timeout
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
when :monitor
|
39
|
+
case result.status
|
40
|
+
when :match
|
42
41
|
Datadog.logger.debug { "WAF: #{result.inspect}" }
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
yield [
|
47
|
-
|
48
|
-
|
42
|
+
|
43
|
+
block = result.actions.include?('block')
|
44
|
+
|
45
|
+
yield [result, block]
|
46
|
+
|
47
|
+
throw(:block, [result, true]) if block
|
48
|
+
when :ok
|
49
49
|
Datadog.logger.debug { "WAF OK: #{result.inspect}" }
|
50
50
|
when :invalid_call
|
51
51
|
Datadog.logger.debug { "WAF CALL ERROR: #{result.inspect}" }
|
52
52
|
when :invalid_rule, :invalid_flow, :no_rule
|
53
53
|
Datadog.logger.debug { "WAF RULE ERROR: #{result.inspect}" }
|
54
54
|
else
|
55
|
-
Datadog.logger.debug { "WAF UNKNOWN: #{
|
55
|
+
Datadog.logger.debug { "WAF UNKNOWN: #{result.status.inspect} #{result.inspect}" }
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
@@ -32,27 +32,27 @@ module Datadog
|
|
32
32
|
}
|
33
33
|
|
34
34
|
waf_timeout = Datadog::AppSec.settings.waf_timeout
|
35
|
-
|
35
|
+
result = waf_context.run(waf_args, waf_timeout)
|
36
36
|
|
37
37
|
Datadog.logger.debug { "WAF TIMEOUT: #{result.inspect}" } if result.timeout
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
when :monitor
|
39
|
+
case result.status
|
40
|
+
when :match
|
42
41
|
Datadog.logger.debug { "WAF: #{result.inspect}" }
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
yield [
|
47
|
-
|
48
|
-
|
42
|
+
|
43
|
+
block = result.actions.include?('block')
|
44
|
+
|
45
|
+
yield [result, block]
|
46
|
+
|
47
|
+
throw(:block, [result, true]) if block
|
48
|
+
when :ok
|
49
49
|
Datadog.logger.debug { "WAF OK: #{result.inspect}" }
|
50
50
|
when :invalid_call
|
51
51
|
Datadog.logger.debug { "WAF CALL ERROR: #{result.inspect}" }
|
52
52
|
when :invalid_rule, :invalid_flow, :no_rule
|
53
53
|
Datadog.logger.debug { "WAF RULE ERROR: #{result.inspect}" }
|
54
54
|
else
|
55
|
-
Datadog.logger.debug { "WAF UNKNOWN: #{
|
55
|
+
Datadog.logger.debug { "WAF UNKNOWN: #{result.status.inspect} #{result.inspect}" }
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
@@ -47,6 +47,9 @@ module Datadog
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def self.form_hash(request)
|
50
|
+
# force form data processing
|
51
|
+
request.POST if request.form_data?
|
52
|
+
|
50
53
|
# usually Hash<String,String> but can be a more complex
|
51
54
|
# Hash<String,String||Array||Hash> when e.g coming from JSON
|
52
55
|
request.env['rack.request.form_hash']
|
@@ -21,7 +21,7 @@ module Datadog
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def call(env)
|
24
|
-
return @app.call(env) unless @processor.ready?
|
24
|
+
return @app.call(env) unless Datadog.configuration.appsec.enabled && @processor.ready?
|
25
25
|
|
26
26
|
# TODO: handle exceptions, except for @app.call
|
27
27
|
|
@@ -57,6 +57,7 @@ module Datadog
|
|
57
57
|
request_return
|
58
58
|
ensure
|
59
59
|
add_waf_runtime_tags(context) if context
|
60
|
+
context.finalize if context
|
60
61
|
end
|
61
62
|
|
62
63
|
private
|
@@ -13,7 +13,7 @@ module Datadog
|
|
13
13
|
# Watcher for Rails gateway events
|
14
14
|
module Watcher
|
15
15
|
def self.watch
|
16
|
-
Instrumentation.gateway.watch('rails.request.action') do |stack, request|
|
16
|
+
Instrumentation.gateway.watch('rails.request.action', :appsec) do |stack, request|
|
17
17
|
block = false
|
18
18
|
event = nil
|
19
19
|
waf_context = request.env['datadog.waf.context']
|
@@ -22,23 +22,24 @@ module Datadog
|
|
22
22
|
trace = active_trace
|
23
23
|
span = active_span
|
24
24
|
|
25
|
-
Rails::Reactive::Action.subscribe(op, waf_context) do |
|
26
|
-
|
27
|
-
if record
|
25
|
+
Rails::Reactive::Action.subscribe(op, waf_context) do |result, _block|
|
26
|
+
if result.status == :match
|
28
27
|
# TODO: should this hash be an Event instance instead?
|
29
28
|
event = {
|
30
29
|
waf_result: result,
|
31
30
|
trace: trace,
|
32
31
|
span: span,
|
33
32
|
request: request,
|
34
|
-
|
33
|
+
actions: result.actions
|
35
34
|
}
|
36
35
|
|
36
|
+
span.set_tag('appsec.event', 'true') if span
|
37
|
+
|
37
38
|
waf_context.events << event
|
38
39
|
end
|
39
40
|
end
|
40
41
|
|
41
|
-
|
42
|
+
_result, block = Rails::Reactive::Action.publish(op, request)
|
42
43
|
end
|
43
44
|
|
44
45
|
next [nil, [[:block, event]]] if block
|
@@ -36,27 +36,27 @@ module Datadog
|
|
36
36
|
}
|
37
37
|
|
38
38
|
waf_timeout = Datadog::AppSec.settings.waf_timeout
|
39
|
-
|
39
|
+
result = waf_context.run(waf_args, waf_timeout)
|
40
40
|
|
41
41
|
Datadog.logger.debug { "WAF TIMEOUT: #{result.inspect}" } if result.timeout
|
42
42
|
|
43
|
-
|
44
|
-
|
45
|
-
when :monitor
|
43
|
+
case result.status
|
44
|
+
when :match
|
46
45
|
Datadog.logger.debug { "WAF: #{result.inspect}" }
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
yield [
|
51
|
-
|
52
|
-
|
46
|
+
|
47
|
+
block = result.actions.include?('block')
|
48
|
+
|
49
|
+
yield [result, block]
|
50
|
+
|
51
|
+
throw(:block, [result, true]) if block
|
52
|
+
when :ok
|
53
53
|
Datadog.logger.debug { "WAF OK: #{result.inspect}" }
|
54
54
|
when :invalid_call
|
55
55
|
Datadog.logger.debug { "WAF CALL ERROR: #{result.inspect}" }
|
56
56
|
when :invalid_rule, :invalid_flow, :no_rule
|
57
57
|
Datadog.logger.debug { "WAF RULE ERROR: #{result.inspect}" }
|
58
58
|
else
|
59
|
-
Datadog.logger.debug { "WAF UNKNOWN: #{
|
59
|
+
Datadog.logger.debug { "WAF UNKNOWN: #{result.status.inspect} #{result.inspect}" }
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
@@ -7,6 +7,9 @@ module Datadog
|
|
7
7
|
# Normalized extration of data from ActionDispatch::Request
|
8
8
|
module Request
|
9
9
|
def self.parsed_body(request)
|
10
|
+
# force body parameter parsing, which is done lazily by Rails
|
11
|
+
request.parameters
|
12
|
+
|
10
13
|
# usually Hash<String,String> but can be a more complex
|
11
14
|
# Hash<String,String||Array||Hash> when e.g coming from JSON or
|
12
15
|
# with Rails advanced param square bracket parsing
|
@@ -15,7 +15,7 @@ module Datadog
|
|
15
15
|
module Watcher
|
16
16
|
# rubocop:disable Metrics/MethodLength
|
17
17
|
def self.watch
|
18
|
-
Instrumentation.gateway.watch('sinatra.request.dispatch') do |stack, request|
|
18
|
+
Instrumentation.gateway.watch('sinatra.request.dispatch', :appsec) do |stack, request|
|
19
19
|
block = false
|
20
20
|
event = nil
|
21
21
|
waf_context = request.env['datadog.waf.context']
|
@@ -24,23 +24,24 @@ module Datadog
|
|
24
24
|
trace = active_trace
|
25
25
|
span = active_span
|
26
26
|
|
27
|
-
Rack::Reactive::RequestBody.subscribe(op, waf_context) do |
|
28
|
-
|
29
|
-
if record
|
27
|
+
Rack::Reactive::RequestBody.subscribe(op, waf_context) do |result, _block|
|
28
|
+
if result.status == :match
|
30
29
|
# TODO: should this hash be an Event instance instead?
|
31
30
|
event = {
|
32
31
|
waf_result: result,
|
33
32
|
trace: trace,
|
34
33
|
span: span,
|
35
34
|
request: request,
|
36
|
-
|
35
|
+
actions: result.actions
|
37
36
|
}
|
38
37
|
|
38
|
+
span.set_tag('appsec.event', 'true') if span
|
39
|
+
|
39
40
|
waf_context.events << event
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
43
|
-
|
44
|
+
_result, block = Rack::Reactive::RequestBody.publish(op, request)
|
44
45
|
end
|
45
46
|
|
46
47
|
next [nil, [[:block, event]]] if block
|
@@ -55,7 +56,7 @@ module Datadog
|
|
55
56
|
[ret, res]
|
56
57
|
end
|
57
58
|
|
58
|
-
Instrumentation.gateway.watch('sinatra.request.routed') do |stack, (request, route_params)|
|
59
|
+
Instrumentation.gateway.watch('sinatra.request.routed', :appsec) do |stack, (request, route_params)|
|
59
60
|
block = false
|
60
61
|
event = nil
|
61
62
|
waf_context = request.env['datadog.waf.context']
|
@@ -64,23 +65,24 @@ module Datadog
|
|
64
65
|
trace = active_trace
|
65
66
|
span = active_span
|
66
67
|
|
67
|
-
Sinatra::Reactive::Routed.subscribe(op, waf_context) do |
|
68
|
-
|
69
|
-
if record
|
68
|
+
Sinatra::Reactive::Routed.subscribe(op, waf_context) do |result, _block|
|
69
|
+
if result.status == :match
|
70
70
|
# TODO: should this hash be an Event instance instead?
|
71
71
|
event = {
|
72
72
|
waf_result: result,
|
73
73
|
trace: trace,
|
74
74
|
span: span,
|
75
75
|
request: request,
|
76
|
-
|
76
|
+
actions: result.actions
|
77
77
|
}
|
78
78
|
|
79
|
+
span.set_tag('appsec.event', 'true') if span
|
80
|
+
|
79
81
|
waf_context.events << event
|
80
82
|
end
|
81
83
|
end
|
82
84
|
|
83
|
-
|
85
|
+
_result, block = Sinatra::Reactive::Routed.publish(op, [request, route_params])
|
84
86
|
end
|
85
87
|
|
86
88
|
next [nil, [[:block, event]]] if block
|
@@ -31,27 +31,27 @@ module Datadog
|
|
31
31
|
}
|
32
32
|
|
33
33
|
waf_timeout = Datadog::AppSec.settings.waf_timeout
|
34
|
-
|
34
|
+
result = waf_context.run(waf_args, waf_timeout)
|
35
35
|
|
36
36
|
Datadog.logger.debug { "WAF TIMEOUT: #{result.inspect}" } if result.timeout
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
when :monitor
|
38
|
+
case result.status
|
39
|
+
when :match
|
41
40
|
Datadog.logger.debug { "WAF: #{result.inspect}" }
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
yield [
|
46
|
-
|
47
|
-
|
41
|
+
|
42
|
+
block = result.actions.include?('block')
|
43
|
+
|
44
|
+
yield [result, block]
|
45
|
+
|
46
|
+
throw(:block, [result, true]) if block
|
47
|
+
when :ok
|
48
48
|
Datadog.logger.debug { "WAF OK: #{result.inspect}" }
|
49
49
|
when :invalid_call
|
50
50
|
Datadog.logger.debug { "WAF CALL ERROR: #{result.inspect}" }
|
51
51
|
when :invalid_rule, :invalid_flow, :no_rule
|
52
52
|
Datadog.logger.debug { "WAF RULE ERROR: #{result.inspect}" }
|
53
53
|
else
|
54
|
-
Datadog.logger.debug { "WAF UNKNOWN: #{
|
54
|
+
Datadog.logger.debug { "WAF UNKNOWN: #{result.status.inspect} #{result.inspect}" }
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
data/lib/datadog/appsec/event.rb
CHANGED
@@ -51,8 +51,6 @@ module Datadog
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
# rubocop:disable Metrics/AbcSize
|
55
|
-
# rubocop:disable Metrics/MethodLength
|
56
54
|
def self.record_via_span(*events)
|
57
55
|
events.group_by { |e| e[:trace] }.each do |trace, event_group|
|
58
56
|
unless trace
|
@@ -64,10 +62,6 @@ module Datadog
|
|
64
62
|
|
65
63
|
# prepare and gather tags to apply
|
66
64
|
trace_tags = event_group.each_with_object({}) do |event, tags|
|
67
|
-
span = event[:span]
|
68
|
-
|
69
|
-
span.set_tag('appsec.event', 'true') if span
|
70
|
-
|
71
65
|
# TODO: assume HTTP request context for now
|
72
66
|
|
73
67
|
if (request = event[:request])
|
@@ -114,8 +108,6 @@ module Datadog
|
|
114
108
|
end
|
115
109
|
end
|
116
110
|
end
|
117
|
-
# rubocop:enable Metrics/MethodLength
|
118
|
-
# rubocop:enable Metrics/AbcSize
|
119
111
|
end
|
120
112
|
end
|
121
113
|
end
|
@@ -6,6 +6,20 @@ module Datadog
|
|
6
6
|
module Instrumentation
|
7
7
|
# Instrumentation gateway implementation
|
8
8
|
class Gateway
|
9
|
+
# Instrumentation gateway middleware
|
10
|
+
class Middleware
|
11
|
+
attr_reader :key, :block
|
12
|
+
|
13
|
+
def initialize(key, &block)
|
14
|
+
@key = key
|
15
|
+
@block = block
|
16
|
+
end
|
17
|
+
|
18
|
+
def call(*args, **kwargs, &block)
|
19
|
+
@block.call(*args, **kwargs, &block)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
9
23
|
def initialize
|
10
24
|
@middlewares = Hash.new { |h, k| h[k] = [] }
|
11
25
|
end
|
@@ -31,8 +45,8 @@ module Datadog
|
|
31
45
|
stack.call(env)
|
32
46
|
end
|
33
47
|
|
34
|
-
def watch(name, &block)
|
35
|
-
@middlewares[name] << block
|
48
|
+
def watch(name, key, &block)
|
49
|
+
@middlewares[name] << Middleware.new(key, &block) unless @middlewares[name].any? { |m| m.key == key }
|
36
50
|
end
|
37
51
|
end
|
38
52
|
|
@@ -31,7 +31,7 @@ module Datadog
|
|
31
31
|
def run(*args)
|
32
32
|
start_ns = Core::Utils::Time.get_time(:nanosecond)
|
33
33
|
|
34
|
-
|
34
|
+
_code, res = @context.run(*args)
|
35
35
|
|
36
36
|
stop_ns = Core::Utils::Time.get_time(:nanosecond)
|
37
37
|
|
@@ -39,7 +39,11 @@ module Datadog
|
|
39
39
|
@time_ext_ns += (stop_ns - start_ns)
|
40
40
|
@timeouts += 1 if res.timeout
|
41
41
|
|
42
|
-
|
42
|
+
res
|
43
|
+
end
|
44
|
+
|
45
|
+
def finalize
|
46
|
+
@context.finalize
|
43
47
|
end
|
44
48
|
end
|
45
49
|
|
@@ -64,6 +68,18 @@ module Datadog
|
|
64
68
|
Context.new(self)
|
65
69
|
end
|
66
70
|
|
71
|
+
def update_rule_data(data)
|
72
|
+
@handle.update_rule_data(data)
|
73
|
+
end
|
74
|
+
|
75
|
+
def toggle_rules(map)
|
76
|
+
@handle.toggle_rules(map)
|
77
|
+
end
|
78
|
+
|
79
|
+
def finalize
|
80
|
+
@handle.finalize
|
81
|
+
end
|
82
|
+
|
67
83
|
protected
|
68
84
|
|
69
85
|
attr_reader :handle
|
@@ -323,8 +323,8 @@ module Datadog
|
|
323
323
|
|
324
324
|
# Parse tags from environment
|
325
325
|
env_to_list(Core::Environment::Ext::ENV_TAGS, comma_separated_only: false).each do |tag|
|
326
|
-
|
327
|
-
tags[
|
326
|
+
key, value = tag.split(':', 2)
|
327
|
+
tags[key] = value if value && !value.empty?
|
328
328
|
end
|
329
329
|
|
330
330
|
# Override tags if defined
|
@@ -14,20 +14,28 @@ module Datadog
|
|
14
14
|
|
15
15
|
PLACEHOLDER = '?'.freeze
|
16
16
|
|
17
|
+
# taken from Ruby https://github.com/ruby/uri/blob/ffbab83de6d8748c9454414e02db5317609166eb/lib/uri/rfc3986_parser.rb
|
18
|
+
# but adjusted to parse only <scheme>://<host>:<port>/ components
|
19
|
+
# and stop there, since we don't care about the path, query string,
|
20
|
+
# and fragment components
|
21
|
+
RFC3986_URL_BASE = /\A(?<URI>(?<scheme>[A-Za-z][+\-.0-9A-Za-z]*):(?<hier-part>\/\/(?<authority>(?:(?<userinfo>(?:%\h\h|[!$&-.0-;=A-Z_a-z~])*)@)?(?<host>(?<IP-literal>\[(?:(?<IPv6address>(?:\h{1,4}:){6}(?<ls32>\h{1,4}:\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]|\d)\.\g<dec-octet>\.\g<dec-octet>\.\g<dec-octet>))|::(?:\h{1,4}:){5}\g<ls32>|\h{1,4}?::(?:\h{1,4}:){4}\g<ls32>|(?:(?:\h{1,4}:)?\h{1,4})?::(?:\h{1,4}:){3}\g<ls32>|(?:(?:\h{1,4}:){,2}\h{1,4})?::(?:\h{1,4}:){2}\g<ls32>|(?:(?:\h{1,4}:){,3}\h{1,4})?::\h{1,4}:\g<ls32>|(?:(?:\h{1,4}:){,4}\h{1,4})?::\g<ls32>|(?:(?:\h{1,4}:){,5}\h{1,4})?::\h{1,4}|(?:(?:\h{1,4}:){,6}\h{1,4})?::)|(?<IPvFuture>v\h+\.[!$&-.0-;=A-Z_a-z~]+))\])|\g<IPv4address>|(?<reg-name>(?:%\h\h|[!$&-.0-9;=A-Z_a-z~])*))(?::(?<port>\d*))?)))(?:\/|\z)/.freeze # rubocop:disable Style/RegexpLiteral, Layout/LineLength
|
22
|
+
|
17
23
|
module_function
|
18
24
|
|
19
25
|
def url(url, options = {})
|
20
26
|
url!(url, options)
|
21
27
|
rescue StandardError
|
22
|
-
options[:placeholder] || PLACEHOLDER
|
28
|
+
placeholder = options[:placeholder] || PLACEHOLDER
|
29
|
+
|
30
|
+
options[:base] == :exclude ? placeholder : "#{base_url(url)}/#{placeholder}"
|
23
31
|
end
|
24
32
|
|
25
33
|
def base_url(url, options = {})
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
34
|
+
if (m = RFC3986_URL_BASE.match(url))
|
35
|
+
m[1]
|
36
|
+
else
|
37
|
+
''
|
38
|
+
end
|
31
39
|
end
|
32
40
|
|
33
41
|
def url!(url, options = {})
|
@@ -101,6 +101,8 @@ module Datadog
|
|
101
101
|
# Make the trace serializable
|
102
102
|
serializable_trace = SerializableTrace.new(trace)
|
103
103
|
|
104
|
+
Datadog.logger.debug { "Flushing trace: #{JSON.dump(serializable_trace)}" }
|
105
|
+
|
104
106
|
# Encode the trace
|
105
107
|
encoder.encode(serializable_trace)
|
106
108
|
end
|