sqreen 1.20.3 → 1.20.4.beta1

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.
@@ -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