sqreen 1.20.3 → 1.20.4.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -597,6 +597,15 @@ module Legacy
597
597
  method = cb.method
598
598
  key = [klass, method]
599
599
 
600
+ if (call_count = ENV['SQREEN_DEBUG_CALL_COUNT'])
601
+ call_count = JSON.parse(call_count)
602
+ if cb.respond_to?(:rule_name) && call_count.key?(cb.rule_name)
603
+ count = call_count[cb.rule_name]
604
+ Sqreen.log.debug { "override rule:#{cb.rule_name} call_count:#{count.inspect}" }
605
+ cb.instance_eval { @call_count_interval = call_count[cb.rule_name] }
606
+ end
607
+ end
608
+
600
609
  @@record_request_hookpoints << key if cb.is_a?(Sqreen::Rules::RecordRequestContext)
601
610
 
602
611
  already_overriden = @@overriden_methods.include? key
@@ -705,6 +714,7 @@ module Legacy
705
714
  remove_callback_no_lock(cb)
706
715
  end
707
716
  Sqreen.instrumentation_ready = false
717
+ Sqreen.log.info('Instrumentation deactivated')
708
718
  end
709
719
  end
710
720
 
@@ -757,6 +767,8 @@ module Legacy
757
767
  ### globally declare instrumentation ready
758
768
  ### from within instance method? not even thread local?
759
769
  Sqreen.instrumentation_ready = true
770
+
771
+ Sqreen.log.info('Instrumentation activated')
760
772
  end
761
773
 
762
774
  def initialize(metrics_engine = nil)
@@ -14,16 +14,17 @@ require 'sqreen/deferred_logger'
14
14
 
15
15
  module Sqreen
16
16
  def self.log_init
17
+ deferred_logger = @logger
17
18
  @logger = Sqreen::Logger.new(
18
19
  Sqreen.config_get(:log_level).to_s.upcase,
19
20
  Sqreen.config_get(:log_location)
20
21
  )
21
- Sqreen::DeferredLogger.instance.flush_to(@logger.instance_eval { @logger })
22
+ deferred_logger.flush_to(@logger.instance_eval { @logger })
22
23
  rescue => e
23
24
  warn "Sqreen logger exception: #{e}"
24
25
  end
25
26
 
26
27
  def self::log
27
- @logger || Sqreen::DeferredLogger.instance
28
+ @logger ||= Sqreen::DeferredLogger.new
28
29
  end
29
30
  end
@@ -32,6 +32,22 @@ module Sqreen
32
32
  @logger.debug?
33
33
  end
34
34
 
35
+ def info?
36
+ @logger.info?
37
+ end
38
+
39
+ def warn?
40
+ @logger.warn?
41
+ end
42
+
43
+ def error?
44
+ @logger.error?
45
+ end
46
+
47
+ def fatal?
48
+ @logger.fatal?
49
+ end
50
+
35
51
  def debug(msg = nil, &block)
36
52
  @logger.debug(msg, &block)
37
53
  end
@@ -49,6 +65,10 @@ module Sqreen
49
65
  @logger.error(msg, &block)
50
66
  end
51
67
 
68
+ def unknown(msg = nil, &block)
69
+ @logger.unknown(msg, &block)
70
+ end
71
+
52
72
  def add(severity, msg = nil, &block)
53
73
  send(SEVERITY_TO_METHOD[severity], msg, &block)
54
74
  end
@@ -27,6 +27,7 @@ module Sqreen
27
27
  def initialize
28
28
  @store = []
29
29
  @metrics = {} # name => (metric, period, start)
30
+ @mutex = Mutex.new
30
31
  end
31
32
 
32
33
  # Definition contains a name,period and aggregate at least
@@ -34,6 +35,8 @@ module Sqreen
34
35
  # @param rule [RuleCB] the rule associated with this metric, if any
35
36
  # @param mklass [Object] Override metric object (used in testing)
36
37
  def create_metric(definition, rule = nil, mklass = nil)
38
+ @mutex.lock
39
+
37
40
  name = definition[NAME_KEY]
38
41
  kind = definition[KIND_KEY]
39
42
  klass = valid_metric(kind, name)
@@ -49,6 +52,8 @@ module Sqreen
49
52
  metric.rule = rule
50
53
  metric.period = definition[PERIOD_KEY]
51
54
  metric
55
+ ensure
56
+ @mutex.unlock
52
57
  end
53
58
 
54
59
  def metric?(name)
@@ -57,21 +62,27 @@ module Sqreen
57
62
 
58
63
  # @param at [Time] when is the store emptied
59
64
  def update(name, at, key, value)
65
+ @mutex.lock
60
66
  metric, period, start = @metrics[name]
61
67
  raise UnregisteredMetric, "Unknown metric #{name}" unless metric
62
68
  next_sample(name, at) if start.nil? || (start + period) < at
63
69
  metric.update(key, value)
70
+ ensure
71
+ @mutex.unlock
64
72
  end
65
73
 
66
74
  # Drains every metrics and returns the store content
67
75
  # @param at [Time] when is the store emptied
68
76
  def publish(flush = true, at = Sqreen.time)
77
+ @mutex.lock
69
78
  @metrics.each do |name, (_, period, start)|
70
79
  next_sample(name, at) if flush || !start.nil? && (start + period) < at
71
80
  end
72
81
  out = @store
73
82
  @store = []
74
83
  out
84
+ ensure
85
+ @mutex.unlock
75
86
  end
76
87
 
77
88
  protected
@@ -9,6 +9,26 @@ module Sqreen
9
9
  class NullLogger
10
10
  include Singleton
11
11
 
12
+ def debug?
13
+ false
14
+ end
15
+
16
+ def info?
17
+ false
18
+ end
19
+
20
+ def warn?
21
+ false
22
+ end
23
+
24
+ def error?
25
+ false
26
+ end
27
+
28
+ def fatal?
29
+ false
30
+ end
31
+
12
32
  def debug(_msg = nil); end
13
33
 
14
34
  def info(_msg = nil); end
@@ -19,6 +39,8 @@ module Sqreen
19
39
 
20
40
  def fatal(_msg = nil); end
21
41
 
42
+ def unknown(_msg = nil); end
43
+
22
44
  def add(_severity, _msg = nil); end
23
45
 
24
46
  def formatter=(_); end
@@ -18,6 +18,7 @@ module Sqreen
18
18
  :features_get => :features,
19
19
  :features_change => :change_features,
20
20
  :force_logout => :shutdown,
21
+ :force_restart => :restart,
21
22
  :paths_whitelist => :change_whitelisted_paths,
22
23
  :ips_whitelist => :change_whitelisted_ips,
23
24
  :get_bundle => :upload_bundle,
@@ -114,7 +114,7 @@ module Sqreen
114
114
  Sqreen.log.warn('No JavaScript engine is available. ' \
115
115
  'JavaScript callbacks will be ignored')
116
116
  end
117
- Sqreen.log.info("Ignoring JS callback #{rule_name}")
117
+ Sqreen.log.debug("Ignoring JS callback #{rule_name}")
118
118
  return nil
119
119
  end
120
120
 
@@ -33,7 +33,7 @@ module Sqreen
33
33
  private
34
34
 
35
35
  def insert_values(ranges)
36
- Sqreen.log.info 'no ips given for IP blacklisting' if ranges.empty?
36
+ Sqreen.log.debug 'no ips given for IP blacklisting' if ranges.empty?
37
37
 
38
38
  ranges.map { |r| Prefix.from_str(r, r) }.each do |prefix|
39
39
  trie_for(prefix).insert prefix
@@ -50,7 +50,7 @@ module Sqreen
50
50
  begin
51
51
  ipa = IPAddr.new(rip)
52
52
  rescue StandardError
53
- Sqreen.log.info "invalid IP address given by framework: #{rip}"
53
+ Sqreen.log.debug "invalid IP address given by framework: #{rip}"
54
54
  return nil
55
55
  end
56
56
 
@@ -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/deprecation'
6
7
  require 'sqreen/framework_cb'
7
8
  require 'sqreen/context'
8
9
  require 'sqreen/conditionable'
@@ -109,6 +110,7 @@ module Sqreen
109
110
  )
110
111
  true
111
112
  end
113
+ Sqreen::Deprecation.deprecate(instance_method(:overtime!))
112
114
  end
113
115
  end
114
116
  end
@@ -387,8 +387,25 @@ module Sqreen
387
387
 
388
388
  def change_performance_budget(budget, _context_infos = {})
389
389
  return false unless budget.nil? || budget.to_f > 0
390
- prev = Sqreen.performance_budget
391
- Sqreen.update_performance_budget(budget)
390
+
391
+ if @configuration.get(:weave)
392
+ prev = Sqreen::Weave::Budget.current
393
+ prev = prev.to_h if prev
394
+
395
+ budget_s = budget.to_f / 1000 if budget
396
+
397
+ feature = features['performance_budget']
398
+ if feature
399
+ budget_s = feature['threshold'] if feature.key?('threshold')
400
+ ratio = feature['ratio'] if feature.key?('ratio')
401
+ end
402
+
403
+ Sqreen::Weave::Budget.update(threshold: budget_s, ratio: ratio)
404
+ else
405
+ prev = Sqreen.performance_budget
406
+ Sqreen.update_performance_budget(budget)
407
+ end
408
+
392
409
  { :was => prev }
393
410
  end
394
411
 
@@ -478,6 +495,15 @@ module Sqreen
478
495
  logout
479
496
  end
480
497
 
498
+ def restart(_context_infos = {})
499
+ shutdown
500
+ heartbeat_delay = @heartbeat_delay
501
+ Thread.new do
502
+ sleep(2 * heartbeat_delay)
503
+ Sqreen::Worker.start(Sqreen.framework)
504
+ end
505
+ end
506
+
481
507
  def logout(retrying = true)
482
508
  return unless session
483
509
  Sqreen.log.debug("Logging out")
@@ -4,5 +4,5 @@
4
4
  # Please refer to our terms for more information: https://www.sqreen.com/terms.html
5
5
 
6
6
  module Sqreen
7
- VERSION = '1.20.3'.freeze
7
+ VERSION = '1.20.4.beta1'.freeze
8
8
  end
@@ -0,0 +1,46 @@
1
+ # typed: false
2
+
3
+ # Copyright (c) 2015 Sqreen. All Rights Reserved.
4
+ # Please refer to our terms for more information: https://www.sqreen.com/terms.html
5
+
6
+ require 'sqreen/log/loggable'
7
+ require 'sqreen/weave'
8
+
9
+ class Sqreen::Weave::Budget
10
+ include Sqreen::Log::Loggable
11
+
12
+ def initialize(threshold, ratio = nil)
13
+ @threshold = threshold
14
+ @ratio = ratio
15
+ end
16
+
17
+ def static?
18
+ threshold && !ratio
19
+ end
20
+
21
+ def dynamic?
22
+ threshold && ratio
23
+ end
24
+
25
+ attr_reader :threshold
26
+ attr_reader :ratio
27
+
28
+ def to_h
29
+ { threshold: threshold, ratio: ratio }
30
+ end
31
+
32
+ class << self
33
+ attr_reader :current
34
+
35
+ def update(opts = nil)
36
+ Sqreen::Weave.logger.info("budget update:#{opts.inspect}")
37
+
38
+ return @current = nil if opts.nil? || opts.empty?
39
+
40
+ threshold = opts[:threshold]
41
+ ratio = opts[:ratio]
42
+
43
+ @current = new(threshold, ratio)
44
+ end
45
+ end
46
+ end
@@ -4,6 +4,7 @@
4
4
  # Please refer to our terms for more information: https://www.sqreen.com/terms.html
5
5
 
6
6
  require 'sqreen/weave/legacy'
7
+ require 'sqreen/weave/budget'
7
8
  require 'sqreen/graft/hook_point'
8
9
  require 'sqreen/call_countable'
9
10
  require 'sqreen/rules'
@@ -62,7 +63,7 @@ class Sqreen::Weave::Legacy::Instrumentation
62
63
  )
63
64
 
64
65
  metrics_engine.create_metric(
65
- 'name' => 'req_sq_hook_overhead',
66
+ 'name' => 'req.sq.hook.overhead',
66
67
  'period' => 60,
67
68
  'kind' => 'Binning',
68
69
  'options' => { 'base' => 2.0, 'factor' => 0.1 },
@@ -125,6 +126,25 @@ class Sqreen::Weave::Legacy::Instrumentation
125
126
  next unless rule_callback
126
127
  ### attach framework to callback
127
128
  rule_callback.framework = framework
129
+ ## create metric
130
+ Sqreen::Weave.logger.debug { "Adding rule metric: #{rule_callback}" }
131
+ [:pre, :post, :failing].each do |whence|
132
+ next unless rule_callback.send(:"#{whence}?")
133
+ metric_name = "sq.#{rule['name']}.#{whence}"
134
+ metrics_engine.create_metric(
135
+ 'name' => metric_name,
136
+ 'period' => 60,
137
+ 'kind' => 'Binning',
138
+ 'options' => { 'base' => 2.0, 'factor' => 0.1 },
139
+ )
140
+ metric_name = "req.sq.#{rule['name']}.#{whence}"
141
+ metrics_engine.create_metric(
142
+ 'name' => metric_name,
143
+ 'period' => 60,
144
+ 'kind' => 'Binning',
145
+ 'options' => { 'base' => 2.0, 'factor' => 0.1 },
146
+ )
147
+ end
128
148
  ### install callback, observing priority
129
149
  Sqreen::Weave.logger.debug { "Adding rule callback: #{rule_callback}" }
130
150
  @hooks << add_callback("weave,rule=#{rule['name']}", rule_callback, strategy)
@@ -138,6 +158,7 @@ class Sqreen::Weave::Legacy::Instrumentation
138
158
  end
139
159
 
140
160
  metrics_engine = self.metrics_engine
161
+
141
162
  request_hook = Sqreen::Graft::Hook['Sqreen::ShrinkWrap#call', strategy]
142
163
  @hooks << request_hook
143
164
  request_hook.add do
@@ -147,22 +168,32 @@ class Sqreen::Weave::Legacy::Instrumentation
147
168
  # shrinkwrap_timer = Sqreen::Graft::Timer.new('weave,shrinkwrap')
148
169
  # shrinkwrap_timer.start
149
170
 
150
- uuid = SecureRandom.uuid
151
- now = Sqreen::Graft::Timer.read
171
+ request_timer = Sqreen::Graft::Timer.new("request")
172
+ request_timer.start
173
+ sqreen_timer = Sqreen::Graft::Timer.new("sqreen")
174
+ budget = Sqreen::Weave::Budget.current
175
+ request_budget_threshold = budget.threshold
176
+ request_budget_ratio = budget.ratio
177
+ request_budget_is_dynamic = !request_budget_ratio.nil?
178
+ request_budget = !request_budget_threshold.nil?
179
+ timed_level = (Sqreen.features['perf_level'] || 1).to_i
180
+ Sqreen::Weave.logger.debug { "request budget: #{budget.to_h} timed.level: #{timed_level}" } if Sqreen::Weave.logger.debug?
181
+
152
182
  Thread.current[:sqreen_http_request] = {
153
- uuid: uuid,
154
- start_time: now,
155
- time_budget: Sqreen.performance_budget,
183
+ request_timer: request_timer,
184
+ sqreen_timer: sqreen_timer,
156
185
  time_budget_expended: false,
157
- timer: Sqreen::Graft::Timer.new("request_#{uuid}"),
186
+ time_budget_threshold: request_budget_threshold,
187
+ time_budget_dynamic: request_budget_is_dynamic,
188
+ time_budget_ratio: request_budget_ratio,
189
+ time_budget: request_budget,
158
190
  timed_callbacks: [],
159
191
  timed_hooks: [],
192
+ timed_level: timed_level,
160
193
  skipped_callbacks: [],
161
194
  # timed_shrinkwrap: shrinkwrap_timer,
162
195
  }
163
196
 
164
- Sqreen::Weave.logger.debug { "request.uuid: #{uuid}" }
165
-
166
197
  # shrinkwrap_timer.stop
167
198
  end
168
199
 
@@ -175,66 +206,89 @@ class Sqreen::Weave::Legacy::Instrumentation
175
206
  # shrinkwrap_timer.start
176
207
 
177
208
  Thread.current[:sqreen_http_request] = nil
178
- now = Sqreen::Graft::Timer.read
179
- utc_now = Time.now.utc
180
-
181
- request[:timed_callbacks].each do |timer|
182
- duration = timer.duration
183
- # stop = now
184
- # start = now - duration
185
- timer.tag =~ /weave,rule=(.*)$/ && rule = $1
186
- timer.tag =~ /@before/ && whence = 'pre'
187
- timer.tag =~ /@after/ && whence = 'post'
188
- timer.tag =~ /@raised/ && whence = 'failing'
189
-
190
- next unless rule && whence
191
-
192
- # Sqreen::PerformanceNotifications.notify(rule, whence, start, stop)
193
- # => BinnedMetrics
194
- metric_name = "sq.#{rule}.#{whence}"
195
- unless metrics_engine.metric?(metric_name)
196
- metrics_engine.create_metric(
197
- 'name' => metric_name,
198
- 'period' => 60,
199
- 'kind' => 'Binning',
200
- 'options' => { 'base' => 2.0, 'factor' => 0.1 },
201
- )
209
+ request_timer = request[:request_timer]
210
+ now = request_timer.stop
211
+
212
+ if request[:timed_level] >= 1
213
+ request[:timed_callbacks].each do |timer|
214
+ duration = timer.duration
215
+ timer.tag =~ /weave,rule=(.*)$/ && rule = $1
216
+ timer.tag =~ /@before/ && whence = 'pre'
217
+ timer.tag =~ /@after/ && whence = 'post'
218
+ timer.tag =~ /@raised/ && whence = 'failing'
219
+
220
+ next unless rule && whence
221
+
222
+ metric_name = "sq.#{rule}.#{whence}"
223
+ metrics_engine.update(metric_name, now, nil, duration * 1000)
224
+ # Sqreen.observations_queue.push([metric_name, nil, duration * 1000, utc_now])
202
225
  end
203
- metrics_engine.update(metric_name, now, nil, duration * 1000)
204
- end
205
226
 
206
- request[:timed_hooks].each do |timer|
207
- duration = timer.duration
208
- metrics_engine.update('sq.hook.overhead', now, nil, duration * 1000)
227
+ request[:timed_hooks].each do |timer|
228
+ duration = timer.duration
229
+ metrics_engine.update('sq.hook.overhead', now, nil, duration * 1000)
230
+ # Sqreen.observations_queue.push(['sq.hook.overhead', nil, duration * 1000, utc_now])
231
+ end
209
232
  end
210
233
 
211
- skipped = request[:skipped_callbacks].map(&:name)
212
- Sqreen::Weave.logger.debug { "request:#{request[:uuid]} callback.skipped.size: #{skipped.count} callback.skipped: [#{skipped.join(', ')}]" } if Sqreen::Weave.logger.debug?
213
- timer = request[:timer]
214
- total = timer.duration
215
- Sqreen::Weave.logger.debug { "request:#{request[:uuid]} timer.total: #{'%.03fus' % (total * 1_000_000)}" } if Sqreen::Weave.logger.debug?
216
- timings = request[:timed_callbacks].map(&:to_s)
217
- total = request[:timed_callbacks].sum(&:duration)
218
- Sqreen::Weave.logger.debug { "request:#{request[:uuid]} callback.total: #{'%.03fus' % (total * 1_000_000)} callback.timings: [#{timings.join(', ')}]" } if Sqreen::Weave.logger.debug?
219
- timings = request[:timed_hooks].map(&:to_s)
220
- total = request[:timed_hooks].sum(&:duration)
221
- Sqreen::Weave.logger.debug { "request:#{request[:uuid]} hook.total: #{'%.03fus' % (total * 1_000_000)} hook.timings: [#{timings.join(', ')}]" } if Sqreen::Weave.logger.debug?
234
+ sqreen_timer = request[:sqreen_timer]
235
+ total = sqreen_timer.duration
236
+ Sqreen::Weave.logger.debug { "request sqreen_timer.total: #{'%.03fus' % (total * 1_000_000)}" } if Sqreen::Weave.logger.debug?
237
+ total = request_timer.duration
238
+ Sqreen::Weave.logger.debug { "request request_timer.total: #{'%.03fus' % (total * 1_000_000)}" } if Sqreen::Weave.logger.debug?
239
+
240
+ if request[:timed_level] >= 2
241
+ skipped = request[:skipped_callbacks].map(&:name)
242
+ Sqreen::Weave.logger.debug { "request callback.skipped.count: #{skipped.count}" } if Sqreen::Weave.logger.debug?
243
+ timings = request[:timed_callbacks].map(&:to_s)
244
+ total = request[:timed_callbacks].sum(&:duration)
245
+ Sqreen::Weave.logger.debug { "request callback.total: #{'%.03fus' % (total * 1_000_000)} callback.count: #{timings.count}" } if Sqreen::Weave.logger.debug?
246
+ timings = request[:timed_hooks].map(&:to_s)
247
+ total = request[:timed_hooks].sum(&:duration)
248
+ Sqreen::Weave.logger.debug { "request hook.total: #{'%.03fus' % (total * 1_000_000)} hook.count: #{timings.count}" } if Sqreen::Weave.logger.debug?
249
+ end
222
250
 
223
251
  skipped = request[:skipped_callbacks].map(&:name)
224
252
  skipped_rule_name = skipped.first && skipped.first =~ /weave,rule=(.*)$/ && $1
225
- Sqreen.observations_queue.push(['request_overtime', skipped_rule_name, 1, utc_now]) if skipped_rule_name
253
+ metrics_engine.update('request_overtime', now, skipped_rule_name, 1) if skipped_rule_name
254
+ # Sqreen.observations_queue.push(['request_overtime', skipped_rule_name, 1, utc_now]) if skipped_rule_name
226
255
 
227
- sqreen_request_duration = request[:timed_hooks].sum(&:duration) + request[:timed_callbacks].sum(&:duration)
228
- Sqreen.observations_queue.push(['sq', nil, sqreen_request_duration * 1000, utc_now])
256
+ sqreen_request_duration = sqreen_timer.duration
257
+ metrics_engine.update('sq', now, nil, sqreen_request_duration * 1000)
258
+ # Sqreen.observations_queue.push(['sq', nil, sqreen_request_duration * 1000, utc_now])
229
259
 
230
- request_duration = now - request[:start_time]
231
- Sqreen.observations_queue.push(['req', nil, request_duration * 1000, utc_now])
260
+ request_duration = request_timer.duration
261
+ metrics_engine.update('req', now, nil, request_duration * 1000)
262
+ # Sqreen.observations_queue.push(['req', nil, request_duration * 1000, utc_now])
232
263
 
233
264
  sqreen_request_ratio = (sqreen_request_duration * 100.0) / (request_duration - sqreen_request_duration)
234
- Sqreen.observations_queue.push(['pct', nil, sqreen_request_ratio, utc_now])
265
+ metrics_engine.update('pct', now, nil, sqreen_request_ratio)
266
+ # Sqreen.observations_queue.push(['pct', nil, sqreen_request_ratio, utc_now])
267
+ Sqreen::Weave.logger.debug { "request sqreen_timer.ratio: #{'%.03f' % (sqreen_request_ratio / 100.0)}" } if Sqreen::Weave.logger.debug?
268
+
269
+ if request[:timed_level] >= 2
270
+ tallies = Hash.new(0.0)
271
+ request[:timed_callbacks].each do |timer|
272
+ duration = timer.duration
273
+ timer.tag =~ /weave,rule=(.*)$/ && rule = $1
274
+ timer.tag =~ /@before/ && whence = 'pre'
275
+ timer.tag =~ /@after/ && whence = 'post'
276
+ timer.tag =~ /@raised/ && whence = 'failing'
277
+
278
+ next unless rule && whence
279
+
280
+ metric_name = "req.sq.#{rule}.#{whence}"
281
+ tallies[metric_name] += duration
282
+ end
283
+ tallies.each do |metric_name, duration|
284
+ metrics_engine.update(metric_name, now, nil, duration * 1000)
285
+ # Sqreen.observations_queue.push([metric_name, nil, duration * 1000, utc_now])
286
+ end
235
287
 
236
- duration = request[:timed_hooks].sum(&:duration)
237
- metrics_engine.update('req_sq_hook_overhead', now, nil, duration * 1000)
288
+ duration = request[:timed_hooks].sum(&:duration)
289
+ metrics_engine.update('req.sq.hook.overhead', now, nil, duration * 1000)
290
+ # Sqreen.observations_queue.push(['req.sq.hook.overhead', nil, duration * 1000, utc_now])
291
+ end
238
292
 
239
293
  # shrinkwrap_timer.stop
240
294
 
@@ -245,11 +299,13 @@ class Sqreen::Weave::Legacy::Instrumentation
245
299
 
246
300
  ### globally declare instrumentation ready
247
301
  Sqreen.instrumentation_ready = true
302
+ Sqreen::Weave.logger.info { "Instrumentation activated" }
248
303
  end
249
304
 
250
305
  # needed by Sqreen::Runner
251
306
  def remove_all_callbacks
252
307
  Sqreen.instrumentation_ready = false
308
+ Sqreen::Weave.logger.info { "Instrumentation deactivated" }
253
309
 
254
310
  loop do
255
311
  hook = @hooks.pop
@@ -266,6 +322,15 @@ class Sqreen::Weave::Legacy::Instrumentation
266
322
  klass = callback.klass
267
323
  method = callback.method
268
324
 
325
+ if (call_count = ENV['SQREEN_DEBUG_CALL_COUNT'])
326
+ call_count = JSON.parse(call_count)
327
+ if callback.respond_to?(:rule_name) && call_count.key?(callback.rule_name)
328
+ count = call_count[callback.rule_name]
329
+ Sqreen::Weave.logger.debug { "override rule: #{callback.rule_name} call_count: #{count.inspect}" }
330
+ callback.instance_eval { @call_count_interval = call_count[callback.rule_name] }
331
+ end
332
+ end
333
+
269
334
  if Sqreen::Graft::HookPoint.new("#{klass}.#{method}").exist?
270
335
  hook_point = "#{klass}.#{method}"
271
336
  elsif Sqreen::Graft::HookPoint.new("#{klass}##{method}").exist?
@@ -288,7 +353,6 @@ class Sqreen::Weave::Legacy::Instrumentation
288
353
  a = call.args
289
354
  r = call.remaining
290
355
 
291
- Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#pre instance=#{i}" } if Sqreen::Weave.logger.debug?
292
356
  begin
293
357
  ret = callback.pre(i, a, r)
294
358
  rescue StandardError => e
@@ -299,7 +363,6 @@ class Sqreen::Weave::Legacy::Instrumentation
299
363
  Sqreen::RemoteException.record(e)
300
364
  end
301
365
  end
302
- Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#pre instance=#{i} => return=#{ret.inspect}" } if Sqreen::Weave.logger.debug?
303
366
 
304
367
  case ret[:status]
305
368
  when :skip, 'skip'
@@ -322,7 +385,6 @@ class Sqreen::Weave::Legacy::Instrumentation
322
385
  a = call.args
323
386
  r = call.remaining
324
387
 
325
- Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#post instance=#{i}" } if Sqreen::Weave.logger.debug?
326
388
  begin
327
389
  ret = callback.post(v, i, a, r)
328
390
  rescue StandardError => e
@@ -333,7 +395,6 @@ class Sqreen::Weave::Legacy::Instrumentation
333
395
  Sqreen::RemoteException.record(e)
334
396
  end
335
397
  end
336
- Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#post instance=#{i} => return=#{ret.inspect}" } if Sqreen::Weave.logger.debug?
337
398
 
338
399
  case ret[:status]
339
400
  when :override, 'override'
@@ -354,7 +415,6 @@ class Sqreen::Weave::Legacy::Instrumentation
354
415
  a = call.args
355
416
  r = call.remaining
356
417
 
357
- Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#failing instance=#{i}" } if Sqreen::Weave.logger.debug?
358
418
  begin
359
419
  ret = callback.failing(e, i, a, r)
360
420
  rescue StandardError => e
@@ -365,7 +425,6 @@ class Sqreen::Weave::Legacy::Instrumentation
365
425
  Sqreen::RemoteException.record(e)
366
426
  end
367
427
  end
368
- Sqreen::Weave.logger.debug { "#{rule} klass=#{callback.klass} method=#{callback.method} when=#failing instance=#{i} => return=#{ret.inspect}" } if Sqreen::Weave.logger.debug?
369
428
 
370
429
  throw(b, b.raise(e)) if ret.nil? || !ret.is_a?(Hash)
371
430