sqreen 1.20.4.beta1 → 1.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/lib/sqreen/condition_evaluator.rb +8 -2
- data/lib/sqreen/deliveries/batch.rb +8 -1
- data/lib/sqreen/ecosystem.rb +123 -0
- data/lib/sqreen/ecosystem/databases/database_connection_data.rb +23 -0
- data/lib/sqreen/ecosystem/databases/mongo.rb +39 -0
- data/lib/sqreen/ecosystem/databases/mysql.rb +54 -0
- data/lib/sqreen/ecosystem/databases/postgres.rb +51 -0
- data/lib/sqreen/ecosystem/databases/redis.rb +36 -0
- data/lib/sqreen/ecosystem/dispatch_table.rb +43 -0
- data/lib/sqreen/ecosystem/exception_reporting.rb +28 -0
- data/lib/sqreen/ecosystem/http/net_http.rb +50 -0
- data/lib/sqreen/ecosystem/http/rack_request.rb +39 -0
- data/lib/sqreen/ecosystem/loggable.rb +13 -0
- data/lib/sqreen/ecosystem/messaging/bunny.rb +61 -0
- data/lib/sqreen/ecosystem/messaging/kafka.rb +70 -0
- data/lib/sqreen/ecosystem/messaging/kinesis.rb +66 -0
- data/lib/sqreen/ecosystem/messaging/sqs.rb +68 -0
- data/lib/sqreen/ecosystem/module_api.rb +30 -0
- data/lib/sqreen/ecosystem/module_api/event_listener.rb +18 -0
- data/lib/sqreen/ecosystem/module_api/instrumentation.rb +23 -0
- data/lib/sqreen/ecosystem/module_api/message_producer.rb +57 -0
- data/lib/sqreen/ecosystem/module_api/signal_producer.rb +24 -0
- data/lib/sqreen/ecosystem/module_api/tracing.rb +45 -0
- data/lib/sqreen/ecosystem/module_api/tracing/client_data.rb +31 -0
- data/lib/sqreen/ecosystem/module_api/tracing/consumer_data.rb +13 -0
- data/lib/sqreen/ecosystem/module_api/tracing/messaging_data.rb +35 -0
- data/lib/sqreen/ecosystem/module_api/tracing/producer_data.rb +13 -0
- data/lib/sqreen/ecosystem/module_api/tracing/server_data.rb +27 -0
- data/lib/sqreen/ecosystem/module_api/tracing_id_generation.rb +16 -0
- data/lib/sqreen/ecosystem/module_api/transaction_storage.rb +71 -0
- data/lib/sqreen/ecosystem/module_registry.rb +48 -0
- data/lib/sqreen/ecosystem/tracing/modules/client.rb +35 -0
- data/lib/sqreen/ecosystem/tracing/modules/consumer.rb +35 -0
- data/lib/sqreen/ecosystem/tracing/modules/determine_ip.rb +28 -0
- data/lib/sqreen/ecosystem/tracing/modules/producer.rb +35 -0
- data/lib/sqreen/ecosystem/tracing/modules/server.rb +30 -0
- data/lib/sqreen/ecosystem/tracing/sampler.rb +160 -0
- data/lib/sqreen/ecosystem/tracing/sampling_configuration.rb +150 -0
- data/lib/sqreen/ecosystem/tracing/signals/tracing_client.rb +53 -0
- data/lib/sqreen/ecosystem/tracing/signals/tracing_consumer.rb +56 -0
- data/lib/sqreen/ecosystem/tracing/signals/tracing_producer.rb +56 -0
- data/lib/sqreen/ecosystem/tracing/signals/tracing_server.rb +53 -0
- data/lib/sqreen/ecosystem/tracing_broker.rb +101 -0
- data/lib/sqreen/ecosystem/tracing_id_setup.rb +34 -0
- data/lib/sqreen/ecosystem/transaction_storage.rb +64 -0
- data/lib/sqreen/ecosystem/util/call_writers_from_init.rb +13 -0
- data/lib/sqreen/ecosystem_integration.rb +81 -0
- data/lib/sqreen/ecosystem_integration/around_callbacks.rb +89 -0
- data/lib/sqreen/ecosystem_integration/instrumentation_service.rb +38 -0
- data/lib/sqreen/ecosystem_integration/request_lifecycle_tracking.rb +58 -0
- data/lib/sqreen/ecosystem_integration/signal_consumption.rb +35 -0
- data/lib/sqreen/events/request_record.rb +0 -1
- data/lib/sqreen/frameworks/generic.rb +15 -1
- data/lib/sqreen/frameworks/request_recorder.rb +2 -0
- data/lib/sqreen/graft/call.rb +9 -0
- data/lib/sqreen/graft/hook.rb +5 -3
- data/lib/sqreen/graft/hook_point.rb +17 -10
- data/lib/sqreen/kit/signals/specialized/sqreen_exception.rb +2 -0
- data/lib/sqreen/legacy/old_event_submission_strategy.rb +9 -2
- data/lib/sqreen/remote_command.rb +3 -0
- data/lib/sqreen/rules.rb +7 -3
- data/lib/sqreen/rules/custom_error_cb.rb +3 -3
- data/lib/sqreen/rules/waf_cb.rb +3 -3
- data/lib/sqreen/runner.rb +19 -5
- data/lib/sqreen/session.rb +2 -0
- data/lib/sqreen/signals/conversions.rb +6 -1
- data/lib/sqreen/version.rb +1 -1
- data/lib/sqreen/weave/legacy/instrumentation.rb +38 -19
- metadata +57 -11
- data/lib/sqreen/encoding_sanitizer.rb +0 -27
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require 'sqreen/log/loggable'
|
|
2
|
+
require 'sqreen/events/remote_exception'
|
|
3
|
+
require 'sqreen/mono_time'
|
|
4
|
+
|
|
5
|
+
module Sqreen
|
|
6
|
+
class EcosystemIntegration
|
|
7
|
+
module AroundCallbacks
|
|
8
|
+
class << self
|
|
9
|
+
include Log::Loggable::ClassMethods
|
|
10
|
+
|
|
11
|
+
# for instrumentation hooks
|
|
12
|
+
# instrumentation hooks already handle budgets, so nothing
|
|
13
|
+
# to do in that respect
|
|
14
|
+
def wrap_instrumentation_hook(module_name, action, callable)
|
|
15
|
+
perf_notif_name = "ecosystem_#{module_name}"
|
|
16
|
+
|
|
17
|
+
Proc.new do |*args|
|
|
18
|
+
begin
|
|
19
|
+
start = Sqreen.time
|
|
20
|
+
callable.call(*args)
|
|
21
|
+
rescue ::Exception => e # rubocop:disable Lint/RescueException
|
|
22
|
+
# 2) rescue exceptions
|
|
23
|
+
logger.warn { "Error in #{module_name}:#{action}: #{e.message}" }
|
|
24
|
+
logger.debug { e.backtrace.map { |x| " #{x}" }.join("\n") }
|
|
25
|
+
Sqreen::RemoteException.record(e)
|
|
26
|
+
ensure
|
|
27
|
+
# 3) contribute to performance metrics
|
|
28
|
+
stop = Sqreen.time
|
|
29
|
+
Sqreen::PerformanceNotifications.notify(perf_notif_name, action, start, stop)
|
|
30
|
+
end # end proc
|
|
31
|
+
end # end begin
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# XXX: not used yet
|
|
35
|
+
def wrap_generic_callback(module_name, action, callable)
|
|
36
|
+
timer_name = "ecosystem:#{module_name}@#{action}"
|
|
37
|
+
perf_notif_name = "ecosystem_#{module_name}"
|
|
38
|
+
|
|
39
|
+
Proc.new do |*args|
|
|
40
|
+
begin
|
|
41
|
+
req_storage = Thread.current[:sqreen_http_request]
|
|
42
|
+
|
|
43
|
+
timer = Graft::Timer.new(timer_name) do |t|
|
|
44
|
+
# this is an epilogue to measure()
|
|
45
|
+
req_storage && req_storage[:timed_hooks] << t
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
req_timer = nil
|
|
49
|
+
timer.measure do
|
|
50
|
+
# not in a request, no budget; call cb
|
|
51
|
+
next callable.call(*args) unless req_storage
|
|
52
|
+
|
|
53
|
+
# 1) budget enforcement
|
|
54
|
+
# skip callback if budget already expended
|
|
55
|
+
next if req_storage[:time_budget_expended]
|
|
56
|
+
|
|
57
|
+
budget = req_storage[:time_budget]
|
|
58
|
+
if budget
|
|
59
|
+
req_timer = req_storage[:timer]
|
|
60
|
+
remaining = budget - req_timer.elapsed
|
|
61
|
+
unless remaining > 0
|
|
62
|
+
req_storage[:time_budget_expended] = true
|
|
63
|
+
next # skip callback
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
callable.call(*args)
|
|
68
|
+
end
|
|
69
|
+
rescue ::Exception => e # rubocop:disable Lint/RescueException
|
|
70
|
+
# 2) rescue exceptions
|
|
71
|
+
logger.warn { "Error in #{module_name}:#{action}: #{e.message}" }
|
|
72
|
+
logger.debug { e.backtrace.map { |x| " #{x}" }.join("\n") }
|
|
73
|
+
Sqreen::RemoteException.record(e)
|
|
74
|
+
ensure
|
|
75
|
+
# 3) contribute to performance metrics
|
|
76
|
+
if timer
|
|
77
|
+
req_timer.include_measurements(timer) if req_timer
|
|
78
|
+
|
|
79
|
+
Sqreen::PerformanceNotifications.notify(
|
|
80
|
+
perf_notif_name, action, *timer.start_and_end
|
|
81
|
+
)
|
|
82
|
+
end
|
|
83
|
+
end # end begin
|
|
84
|
+
end # end proc
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'sqreen/graft/hook'
|
|
2
|
+
require 'sqreen/ecosystem_integration/around_callbacks'
|
|
3
|
+
|
|
4
|
+
module Sqreen
|
|
5
|
+
class EcosystemIntegration
|
|
6
|
+
module InstrumentationService
|
|
7
|
+
class << self
|
|
8
|
+
# @param [String] module_name
|
|
9
|
+
# @param [String] method in form A::B#c or A::B.c
|
|
10
|
+
# @param [Hash{Symbol=>Proc}] spec
|
|
11
|
+
def instrument(module_name, method, spec)
|
|
12
|
+
hook = Sqreen::Graft::Hook[method].add do
|
|
13
|
+
if spec[:before]
|
|
14
|
+
cb = AroundCallbacks.wrap_instrumentation_hook(module_name, 'pre', spec[:before])
|
|
15
|
+
before(nil, flow: true, &cb)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
if spec[:after]
|
|
19
|
+
cb = AroundCallbacks.wrap_instrumentation_hook(module_name, 'post', spec[:after])
|
|
20
|
+
after(nil, flow: true, &cb)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
if spec[:raised]
|
|
24
|
+
cb = AroundCallbacks.wrap_instrumentation_hook(module_name, 'failing', spec[:raised])
|
|
25
|
+
raised(nil, flow: true, &cb)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
if spec[:ensured]
|
|
29
|
+
cb = AroundCallbacks.wrap_instrumentation_hook(module_name, 'finally', spec[:ensured])
|
|
30
|
+
ensured(nil, flow: true, &cb)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
hook.install
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'sqreen/events/remote_exception'
|
|
2
|
+
require 'sqreen/log/loggable'
|
|
3
|
+
|
|
4
|
+
module Sqreen
|
|
5
|
+
class EcosystemIntegration
|
|
6
|
+
# This class gets notified of request start/end and
|
|
7
|
+
# 1) distributes such events to listeners (typically ecosystem modules;
|
|
8
|
+
# the method add_start_observer is exposed to ecosystem modules through
|
|
9
|
+
# +Sqreen::Ecosystem::ModuleApi::EventListener+ and the dispatch table).
|
|
10
|
+
# 2) keeps track of whether a request is active on this thread. This is
|
|
11
|
+
# so that users of this class can have this information without needing
|
|
12
|
+
# to subscribe to request start/events and keeping thread local state
|
|
13
|
+
# themselves.
|
|
14
|
+
# XXX: Since the Ecosystem is also notified of request start/end, it could
|
|
15
|
+
# notify its modules of request start without going through the dispatch
|
|
16
|
+
# table and call add_start_observer. We need to think if we want to keep
|
|
17
|
+
# the transaction / request distinction or if they should just be
|
|
18
|
+
# assumed to be the same, though.
|
|
19
|
+
class RequestLifecycleTracking
|
|
20
|
+
include Sqreen::Log::Loggable
|
|
21
|
+
|
|
22
|
+
def initialize
|
|
23
|
+
@start_observers = []
|
|
24
|
+
@tl_key = "#{object_id}_req_in_flight"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# API for classes needing to know the request state
|
|
28
|
+
|
|
29
|
+
# @param cb A callback taking a Rack::Request
|
|
30
|
+
def add_start_observer(cb)
|
|
31
|
+
@start_observers << cb
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def in_request?
|
|
35
|
+
Thread.current[@tl_key] ? true : false
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# API for classes notifying this one of request events
|
|
39
|
+
|
|
40
|
+
def notify_request_start(rack_req)
|
|
41
|
+
Thread.current[@tl_key] = true
|
|
42
|
+
return if @start_observers.empty?
|
|
43
|
+
@start_observers.each do |cb|
|
|
44
|
+
begin
|
|
45
|
+
cb.call(rack_req)
|
|
46
|
+
rescue ::Exception => e # rubocop:disable Lint/RescueException
|
|
47
|
+
logger.warn { "Error calling #{cb} on request start: #{e.message}" }
|
|
48
|
+
Sqreen::RemoteException.record(e)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def notify_request_end
|
|
54
|
+
Thread.current[@tl_key] = false
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'sqreen/log/loggable'
|
|
2
|
+
|
|
3
|
+
module Sqreen
|
|
4
|
+
class EcosystemIntegration
|
|
5
|
+
class SignalConsumption
|
|
6
|
+
include Sqreen::Log::Loggable
|
|
7
|
+
|
|
8
|
+
PAYLOAD_CREATOR_SECTIONS = %w[request response params headers].freeze
|
|
9
|
+
|
|
10
|
+
# @param [Sqreen::Frameworks::GenericFramework] framework
|
|
11
|
+
# @param [Sqreen::EcosystemIntegration::RequestLifecycleTracking]
|
|
12
|
+
# @param [Sqreen::CappedQueue]
|
|
13
|
+
def initialize(framework, req_lifecycle, queue)
|
|
14
|
+
@framework = framework
|
|
15
|
+
@req_lifecycle = req_lifecycle
|
|
16
|
+
@queue = queue
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def consume_signal(signal)
|
|
20
|
+
# transitional
|
|
21
|
+
unless Sqreen.features.fetch('use_signals', DEFAULT_USE_SIGNALS)
|
|
22
|
+
logger.debug { "Discarding signal #{signal} (signals disabled)" }
|
|
23
|
+
return
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if @req_lifecycle.in_request?
|
|
27
|
+
# add it to the request record
|
|
28
|
+
@framework.observe(:signals, signal, PAYLOAD_CREATOR_SECTIONS, true)
|
|
29
|
+
else
|
|
30
|
+
@queue.push signal
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -22,8 +22,17 @@ module Sqreen
|
|
|
22
22
|
include RequestRecorder
|
|
23
23
|
attr_accessor :sqreen_configuration
|
|
24
24
|
|
|
25
|
+
attr_writer :req_start_cb, :req_end_cb
|
|
26
|
+
|
|
25
27
|
def initialize
|
|
26
28
|
clean_request_record
|
|
29
|
+
|
|
30
|
+
# for notifying the ecosystem of request boundaries
|
|
31
|
+
# XXX: this should be refactored. It shouldn't be
|
|
32
|
+
# the framework doing these notifications to the ecosystem
|
|
33
|
+
# Probably the rule callback should do it itself
|
|
34
|
+
@req_start_cb = Proc.new {}
|
|
35
|
+
@req_end_cb = Proc.new {}
|
|
27
36
|
end
|
|
28
37
|
|
|
29
38
|
# What kind of database is this
|
|
@@ -260,8 +269,12 @@ module Sqreen
|
|
|
260
269
|
# Nota: cleanup should be performed at end of request (see clean_request)
|
|
261
270
|
def store_request(object)
|
|
262
271
|
return unless ensure_rack_loaded
|
|
272
|
+
|
|
273
|
+
rack_req = Rack::Request.new(object)
|
|
274
|
+
@req_start_cb.call(rack_req)
|
|
275
|
+
|
|
263
276
|
self.remaining_perf_budget = Sqreen.performance_budget
|
|
264
|
-
SharedStorage.set(:request,
|
|
277
|
+
SharedStorage.set(:request, rack_req)
|
|
265
278
|
SharedStorage.set(:xss_params, nil)
|
|
266
279
|
SharedStorage.set(:whitelisted, nil)
|
|
267
280
|
SharedStorage.set(:request_overtime, nil)
|
|
@@ -290,6 +303,7 @@ module Sqreen
|
|
|
290
303
|
SharedStorage.set(:xss_params, nil)
|
|
291
304
|
SharedStorage.set(:whitelisted, nil)
|
|
292
305
|
SharedStorage.set(:request_overtime, nil)
|
|
306
|
+
@req_end_cb.call
|
|
293
307
|
end
|
|
294
308
|
|
|
295
309
|
def remaining_perf_budget
|
|
@@ -69,6 +69,8 @@ module Sqreen
|
|
|
69
69
|
|
|
70
70
|
# signals require request section to be present
|
|
71
71
|
payload_requests << 'request'
|
|
72
|
+
# for signals, response is optional, but the backend team wants them
|
|
73
|
+
payload_requests << 'response'
|
|
72
74
|
payload = payload_creator.payload(payload_requests)
|
|
73
75
|
payload[:observed] = observed_items
|
|
74
76
|
|
data/lib/sqreen/graft/call.rb
CHANGED
|
@@ -195,6 +195,15 @@ module Sqreen
|
|
|
195
195
|
@size.even?
|
|
196
196
|
end
|
|
197
197
|
|
|
198
|
+
def include_measurements(another_timer)
|
|
199
|
+
@blips += another_timer.instance_variable_get(:@blips)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def start_and_end
|
|
203
|
+
raise 'Not exactly two measurements recorded' unless size == 2
|
|
204
|
+
@blips
|
|
205
|
+
end
|
|
206
|
+
|
|
198
207
|
def to_s
|
|
199
208
|
"#{@tag}: time=%.03fus" % (duration * 1_000_000)
|
|
200
209
|
end
|
data/lib/sqreen/graft/hook.rb
CHANGED
|
@@ -11,13 +11,15 @@ require 'sqreen/graft/hook_point'
|
|
|
11
11
|
module Sqreen
|
|
12
12
|
module Graft
|
|
13
13
|
class Hook
|
|
14
|
+
DEFAULT_STRATEGY = Sqreen::Graft::HookPoint::DEFAULT_STRATEGY
|
|
15
|
+
|
|
14
16
|
@hooks = {}
|
|
15
17
|
|
|
16
|
-
def self.[](hook_point, strategy =
|
|
18
|
+
def self.[](hook_point, strategy = DEFAULT_STRATEGY)
|
|
17
19
|
@hooks[hook_point] ||= new(hook_point, nil, strategy)
|
|
18
20
|
end
|
|
19
21
|
|
|
20
|
-
def self.add(hook_point, strategy =
|
|
22
|
+
def self.add(hook_point, strategy = DEFAULT_STRATEGY, &block)
|
|
21
23
|
self[hook_point, strategy].add(&block)
|
|
22
24
|
end
|
|
23
25
|
|
|
@@ -30,7 +32,7 @@ module Sqreen
|
|
|
30
32
|
|
|
31
33
|
attr_reader :point
|
|
32
34
|
|
|
33
|
-
def initialize(hook_point, dependency_test = nil, strategy =
|
|
35
|
+
def initialize(hook_point, dependency_test = nil, strategy = DEFAULT_STRATEGY)
|
|
34
36
|
@disabled = false
|
|
35
37
|
@point = hook_point.is_a?(HookPoint) ? hook_point : HookPoint.new(hook_point, strategy)
|
|
36
38
|
@before = []
|
|
@@ -23,6 +23,8 @@ module Sqreen
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
class HookPoint
|
|
26
|
+
DEFAULT_STRATEGY = Module.respond_to?(:prepend) ? :prepend : :chain
|
|
27
|
+
|
|
26
28
|
def self.parse(hook_point)
|
|
27
29
|
klass_name, separator, method_name = hook_point.split(/(\#|\.)/, 2)
|
|
28
30
|
|
|
@@ -36,7 +38,7 @@ module Sqreen
|
|
|
36
38
|
|
|
37
39
|
attr_reader :klass_name, :method_kind, :method_name
|
|
38
40
|
|
|
39
|
-
def initialize(hook_point, strategy =
|
|
41
|
+
def initialize(hook_point, strategy = DEFAULT_STRATEGY)
|
|
40
42
|
@klass_name, @method_kind, @method_name = Sqreen::Graft::HookPoint.parse(hook_point)
|
|
41
43
|
@strategy = strategy
|
|
42
44
|
end
|
|
@@ -177,23 +179,30 @@ module Sqreen
|
|
|
177
179
|
|
|
178
180
|
private
|
|
179
181
|
|
|
180
|
-
def
|
|
182
|
+
def hook_spot(key)
|
|
181
183
|
target = klass_method? ? klass.singleton_class : klass
|
|
182
184
|
mod = target.ancestors.each { |e| break if e == target; break(e) if e.class == HookSpot && e.key == key }
|
|
185
|
+
raise "Inconsistency detected: #{target} missing from its own ancestors" if mod.is_a?(Array)
|
|
186
|
+
|
|
187
|
+
[target, mod]
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def prepend(key)
|
|
191
|
+
target, mod = hook_spot(key)
|
|
192
|
+
|
|
183
193
|
mod ||= HookSpot.new(key)
|
|
194
|
+
|
|
184
195
|
target.instance_eval { prepend(mod) }
|
|
185
196
|
end
|
|
186
197
|
|
|
187
198
|
def prepended?(key)
|
|
188
|
-
|
|
189
|
-
mod = target.ancestors.each { |e| break if e == target; break(e) if e.class == HookSpot && e.key == key }
|
|
199
|
+
_, mod = hook_spot(key)
|
|
190
200
|
|
|
191
201
|
mod != nil
|
|
192
202
|
end
|
|
193
203
|
|
|
194
204
|
def overridden?(key)
|
|
195
|
-
|
|
196
|
-
mod = target.ancestors.each { |e| break if e == target; break(e) if e.class == HookSpot && e.key == key }
|
|
205
|
+
_, mod = hook_spot(key)
|
|
197
206
|
|
|
198
207
|
(mod.instance_methods(false) + mod.protected_instance_methods(false) + mod.private_instance_methods(false)).include?(method_name)
|
|
199
208
|
end
|
|
@@ -202,8 +211,7 @@ module Sqreen
|
|
|
202
211
|
hook_point = self
|
|
203
212
|
method_name = @method_name
|
|
204
213
|
|
|
205
|
-
|
|
206
|
-
mod = target.ancestors.each { |e| break if e == target; break(e) if e.class == HookSpot && e.key == key }
|
|
214
|
+
_, mod = hook_spot(key)
|
|
207
215
|
|
|
208
216
|
mod.instance_eval do
|
|
209
217
|
if hook_point.private_method?
|
|
@@ -221,8 +229,7 @@ module Sqreen
|
|
|
221
229
|
def unoverride(key)
|
|
222
230
|
method_name = @method_name
|
|
223
231
|
|
|
224
|
-
|
|
225
|
-
mod = target.ancestors.each { |e| break if e == target; break(e) if e.class == HookSpot && e.key == key }
|
|
232
|
+
_, mod = hook_spot(key)
|
|
226
233
|
|
|
227
234
|
mod.instance_eval { remove_method(method_name) }
|
|
228
235
|
end
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
4
4
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
5
5
|
|
|
6
|
+
require 'sqreen/kit/configuration'
|
|
6
7
|
require 'sqreen/kit/signals/point'
|
|
7
8
|
require 'sqreen/kit/signals/dto_helper'
|
|
8
9
|
|
|
@@ -38,6 +39,7 @@ class Sqreen::Kit::Signals::Specialized::SqreenException < Sqreen::Kit::Signals:
|
|
|
38
39
|
self.payload_schema = PAYLOAD_SCHEMA_VERSION
|
|
39
40
|
self.signal_name = 'sq.agent.exception'
|
|
40
41
|
self.time = values[:time] || Time.now
|
|
42
|
+
self.source = values[:source] || Sqreen::Kit::Configuration.default_source
|
|
41
43
|
super
|
|
42
44
|
end
|
|
43
45
|
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
require 'sqreen/aggregated_metric'
|
|
7
7
|
require 'sqreen/log/loggable'
|
|
8
8
|
require 'sqreen/legacy/waf_redactions'
|
|
9
|
+
require 'sqreen/kit/string_sanitizer'
|
|
9
10
|
|
|
10
11
|
module Sqreen
|
|
11
12
|
module Legacy
|
|
@@ -55,6 +56,12 @@ module Sqreen
|
|
|
55
56
|
when AggregatedMetric
|
|
56
57
|
logger.warn "Aggregated metric event in non-signal mode. Signals disabled at runtime?"
|
|
57
58
|
next
|
|
59
|
+
when Sqreen::Kit::Signals::Signal
|
|
60
|
+
logger.warn "Signal event in non-signal mode"
|
|
61
|
+
next
|
|
62
|
+
when Sqreen::Kit::Signals::Trace
|
|
63
|
+
logger.warn "Trace event in non-signal mode"
|
|
64
|
+
next
|
|
58
65
|
when Attack # in practice only found inside req rec
|
|
59
66
|
EventToHash.convert_attack event
|
|
60
67
|
when RemoteException
|
|
@@ -72,7 +79,7 @@ module Sqreen
|
|
|
72
79
|
tally = Hash[events.group_by(&:class).map { |k, v| [k, v.count] }]
|
|
73
80
|
"Doing batch with the following tally of event types: #{tally}"
|
|
74
81
|
end
|
|
75
|
-
post('batch', { batch: batch }, {}, RETRY_MANY)
|
|
82
|
+
post('batch', { batch: batch.compact }, {}, RETRY_MANY)
|
|
76
83
|
end
|
|
77
84
|
|
|
78
85
|
private
|
|
@@ -166,7 +173,7 @@ module Sqreen
|
|
|
166
173
|
res[:request][:parameters] = payload['params'] if payload['params']
|
|
167
174
|
res[:request][:headers] = payload['headers'] if payload['headers']
|
|
168
175
|
|
|
169
|
-
res = Sqreen::
|
|
176
|
+
res = Sqreen::Kit::StringSanitizer.sanitize(res)
|
|
170
177
|
|
|
171
178
|
if rr.redactor
|
|
172
179
|
res[:request], redacted = rr.redactor.redact(res[:request])
|