sqreen 1.19.1-java → 1.21.0.beta3-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +34 -0
- data/lib/sqreen/actions/block_user.rb +1 -1
- data/lib/sqreen/actions/redirect_ip.rb +1 -1
- data/lib/sqreen/actions/redirect_user.rb +1 -1
- data/lib/sqreen/agent_message.rb +20 -0
- data/lib/sqreen/aggregated_metric.rb +25 -0
- data/lib/sqreen/attack_detected.html +1 -2
- data/lib/sqreen/ca.crt +24 -0
- data/lib/sqreen/condition_evaluator.rb +9 -2
- data/lib/sqreen/conditionable.rb +24 -6
- data/lib/sqreen/configuration.rb +11 -5
- data/lib/sqreen/deferred_logger.rb +50 -14
- data/lib/sqreen/deliveries/batch.rb +12 -2
- data/lib/sqreen/deliveries/simple.rb +4 -0
- data/lib/sqreen/deprecation.rb +38 -0
- data/lib/sqreen/ecosystem.rb +96 -0
- data/lib/sqreen/ecosystem/dispatch_table.rb +43 -0
- data/lib/sqreen/ecosystem/exception_reporting.rb +26 -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/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 +51 -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/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 +44 -0
- data/lib/sqreen/ecosystem/redis/redis_connection.rb +43 -0
- data/lib/sqreen/ecosystem/tracing/modules/client.rb +31 -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_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 +87 -0
- data/lib/sqreen/ecosystem_integration/around_callbacks.rb +99 -0
- data/lib/sqreen/ecosystem_integration/instrumentation_service.rb +42 -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/endpoint_testing.rb +184 -0
- data/lib/sqreen/event.rb +7 -5
- data/lib/sqreen/events/attack.rb +23 -18
- data/lib/sqreen/events/remote_exception.rb +0 -22
- data/lib/sqreen/events/request_record.rb +15 -71
- data/lib/sqreen/frameworks/generic.rb +24 -1
- data/lib/sqreen/frameworks/rails.rb +0 -7
- data/lib/sqreen/frameworks/request_recorder.rb +15 -2
- data/lib/sqreen/graft/call.rb +106 -19
- data/lib/sqreen/graft/callback.rb +1 -1
- data/lib/sqreen/graft/hook.rb +212 -100
- data/lib/sqreen/graft/hook_point.rb +18 -11
- data/lib/sqreen/kit/signals/specialized/aggregated_metric.rb +72 -0
- data/lib/sqreen/kit/signals/specialized/attack.rb +57 -0
- data/lib/sqreen/kit/signals/specialized/binning_metric.rb +76 -0
- data/lib/sqreen/kit/signals/specialized/http_trace.rb +26 -0
- data/lib/sqreen/kit/signals/specialized/sdk_track_call.rb +50 -0
- data/lib/sqreen/kit/signals/specialized/sqreen_exception.rb +57 -0
- data/lib/sqreen/legacy/instrumentation.rb +22 -10
- data/lib/sqreen/legacy/old_event_submission_strategy.rb +228 -0
- data/lib/sqreen/legacy/waf_redactions.rb +49 -0
- data/lib/sqreen/log.rb +3 -2
- data/lib/sqreen/log/loggable.rb +2 -1
- data/lib/sqreen/logger.rb +24 -0
- data/lib/sqreen/metrics.rb +1 -0
- data/lib/sqreen/metrics/base.rb +3 -0
- data/lib/sqreen/metrics/req_detailed.rb +41 -0
- data/lib/sqreen/metrics_store.rb +33 -12
- data/lib/sqreen/null_logger.rb +22 -0
- data/lib/sqreen/performance_notifications/binned_metrics.rb +8 -2
- data/lib/sqreen/remote_command.rb +4 -0
- data/lib/sqreen/rules.rb +12 -6
- data/lib/sqreen/rules/blacklist_ips_cb.rb +2 -2
- data/lib/sqreen/rules/custom_error_cb.rb +3 -3
- data/lib/sqreen/rules/not_found_cb.rb +2 -0
- data/lib/sqreen/rules/rule_cb.rb +6 -2
- data/lib/sqreen/rules/waf_cb.rb +16 -13
- data/lib/sqreen/runner.rb +138 -16
- data/lib/sqreen/sensitive_data_redactor.rb +19 -31
- data/lib/sqreen/session.rb +53 -43
- data/lib/sqreen/signals/conversions.rb +288 -0
- data/lib/sqreen/signals/http_trace_redaction.rb +111 -0
- data/lib/sqreen/signals/signals_submission_strategy.rb +78 -0
- data/lib/sqreen/version.rb +1 -1
- data/lib/sqreen/weave/budget.rb +35 -0
- data/lib/sqreen/weave/legacy/instrumentation.rb +277 -135
- data/lib/sqreen/worker.rb +6 -2
- metadata +86 -10
- data/lib/sqreen/backport.rb +0 -9
- data/lib/sqreen/backport/clock_gettime.rb +0 -74
- data/lib/sqreen/backport/original_name.rb +0 -88
- data/lib/sqreen/encoding_sanitizer.rb +0 -27
@@ -21,7 +21,7 @@ module Sqreen
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def call(*args, &block)
|
24
|
-
Sqreen::Graft.logger.debug { "[#{Process.pid}] Callback #{@name} disabled:#{disabled?}" }
|
24
|
+
# Sqreen::Graft.logger.debug { "[#{Process.pid}] Callback #{@name} disabled:#{disabled?}" } if Sqreen::Graft.logger.debug?
|
25
25
|
return if @disabled
|
26
26
|
@block.call(*args, &block)
|
27
27
|
end
|
data/lib/sqreen/graft/hook.rb
CHANGED
@@ -7,23 +7,34 @@ require 'sqreen/graft'
|
|
7
7
|
require 'sqreen/graft/call'
|
8
8
|
require 'sqreen/graft/callback'
|
9
9
|
require 'sqreen/graft/hook_point'
|
10
|
+
require 'sqreen/weave'
|
11
|
+
require 'sqreen/runner' # Sqreen.queue
|
10
12
|
|
11
13
|
module Sqreen
|
12
14
|
module Graft
|
13
15
|
class Hook
|
16
|
+
DEFAULT_STRATEGY = Sqreen::Graft::HookPoint::DEFAULT_STRATEGY
|
17
|
+
|
14
18
|
@hooks = {}
|
15
19
|
|
16
|
-
def self.[](hook_point, strategy =
|
20
|
+
def self.[](hook_point, strategy = DEFAULT_STRATEGY)
|
17
21
|
@hooks[hook_point] ||= new(hook_point, nil, strategy)
|
18
22
|
end
|
19
23
|
|
20
|
-
def self.add(hook_point, strategy =
|
24
|
+
def self.add(hook_point, strategy = DEFAULT_STRATEGY, &block)
|
21
25
|
self[hook_point, strategy].add(&block)
|
22
26
|
end
|
23
27
|
|
28
|
+
def self.ignore
|
29
|
+
Thread.current[:sqreen_hook_entered] = true
|
30
|
+
yield
|
31
|
+
ensure
|
32
|
+
Thread.current[:sqreen_hook_entered] = false
|
33
|
+
end
|
34
|
+
|
24
35
|
attr_reader :point
|
25
36
|
|
26
|
-
def initialize(hook_point, dependency_test = nil, strategy =
|
37
|
+
def initialize(hook_point, dependency_test = nil, strategy = DEFAULT_STRATEGY)
|
27
38
|
@disabled = false
|
28
39
|
@point = hook_point.is_a?(HookPoint) ? hook_point : HookPoint.new(hook_point, strategy)
|
29
40
|
@before = []
|
@@ -46,27 +57,31 @@ module Sqreen
|
|
46
57
|
end
|
47
58
|
|
48
59
|
def before(tag = nil, opts = {}, &block)
|
49
|
-
return @before
|
60
|
+
return @before if block.nil?
|
50
61
|
|
51
62
|
@before << Callback.new(callback_name(:before, tag), opts, &block)
|
63
|
+
@before.sort_by!(&:rank)
|
52
64
|
end
|
53
65
|
|
54
66
|
def after(tag = nil, opts = {}, &block)
|
55
|
-
return @after
|
67
|
+
return @after if block.nil?
|
56
68
|
|
57
69
|
@after << Callback.new(callback_name(:after, tag), opts, &block)
|
70
|
+
@after.sort_by!(&:rank)
|
58
71
|
end
|
59
72
|
|
60
73
|
def raised(tag = nil, opts = {}, &block)
|
61
|
-
return @raised
|
74
|
+
return @raised if block.nil?
|
62
75
|
|
63
76
|
@raised << Callback.new(callback_name(:raised, tag), opts, &block)
|
77
|
+
@raised.sort_by!(&:rank)
|
64
78
|
end
|
65
79
|
|
66
80
|
def ensured(tag = nil, opts = {}, &block)
|
67
|
-
return @ensured
|
81
|
+
return @ensured if block.nil?
|
68
82
|
|
69
83
|
@ensured << Callback.new(callback_name(:ensured, tag), opts, &block)
|
84
|
+
@ensured.sort_by!(&:rank)
|
70
85
|
end
|
71
86
|
|
72
87
|
def depends_on(&block)
|
@@ -109,11 +124,32 @@ module Sqreen
|
|
109
124
|
@before = []
|
110
125
|
@after = []
|
111
126
|
@raised = []
|
127
|
+
@ensured = []
|
112
128
|
end
|
113
129
|
|
114
130
|
def self.wrapper(hook)
|
131
|
+
timed_hooks_proc = proc do |t|
|
132
|
+
if (request = Thread.current[:sqreen_http_request])
|
133
|
+
request[:timed_hooks] << t if request[:timed_level] >= 1
|
134
|
+
end
|
135
|
+
end
|
136
|
+
timed_callbacks_proc = proc do |t|
|
137
|
+
if (request = Thread.current[:sqreen_http_request])
|
138
|
+
request[:timed_callbacks] << t if request[:timed_level] >= 1
|
139
|
+
end
|
140
|
+
end
|
141
|
+
# very hacky, but the non-local control flow with throw-catch
|
142
|
+
# makes the solution non-obvious. needs to be revisited
|
143
|
+
conditions_passed_proc = proc do
|
144
|
+
if (request = Thread.current[:sqreen_http_request])
|
145
|
+
request[:timed_callbacks].last.conditions_passed = true
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
115
149
|
Proc.new do |*args, &block|
|
116
|
-
|
150
|
+
request = Thread.current[:sqreen_http_request]
|
151
|
+
|
152
|
+
if Thread.current[:sqreen_hook_entered]
|
117
153
|
if hook.point.super?
|
118
154
|
return super(*args, &block)
|
119
155
|
else
|
@@ -121,113 +157,159 @@ module Sqreen
|
|
121
157
|
end
|
122
158
|
end
|
123
159
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
160
|
+
if request && request[:time_budget_expended] && (hook.before + hook.after + hook.raised + hook.ensured).none?(&:mandatory)
|
161
|
+
if request[:timed_level] >= 2
|
162
|
+
begin
|
163
|
+
request[:skipped_callbacks].concat(hook.before)
|
164
|
+
|
165
|
+
if hook.point.super?
|
166
|
+
return super(*args, &block)
|
167
|
+
else
|
168
|
+
return hook.point.apply(self, 'sqreen_hook', *args, &block)
|
169
|
+
end
|
170
|
+
rescue ::Exception # rubocop:disable Lint/RescueException
|
171
|
+
request[:skipped_callbacks].concat(hook.raised)
|
172
|
+
raise
|
173
|
+
else
|
174
|
+
request[:skipped_callbacks].concat(hook.after)
|
175
|
+
ensure
|
176
|
+
request[:skipped_callbacks].concat(hook.ensured)
|
177
|
+
end
|
178
|
+
else
|
179
|
+
if hook.point.super? # rubocop:disable Style/IfInsideElse
|
180
|
+
return super(*args, &block)
|
181
|
+
else
|
182
|
+
return hook.point.apply(self, 'sqreen_hook', *args, &block)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
hook_point_super = hook.point.super?
|
188
|
+
logger = Sqreen::Graft.logger
|
189
|
+
logger_debug = Sqreen::Graft.logger.debug?
|
190
|
+
|
191
|
+
Timer.new(hook.point, &timed_hooks_proc).measure do |chrono|
|
192
|
+
# budget implies request
|
193
|
+
# TODO: make budget depend on a generic context (currently "request")
|
194
|
+
budget = request[:time_budget] if request
|
195
|
+
if request && (budget || request[:timed_level] >= 1)
|
196
|
+
sqreen_timer = request[:sqreen_timer]
|
197
|
+
end
|
128
198
|
|
129
|
-
budget = Thread.current[:sqreen_http_request] && Thread.current[:sqreen_http_request][:time_budget]
|
130
|
-
timer = Thread.current[:sqreen_http_request] && Thread.current[:sqreen_http_request][:timer] if budget
|
131
199
|
hooked_call = HookedCall.new(self, args)
|
132
200
|
|
133
201
|
begin
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
Thread.current[:sqreen_http_request] && Thread.current[:sqreen_http_request][:timed_hooks_before] << t
|
148
|
-
end.measure do |before_chrono|
|
202
|
+
begin
|
203
|
+
sqreen_timer.start if sqreen_timer
|
204
|
+
Thread.current[:sqreen_hook_entered] = true
|
205
|
+
|
206
|
+
# TODO: make Call have #ball to throw by cb
|
207
|
+
# TODO: can Call be the ball? r = catch(Call.new, &c)
|
208
|
+
# TODO: is catch return value a Call? a #dispatch?
|
209
|
+
# TODO: make before/after/raised return a CallbackCollection << Array (or extend with module)
|
210
|
+
# TODO: add CallbackCollection#each_with_call(instance, args) { |call| ... } ?
|
211
|
+
# TODO: HookCall x CallbackCollection#each_with_call x Flow
|
212
|
+
# TODO: TimedHookCall TimedCallbackCall
|
213
|
+
# TODO: TimeBoundHookCall TimeBoundCallbackCall TimeBoundFlow?
|
214
|
+
|
149
215
|
hook.before.each do |c|
|
150
216
|
next if c.ignore && c.ignore.call
|
151
217
|
|
152
|
-
if
|
153
|
-
|
154
|
-
|
155
|
-
Thread.current[:sqreen_http_request] && Thread.current[:sqreen_http_request][:skipped_callbacks] << c && Thread.current[:sqreen_http_request][:time_budget_expended] = true
|
156
|
-
next
|
157
|
-
end
|
218
|
+
if budget && !c.mandatory && request[:time_budget_expended]
|
219
|
+
request[:skipped_callbacks] << c
|
220
|
+
next
|
158
221
|
end
|
159
222
|
|
223
|
+
remaining = budget - sqreen_timer.elapsed if budget
|
224
|
+
|
225
|
+
timer = nil
|
160
226
|
flow = catch(Ball.new) do |ball|
|
161
|
-
Timer.new(c.name)
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
227
|
+
timer = Timer.new(c.name, &timed_callbacks_proc)
|
228
|
+
timer.measure(ignore: chrono) do
|
229
|
+
c.call(CallbackCall.new(c, remaining, hooked_call.instance, hooked_call.args_passed), ball)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
if budget && timer
|
234
|
+
remaining -= timer.duration
|
235
|
+
if remaining < 0.0
|
236
|
+
request[:time_budget_expended]
|
237
|
+
request[:overtime_cb] = c.name
|
167
238
|
end
|
168
239
|
end
|
169
240
|
|
170
241
|
next unless c.flow && flow.is_a?(Flow)
|
242
|
+
conditions_passed_proc[] if flow.passed_conditions?
|
171
243
|
hooked_call.raise = flow.raise and hooked_call.raising = true if flow.raise?
|
172
244
|
hooked_call.args_pass = flow.args and hooked_call.args_passing = true if flow.args?
|
173
245
|
hooked_call.return = flow.return and hooked_call.returning = true if flow.return?
|
174
246
|
break if flow.break?
|
175
247
|
end unless hook.disabled?
|
248
|
+
rescue StandardError => e
|
249
|
+
Sqreen::Weave.logger.debug { "exception:#{e.class} message:'#{e.message}' location:\"#{e.backtrace[0]}\"" }
|
250
|
+
Sqreen::RemoteException.record(e) if Sqreen.queue
|
176
251
|
end
|
177
252
|
|
178
253
|
raise hooked_call.raise if hooked_call.raising
|
179
254
|
return hooked_call.return if hooked_call.returning
|
180
255
|
ensure
|
181
256
|
Thread.current[:sqreen_hook_entered] = false
|
182
|
-
|
183
|
-
end
|
257
|
+
sqreen_timer.stop if sqreen_timer
|
258
|
+
end unless hook.before.empty?
|
184
259
|
|
185
260
|
begin
|
186
261
|
chrono.ignore do
|
187
|
-
if
|
262
|
+
if hook_point_super
|
188
263
|
hooked_call.returned = super(*(hooked_call.args_passing ? hooked_call.args_pass : hooked_call.args_passed), &block)
|
189
264
|
else
|
190
265
|
hooked_call.returned = hook.point.apply(hooked_call.instance, 'sqreen_hook', *(hooked_call.args_passing ? hooked_call.args_pass : hooked_call.args_passed), &block)
|
191
266
|
end
|
192
267
|
end
|
193
268
|
rescue ::Exception => e # rubocop:disable Lint/RescueException
|
194
|
-
|
195
|
-
|
196
|
-
|
269
|
+
begin
|
270
|
+
sqreen_timer.start if sqreen_timer
|
271
|
+
Thread.current[:sqreen_hook_entered] = true
|
272
|
+
hooked_call.raised = e
|
197
273
|
|
198
|
-
|
199
|
-
|
274
|
+
logger.debug { "[#{Process.pid}] Hook #{hook.point} disabled:#{hook.disabled?} exception:#{e}" } if logger_debug
|
275
|
+
raise if hook.raised.empty?
|
200
276
|
|
201
|
-
Timer.new("#{hook.point}@raised") do |t|
|
202
|
-
Thread.current[:sqreen_http_request] && Thread.current[:sqreen_http_request][:timed_hooks_raised] << t
|
203
|
-
end.measure do |raised_chrono|
|
204
277
|
hook.raised.each do |c|
|
205
278
|
next if c.ignore && c.ignore.call
|
206
279
|
|
207
|
-
if
|
208
|
-
|
209
|
-
|
210
|
-
Thread.current[:sqreen_http_request] && Thread.current[:sqreen_http_request][:skipped_callbacks] << c && Thread.current[:sqreen_http_request][:time_budget_expended] = true
|
211
|
-
next
|
212
|
-
end
|
280
|
+
if budget && !c.mandatory && request[:time_budget_expended]
|
281
|
+
request[:skipped_callbacks] << c
|
282
|
+
next
|
213
283
|
end
|
214
284
|
|
285
|
+
remaining = budget - sqreen_timer.elapsed if budget
|
286
|
+
|
287
|
+
timer = nil
|
215
288
|
flow = catch(Ball.new) do |ball|
|
216
|
-
Timer.new(c.name)
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
289
|
+
timer = Timer.new(c.name, &timed_callbacks_proc)
|
290
|
+
timer.measure(ignore: chrono) do
|
291
|
+
c.call(CallbackCall.new(c, remaining, hooked_call.instance, hooked_call.args_passing ? hooked_call.args_pass : hooked_call.args_passed, hooked_call.raised), ball)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
if budget && timer
|
296
|
+
remaining -= timer.duration
|
297
|
+
if remaining < 0.0
|
298
|
+
request[:time_budget_expended]
|
299
|
+
request[:overtime_cb] = c.name
|
222
300
|
end
|
223
301
|
end
|
224
302
|
|
225
303
|
next unless c.flow && flow.is_a?(Flow)
|
304
|
+
conditions_passed_proc[] if flow.passed_conditions?
|
226
305
|
hooked_call.raise = flow.raise and hooked_call.raising = true if flow.raise?
|
227
306
|
hooked_call.return = flow.return and hooked_call.returning = true if flow.return?
|
228
307
|
hooked_call.retrying = true if flow.retry?
|
229
308
|
break if flow.break?
|
230
309
|
end unless hook.disabled?
|
310
|
+
rescue StandardError => e
|
311
|
+
Sqreen::Weave.logger.debug { "exception:#{e.class} message:'#{e.message}' location:\"#{e.backtrace[0]}\"" }
|
312
|
+
Sqreen::RemoteException.record(e) if Sqreen.queue
|
231
313
|
end
|
232
314
|
|
233
315
|
retry if hooked_call.retrying
|
@@ -235,78 +317,108 @@ module Sqreen
|
|
235
317
|
return hooked_call.return if hooked_call.returning
|
236
318
|
raise
|
237
319
|
else
|
238
|
-
|
239
|
-
|
320
|
+
begin
|
321
|
+
sqreen_timer.start if sqreen_timer
|
322
|
+
Thread.current[:sqreen_hook_entered] = true
|
323
|
+
|
324
|
+
# TODO: hooked_call.returning should be always false here?
|
325
|
+
return hooked_call.returning ? hooked_call.return : hooked_call.returned if hook.after.empty?
|
240
326
|
|
241
|
-
Timer.new("#{hook.point}@after") do |t|
|
242
|
-
Thread.current[:sqreen_http_request] && Thread.current[:sqreen_http_request][:timed_hooks_after] << t
|
243
|
-
end.measure do |after_chrono|
|
244
327
|
hook.after.each do |c|
|
245
328
|
next if c.ignore && c.ignore.call
|
246
329
|
|
247
|
-
if
|
248
|
-
|
249
|
-
|
250
|
-
Thread.current[:sqreen_http_request] && Thread.current[:sqreen_http_request][:skipped_callbacks] << c && Thread.current[:sqreen_http_request][:time_budget_expended] = true
|
251
|
-
next
|
252
|
-
end
|
330
|
+
if budget && !c.mandatory && request[:time_budget_expended]
|
331
|
+
request[:skipped_callbacks] << c
|
332
|
+
next
|
253
333
|
end
|
254
334
|
|
335
|
+
remaining = budget - sqreen_timer.elapsed if budget
|
336
|
+
|
337
|
+
timer = nil
|
255
338
|
flow = catch(Ball.new) do |ball|
|
256
|
-
Timer.new(c.name)
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
339
|
+
timer = Timer.new(c.name, &timed_callbacks_proc)
|
340
|
+
timer.measure(ignore: chrono) do
|
341
|
+
c.call(CallbackCall.new(c, remaining, hooked_call.instance, hooked_call.args_passing ? hooked_call.args_pass : hooked_call.args_passed, nil, hooked_call.returned), ball)
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
if budget && timer
|
346
|
+
remaining -= timer.duration
|
347
|
+
if remaining < 0.0
|
348
|
+
request[:time_budget_expended]
|
349
|
+
request[:overtime_cb] = c.name
|
262
350
|
end
|
263
351
|
end
|
264
352
|
|
265
353
|
next unless c.flow && flow.is_a?(Flow)
|
354
|
+
conditions_passed_proc[] if flow.passed_conditions?
|
266
355
|
hooked_call.raise = flow.raise and hooked_call.raising = true if flow.raise?
|
267
356
|
hooked_call.return = flow.return and hooked_call.returning = true if flow.return?
|
268
357
|
break if flow.break?
|
269
358
|
end unless hook.disabled?
|
359
|
+
rescue StandardError => e
|
360
|
+
Sqreen::Weave.logger.debug { "exception:#{e.class} message:'#{e.message}' location:\"#{e.backtrace[0]}\"" }
|
361
|
+
Sqreen::RemoteException.record(e) if Sqreen.queue
|
270
362
|
end
|
271
363
|
|
272
364
|
raise hooked_call.raise if hooked_call.raising
|
273
365
|
return hooked_call.returning ? hooked_call.return : hooked_call.returned
|
274
366
|
ensure
|
275
|
-
|
367
|
+
begin
|
368
|
+
# TODO: sqreen_timer.start if someone has thrown?
|
369
|
+
# TODO: sqreen_timer.stop at end of rescue+else?
|
370
|
+
# TODO: Thread.current[:sqreen_hook_entered] = true if neither rescue nor else ie thrown?
|
371
|
+
# TODO: Thread.current[:sqreen_hook_entered] = false at end of rescue+else? (risky?)
|
372
|
+
|
373
|
+
# TODO: uniform early bail out? (but don't forget sqreen_hook_entered and sqreen_timer)
|
374
|
+
# return hooked_call.returning ? hooked_call.return : hooked_call.returned if hook.ensured.empty?
|
375
|
+
|
376
|
+
# done at either rescue or else
|
377
|
+
# request_elapsed = request_timer.elapsed if budget # && !hook.ensured.empty?
|
276
378
|
|
277
|
-
Timer.new("#{hook.point}@ensured") do |t|
|
278
|
-
Thread.current[:sqreen_http_request] && Thread.current[:sqreen_http_request][:timed_hooks_ensured] << t
|
279
|
-
end.measure do |ensured_chrono|
|
280
379
|
hook.ensured.each do |c|
|
281
380
|
next if c.ignore && c.ignore.call
|
282
381
|
|
283
|
-
if
|
284
|
-
|
285
|
-
|
286
|
-
Thread.current[:sqreen_http_request] && Thread.current[:sqreen_http_request][:skipped_callbacks] << c && Thread.current[:sqreen_http_request][:time_budget_expended] = true
|
287
|
-
next
|
288
|
-
end
|
382
|
+
if budget && !c.mandatory && request[:time_budget_expended]
|
383
|
+
request[:skipped_callbacks] << c
|
384
|
+
next
|
289
385
|
end
|
290
386
|
|
387
|
+
remaining = budget - sqreen_timer.elapsed if budget
|
388
|
+
|
389
|
+
timer = nil
|
291
390
|
flow = catch(Ball.new) do |ball|
|
292
|
-
Timer.new(c.name)
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
391
|
+
timer = Timer.new(c.name, &timed_callbacks_proc)
|
392
|
+
timer.measure(ignore: chrono) do
|
393
|
+
c.call(CallbackCall.new(c, remaining, hooked_call.instance, hooked_call.args_passing ? hooked_call.args_pass : hooked_call.args_passed, nil, hooked_call.returned), ball)
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
if budget && timer
|
398
|
+
remaining -= timer.duration
|
399
|
+
if remaining < 0.0
|
400
|
+
request[:time_budget_expended]
|
401
|
+
request[:overtime_cb] = c.name
|
298
402
|
end
|
299
403
|
end
|
300
404
|
|
301
405
|
next unless c.flow && flow.is_a?(Flow)
|
406
|
+
conditions_passed_proc[] if flow.passed_conditions?
|
302
407
|
hooked_call.raise = flow.raise and hooked_call.raising = true if flow.raise?
|
303
408
|
hooked_call.return = flow.return and hooked_call.returning = true if flow.return?
|
304
409
|
break if flow.break?
|
305
|
-
end unless hook.disabled?
|
410
|
+
end unless hook.ensured.empty? || hook.disabled?
|
411
|
+
|
412
|
+
Thread.current[:sqreen_hook_entered] = false
|
413
|
+
sqreen_timer.stop if sqreen_timer
|
414
|
+
rescue StandardError => e
|
415
|
+
Sqreen::Weave.logger.debug { "exception:#{e.class} message:'#{e.message}' location:\"#{e.backtrace[0]}\"" }
|
416
|
+
Sqreen::RemoteException.record(e) if Sqreen.queue
|
306
417
|
end
|
307
418
|
|
308
|
-
|
309
|
-
|
419
|
+
# TODO: should we run the following?
|
420
|
+
# raise hooked_call.raise if hooked_call.raising
|
421
|
+
# return hooked_call.returning ? hooked_call.return : hooked_call.returned
|
310
422
|
end
|
311
423
|
end # chrono
|
312
424
|
end
|