sqreen 1.19.1-java → 1.21.0.beta3-java
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 +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
|