ddtrace 1.4.2 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -3
  3. data/LICENSE-3rdparty.csv +1 -0
  4. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +0 -2
  5. data/lib/datadog/appsec/assets/waf_rules/recommended.json +1169 -275
  6. data/lib/datadog/appsec/assets/waf_rules/risky.json +78 -78
  7. data/lib/datadog/appsec/assets/waf_rules/strict.json +278 -88
  8. data/lib/datadog/appsec/configuration/settings.rb +0 -2
  9. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +25 -20
  10. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +11 -11
  11. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +11 -11
  12. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +11 -11
  13. data/lib/datadog/appsec/contrib/rack/request.rb +3 -0
  14. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +2 -1
  15. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +7 -6
  16. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  17. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +11 -11
  18. data/lib/datadog/appsec/contrib/rails/request.rb +3 -0
  19. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +14 -12
  20. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +11 -11
  21. data/lib/datadog/appsec/event.rb +0 -8
  22. data/lib/datadog/appsec/instrumentation/gateway.rb +16 -2
  23. data/lib/datadog/appsec/processor.rb +18 -2
  24. data/lib/datadog/ci/ext/environment.rb +16 -4
  25. data/lib/datadog/core/configuration/agent_settings_resolver.rb +0 -3
  26. data/lib/datadog/core/configuration/components.rb +8 -2
  27. data/lib/datadog/core/configuration/settings.rb +71 -4
  28. data/lib/datadog/core/configuration.rb +1 -1
  29. data/lib/datadog/core/header_collection.rb +41 -0
  30. data/lib/datadog/core/telemetry/collector.rb +0 -2
  31. data/lib/datadog/core/workers/async.rb +0 -2
  32. data/lib/datadog/profiling/collectors/old_stack.rb +1 -1
  33. data/lib/datadog/profiling.rb +1 -1
  34. data/lib/datadog/tracing/client_ip.rb +153 -0
  35. data/lib/datadog/tracing/configuration/ext.rb +12 -0
  36. data/lib/datadog/tracing/contrib/aws/services.rb +0 -2
  37. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +0 -2
  38. data/lib/datadog/tracing/contrib/ext.rb +19 -0
  39. data/lib/datadog/tracing/contrib/faraday/middleware.rb +1 -2
  40. data/lib/datadog/tracing/contrib/grape/endpoint.rb +0 -2
  41. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +1 -1
  42. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +5 -4
  43. data/lib/datadog/tracing/contrib/rack/header_collection.rb +35 -0
  44. data/lib/datadog/tracing/contrib/rack/middlewares.rb +92 -38
  45. data/lib/datadog/tracing/contrib/utils/quantization/http.rb +92 -10
  46. data/lib/datadog/tracing/flush.rb +57 -35
  47. data/lib/datadog/tracing/metadata/ext.rb +3 -9
  48. data/lib/datadog/tracing/metadata/tagging.rb +9 -0
  49. data/lib/datadog/tracing/sampling/rate_limiter.rb +3 -0
  50. data/lib/datadog/tracing/sampling/rate_sampler.rb +10 -0
  51. data/lib/datadog/tracing/sampling/span/ext.rb +29 -0
  52. data/lib/datadog/tracing/sampling/span/matcher.rb +9 -0
  53. data/lib/datadog/tracing/sampling/span/rule.rb +82 -0
  54. data/lib/datadog/tracing/sampling/span/rule_parser.rb +104 -0
  55. data/lib/datadog/tracing/sampling/span/sampler.rb +64 -0
  56. data/lib/datadog/tracing/span_operation.rb +0 -2
  57. data/lib/datadog/tracing/trace_operation.rb +22 -3
  58. data/lib/datadog/tracing/trace_segment.rb +1 -2
  59. data/lib/datadog/tracing/tracer.rb +31 -5
  60. data/lib/ddtrace/transport/traces.rb +2 -0
  61. data/lib/ddtrace/version.rb +2 -2
  62. metadata +21 -7
@@ -5,7 +5,6 @@ module Datadog
5
5
  module Configuration
6
6
  # Configuration settings, acting as an integration registry
7
7
  # TODO: as with Configuration, this is a trivial implementation
8
- # rubocop:disable Metrics/ClassLength
9
8
  class Settings
10
9
  class << self
11
10
  def boolean
@@ -188,7 +187,6 @@ module Datadog
188
187
  initialize
189
188
  end
190
189
  end
191
- # rubocop:enable Metrics/ClassLength
192
190
  end
193
191
  end
194
192
  end
@@ -13,12 +13,13 @@ module Datadog
13
13
  module Rack
14
14
  module Gateway
15
15
  # Watcher for Rack gateway events
16
- # rubocop:disable Metrics/ModuleLength
17
16
  module Watcher
18
17
  # rubocop:disable Metrics/AbcSize
19
18
  # rubocop:disable Metrics/MethodLength
19
+ # rubocop:disable Metrics/CyclomaticComplexity
20
+ # rubocop:disable Metrics/PerceivedComplexity
20
21
  def self.watch
21
- Instrumentation.gateway.watch('rack.request') do |stack, request|
22
+ Instrumentation.gateway.watch('rack.request', :appsec) do |stack, request|
22
23
  block = false
23
24
  event = nil
24
25
  waf_context = request.env['datadog.waf.context']
@@ -27,23 +28,24 @@ module Datadog
27
28
  trace = active_trace
28
29
  span = active_span
29
30
 
30
- Rack::Reactive::Request.subscribe(op, waf_context) do |action, result, _block|
31
- record = [:block, :monitor].include?(action)
32
- if record
31
+ Rack::Reactive::Request.subscribe(op, waf_context) do |result, _block|
32
+ if result.status == :match
33
33
  # TODO: should this hash be an Event instance instead?
34
34
  event = {
35
35
  waf_result: result,
36
36
  trace: trace,
37
37
  span: span,
38
38
  request: request,
39
- action: action
39
+ actions: result.actions
40
40
  }
41
41
 
42
+ span.set_tag('appsec.event', 'true') if span
43
+
42
44
  waf_context.events << event
43
45
  end
44
46
  end
45
47
 
46
- _action, _result, block = Rack::Reactive::Request.publish(op, request)
48
+ _result, block = Rack::Reactive::Request.publish(op, request)
47
49
  end
48
50
 
49
51
  next [nil, [[:block, event]]] if block
@@ -58,7 +60,7 @@ module Datadog
58
60
  [ret, res]
59
61
  end
60
62
 
61
- Instrumentation.gateway.watch('rack.response') do |stack, response|
63
+ Instrumentation.gateway.watch('rack.response', :appsec) do |stack, response|
62
64
  block = false
63
65
  event = nil
64
66
  waf_context = response.instance_eval { @waf_context }
@@ -67,23 +69,24 @@ module Datadog
67
69
  trace = active_trace
68
70
  span = active_span
69
71
 
70
- Rack::Reactive::Response.subscribe(op, waf_context) do |action, result, _block|
71
- record = [:block, :monitor].include?(action)
72
- if record
72
+ Rack::Reactive::Response.subscribe(op, waf_context) do |result, _block|
73
+ if result.status == :match
73
74
  # TODO: should this hash be an Event instance instead?
74
75
  event = {
75
76
  waf_result: result,
76
77
  trace: trace,
77
78
  span: span,
78
79
  response: response,
79
- action: action
80
+ actions: result.actions
80
81
  }
81
82
 
83
+ span.set_tag('appsec.event', 'true') if span
84
+
82
85
  waf_context.events << event
83
86
  end
84
87
  end
85
88
 
86
- _action, _result, block = Rack::Reactive::Response.publish(op, response)
89
+ _result, block = Rack::Reactive::Response.publish(op, response)
87
90
  end
88
91
 
89
92
  next [nil, [[:block, event]]] if block
@@ -98,7 +101,7 @@ module Datadog
98
101
  [ret, res]
99
102
  end
100
103
 
101
- Instrumentation.gateway.watch('rack.request.body') do |stack, request|
104
+ Instrumentation.gateway.watch('rack.request.body', :appsec) do |stack, request|
102
105
  block = false
103
106
  event = nil
104
107
  waf_context = request.env['datadog.waf.context']
@@ -107,23 +110,24 @@ module Datadog
107
110
  trace = active_trace
108
111
  span = active_span
109
112
 
110
- Rack::Reactive::RequestBody.subscribe(op, waf_context) do |action, result, _block|
111
- record = [:block, :monitor].include?(action)
112
- if record
113
+ Rack::Reactive::RequestBody.subscribe(op, waf_context) do |result, _block|
114
+ if result.status == :match
113
115
  # TODO: should this hash be an Event instance instead?
114
116
  event = {
115
117
  waf_result: result,
116
118
  trace: trace,
117
119
  span: span,
118
120
  request: request,
119
- action: action
121
+ actions: result.actions
120
122
  }
121
123
 
124
+ span.set_tag('appsec.event', 'true') if span
125
+
122
126
  waf_context.events << event
123
127
  end
124
128
  end
125
129
 
126
- _action, _result, block = Rack::Reactive::RequestBody.publish(op, request)
130
+ _result, block = Rack::Reactive::RequestBody.publish(op, request)
127
131
  end
128
132
 
129
133
  next [nil, [[:block, event]]] if block
@@ -138,6 +142,8 @@ module Datadog
138
142
  [ret, res]
139
143
  end
140
144
  end
145
+ # rubocop:enable Metrics/CyclomaticComplexity
146
+ # rubocop:enable Metrics/PerceivedComplexity
141
147
  # rubocop:enable Metrics/MethodLength
142
148
  # rubocop:enable Metrics/AbcSize
143
149
 
@@ -161,7 +167,6 @@ module Datadog
161
167
  end
162
168
  end
163
169
  end
164
- # rubocop:enable Metrics/ModuleLength
165
170
  end
166
171
  end
167
172
  end
@@ -54,27 +54,27 @@ module Datadog
54
54
  }
55
55
 
56
56
  waf_timeout = Datadog::AppSec.settings.waf_timeout
57
- action, result = waf_context.run(waf_args, waf_timeout)
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
- # TODO: encapsulate return array in a type
62
- case action
63
- when :monitor
61
+ case result.status
62
+ when :match
64
63
  Datadog.logger.debug { "WAF: #{result.inspect}" }
65
- yield [action, result, false]
66
- when :block
67
- Datadog.logger.debug { "WAF: #{result.inspect}" }
68
- yield [action, result, true]
69
- throw(:block, [action, result, true])
70
- when :good
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: #{action.inspect} #{result.inspect}" }
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
- action, result = waf_context.run(waf_args, waf_timeout)
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
- # TODO: encapsulate return array in a type
40
- case action
41
- when :monitor
39
+ case result.status
40
+ when :match
42
41
  Datadog.logger.debug { "WAF: #{result.inspect}" }
43
- yield [action, result, false]
44
- when :block
45
- Datadog.logger.debug { "WAF: #{result.inspect}" }
46
- yield [action, result, true]
47
- throw(:block, [action, result, true])
48
- when :good
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: #{action.inspect} #{result.inspect}" }
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
- action, result = waf_context.run(waf_args, waf_timeout)
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
- # TODO: encapsulate return array in a type
40
- case action
41
- when :monitor
39
+ case result.status
40
+ when :match
42
41
  Datadog.logger.debug { "WAF: #{result.inspect}" }
43
- yield [action, result, false]
44
- when :block
45
- Datadog.logger.debug { "WAF: #{result.inspect}" }
46
- yield [action, result, true]
47
- throw(:block, [action, result, true])
48
- when :good
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: #{action.inspect} #{result.inspect}" }
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 |action, result, _block|
26
- record = [:block, :monitor].include?(action)
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
- action: action
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
- _action, _result, block = Rails::Reactive::Action.publish(op, request)
42
+ _result, block = Rails::Reactive::Action.publish(op, request)
42
43
  end
43
44
 
44
45
  next [nil, [[:block, event]]] if block
@@ -19,7 +19,7 @@ module Datadog
19
19
  register_as :rails, auto_patch: false
20
20
 
21
21
  def self.version
22
- Gem.loaded_specs['rails'] && Gem.loaded_specs['rails'].version
22
+ Gem.loaded_specs['railties'] && Gem.loaded_specs['railties'].version
23
23
  end
24
24
 
25
25
  def self.loaded?
@@ -36,27 +36,27 @@ module Datadog
36
36
  }
37
37
 
38
38
  waf_timeout = Datadog::AppSec.settings.waf_timeout
39
- action, result = waf_context.run(waf_args, waf_timeout)
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
- # TODO: encapsulate return array in a type
44
- case action
45
- when :monitor
43
+ case result.status
44
+ when :match
46
45
  Datadog.logger.debug { "WAF: #{result.inspect}" }
47
- yield [action, result, false]
48
- when :block
49
- Datadog.logger.debug { "WAF: #{result.inspect}" }
50
- yield [action, result, true]
51
- throw(:block, [action, result, true])
52
- when :good
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: #{action.inspect} #{result.inspect}" }
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 |action, result, _block|
28
- record = [:block, :monitor].include?(action)
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
- action: action
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
- _action, _result, block = Rack::Reactive::RequestBody.publish(op, request)
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 |action, result, _block|
68
- record = [:block, :monitor].include?(action)
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
- action: action
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
- _action, _result, block = Sinatra::Reactive::Routed.publish(op, [request, route_params])
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
- action, result = waf_context.run(waf_args, waf_timeout)
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
- # TODO: encapsulate return array in a type
39
- case action
40
- when :monitor
38
+ case result.status
39
+ when :match
41
40
  Datadog.logger.debug { "WAF: #{result.inspect}" }
42
- yield [action, result, false]
43
- when :block
44
- Datadog.logger.debug { "WAF: #{result.inspect}" }
45
- yield [action, result, true]
46
- throw(:block, [action, result, true])
47
- when :good
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: #{action.inspect} #{result.inspect}" }
54
+ Datadog.logger.debug { "WAF UNKNOWN: #{result.status.inspect} #{result.inspect}" }
55
55
  end
56
56
  end
57
57
  end
@@ -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
- ret, res = @context.run(*args)
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
- [ret, res]
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