sqreen 1.15.0-java → 1.15.5-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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/sqreen/actions.rb +114 -43
  3. data/lib/sqreen/callback_tree.rb +16 -3
  4. data/lib/sqreen/callbacks.rb +7 -34
  5. data/lib/sqreen/capped_queue.rb +5 -1
  6. data/lib/sqreen/configuration.rb +4 -0
  7. data/lib/sqreen/deliveries/batch.rb +7 -4
  8. data/lib/sqreen/event.rb +4 -0
  9. data/lib/sqreen/events/request_record.rb +40 -7
  10. data/lib/sqreen/frameworks/generic.rb +0 -2
  11. data/lib/sqreen/frameworks/request_recorder.rb +14 -1
  12. data/lib/sqreen/instrumentation.rb +57 -33
  13. data/lib/sqreen/js/mini_racer_adapter.rb +46 -8
  14. data/lib/sqreen/metrics/average.rb +1 -1
  15. data/lib/sqreen/metrics/base.rb +4 -2
  16. data/lib/sqreen/metrics/binning.rb +3 -2
  17. data/lib/sqreen/metrics/collect.rb +1 -1
  18. data/lib/sqreen/metrics/sum.rb +1 -1
  19. data/lib/sqreen/metrics_store.rb +10 -5
  20. data/lib/sqreen/mono_time.rb +18 -0
  21. data/lib/sqreen/performance_notifications.rb +13 -38
  22. data/lib/sqreen/performance_notifications/binned_metrics.rb +12 -14
  23. data/lib/sqreen/performance_notifications/log.rb +6 -1
  24. data/lib/sqreen/performance_notifications/log_performance.rb +3 -1
  25. data/lib/sqreen/performance_notifications/metrics.rb +6 -3
  26. data/lib/sqreen/performance_notifications/newrelic.rb +6 -2
  27. data/lib/sqreen/remote_command.rb +26 -0
  28. data/lib/sqreen/rule_attributes.rb +1 -0
  29. data/lib/sqreen/rule_callback.rb +38 -0
  30. data/lib/sqreen/rules_callbacks/binding_accessor_matcher.rb +3 -2
  31. data/lib/sqreen/rules_callbacks/blacklist_ips.rb +1 -1
  32. data/lib/sqreen/rules_callbacks/run_block_user_actions.rb +1 -1
  33. data/lib/sqreen/rules_callbacks/run_req_start_actions.rb +8 -2
  34. data/lib/sqreen/runner.rb +11 -8
  35. data/lib/sqreen/sdk.rb +7 -1
  36. data/lib/sqreen/session.rb +4 -0
  37. data/lib/sqreen/trie.rb +274 -0
  38. data/lib/sqreen/version.rb +1 -1
  39. metadata +4 -2
@@ -14,7 +14,7 @@ module Sqreen
14
14
  end
15
15
 
16
16
  def post(_retval, _inst, args, _budget = nil)
17
- actions = actions_repo[Sqreen::Actions::BlockUser]
17
+ actions = actions_repo.get('block_user', args[@auth_keys_idx])
18
18
 
19
19
  actions.each do |action|
20
20
  res = action.run args[@auth_keys_idx]
@@ -9,6 +9,8 @@ module Sqreen
9
9
  module Rules
10
10
  # Runs actions concerned with whether the request ought to be served
11
11
  class RunReqStartActions < FrameworkCB
12
+ PRIORITY = 95
13
+
12
14
  def initialize(framework)
13
15
  if defined?(Sqreen::Frameworks::SinatraFramework) &&
14
16
  framework.is_a?(Sqreen::Frameworks::SinatraFramework)
@@ -30,13 +32,17 @@ module Sqreen
30
32
  framework && !framework.whitelisted_match.nil?
31
33
  end
32
34
 
35
+ def priority
36
+ PRIORITY
37
+ end
38
+
33
39
  def pre(_inst, _args, _budget = nil, &_block)
34
40
  return unless framework
35
41
  ip = framework.client_ip
36
42
  return unless ip
37
43
 
38
- actions = actions_repo[Sqreen::Actions::BlockIp] +
39
- actions_repo[Sqreen::Actions::RedirectIp]
44
+ actions = actions_repo.get(Sqreen::Actions::BlockIp, ip) +
45
+ actions_repo.get(Sqreen::Actions::RedirectIp, ip)
40
46
 
41
47
  actions.each do |act|
42
48
  res = run_client_ip_action(act, ip)
@@ -214,9 +214,10 @@ module Sqreen
214
214
  def config_binned_metrics(level, base, factor, base_pct, factor_pct)
215
215
  level = level.to_i
216
216
  if level <= 0
217
- Sqreen.log.debug('Disabling binned metrics')
217
+ Sqreen.log.info('Disabling binned metrics')
218
218
  PerformanceNotifications::BinnedMetrics.disable
219
219
  else
220
+ Sqreen.log.info('Enabling binned metrics')
220
221
  Sqreen.log.warn("Unknown value for perf_level: #{level}. Treating as 1") unless level == 1
221
222
  PerformanceNotifications::BinnedMetrics.enable(
222
223
  metrics_engine, PERF_METRICS_PERIOD, base.to_f, factor.to_f, base_pct.to_f, factor_pct.to_f
@@ -352,9 +353,10 @@ module Sqreen
352
353
 
353
354
  def aggregate_observations
354
355
  q = Sqreen.observations_queue
356
+ conv = Sqreen.time - Time.now.utc.to_f
355
357
  q.size.times do
356
358
  cat, key, obs, t = q.pop
357
- metrics_engine.update(cat, t, key, obs)
359
+ metrics_engine.update(cat, conv + t.utc.to_f, key, obs)
358
360
  end
359
361
  end
360
362
 
@@ -445,9 +447,14 @@ module Sqreen
445
447
  def load_actions(hashes)
446
448
  unsupported = Set.new
447
449
 
450
+ repos = Sqreen::Actions::Repository.instance
451
+ repos.clear
452
+
448
453
  actions = hashes.map do |h|
449
454
  begin
450
- Sqreen::Actions.deserialize_action(h)
455
+ act = Sqreen::Actions.deserialize_action(h)
456
+ repos.add h['parameters'], act
457
+ act
451
458
  rescue Sqreen::Actions::UnknownActionType => e
452
459
  Sqreen.log.warn("Unsupported action type: #{e.action_type}")
453
460
  unsupported << e.action_type
@@ -458,11 +465,7 @@ module Sqreen
458
465
  end
459
466
 
460
467
  actions = actions.reject(&:nil?)
461
- Sqreen.log.debug("Will add #{actions.size} valid actions")
462
-
463
- repos = Sqreen::Actions::Repository.instance
464
- repos.clear
465
- actions.each { |action| repos << action }
468
+ Sqreen.log.debug("Added #{actions.size} valid actions")
466
469
 
467
470
  unsupported
468
471
  end
@@ -24,7 +24,13 @@ module Sqreen
24
24
  end
25
25
 
26
26
  def track(event_name, options = {})
27
- return unless Sqreen.framework
27
+ unless Sqreen.framework
28
+ Sqreen.log.warn("Ignored track call (event #{event_name}) due to framework absence")
29
+ return
30
+ end
31
+
32
+ Sqreen.log.debug { "Sqreen.track() call (event #{event_name}, options #{options})" }
33
+
28
34
  if event_name.start_with? SDK_RESERVED_PREFIX
29
35
  Sqreen.log.warn("Event names starting with '#{SDK_RESERVED_PREFIX}' " \
30
36
  'are reserved. Event ignored.')
@@ -292,6 +292,10 @@ module Sqreen
292
292
  h[EVENT_TYPE_KEY] = event_kind(event)
293
293
  h
294
294
  end
295
+ Sqreen.log.debug do
296
+ tally = Hash[events.group_by(&:class).map{ |k,v| [k, v.count] }]
297
+ "Doing batch with the following tally of event types: #{tally}"
298
+ end
295
299
  resilient_post(BATCH_KEY, BATCH_KEY => batch)
296
300
  end
297
301
 
@@ -0,0 +1,274 @@
1
+ require 'ipaddr'
2
+
3
+ module Sqreen
4
+ Trie = Struct.new(:head, :num_active_nodes, :family) do
5
+ attr_reader :max_num_bits
6
+
7
+ def initialize(*args)
8
+ super
9
+ self.family ||= Socket::AF_INET
10
+ self.num_active_nodes = 0
11
+ @max_num_bits = family == Socket::AF_INET ? 32 : 128
12
+ end
13
+
14
+ def insert(arg_prefix)
15
+ raise 'family mismatch' if arg_prefix.family != family
16
+
17
+ if head.nil?
18
+ node = Node.new(
19
+ arg_prefix.bitlen, # bit
20
+ arg_prefix,
21
+ nil, nil, nil, #l , r, parent
22
+ )
23
+ self.head = node
24
+ self.num_active_nodes += 1
25
+ return node
26
+ end
27
+
28
+ arg_addr = arg_prefix.address
29
+ arg_bitlen = arg_prefix.bitlen
30
+ xcur = self.head
31
+
32
+ # descend until we find the end of the tree or go past the
33
+ # bitlen of the prefix we're adding
34
+ while xcur.bit < arg_bitlen || xcur.empty?
35
+ if bit_set?(arg_addr, xcur.bit)
36
+ break if xcur.r.nil?
37
+ xcur = xcur.r
38
+ else
39
+ break if xcur.l.nil?
40
+ xcur = xcur.l
41
+ end
42
+ end
43
+
44
+ trie_addr = xcur.prefix.address
45
+
46
+ # find first bit that differs between addr and trie_addr
47
+ cmp_bit_end = [arg_bitlen, xcur.bit].min # after last to be compared
48
+
49
+ differ_bit = (0...cmp_bit_end).find do |i|
50
+ bit_set?(arg_addr, i) ^ bit_set?(trie_addr, i)
51
+ end
52
+ differ_bit = cmp_bit_end if differ_bit.nil?
53
+
54
+ # go up till we find the parent before the bits differ
55
+ xparent = xcur.parent
56
+ while !xparent.nil? && xparent.bit >= differ_bit
57
+ xcur = xparent
58
+ xparent = xcur.parent
59
+ end
60
+
61
+ # case 1: replace current node's prefix
62
+ if differ_bit == arg_bitlen && xcur.bit == arg_bitlen
63
+ xcur.prefix = arg_prefix
64
+ return xcur
65
+ end
66
+
67
+ xnew = Node.new(arg_prefix.bitlen, arg_prefix, nil, nil, nil)
68
+ self.num_active_nodes += 1
69
+
70
+ # case 2: append below found node
71
+ if xcur.bit == differ_bit
72
+ xnew.parent = xcur
73
+ if bit_set?(arg_addr, xcur.bit)
74
+ xcur.r = xnew
75
+ else
76
+ xcur.l = xnew
77
+ end
78
+
79
+ return xnew
80
+ end
81
+
82
+ # case 3: take place of found node
83
+ if arg_bitlen == differ_bit
84
+ if bit_set?(trie_addr, arg_bitlen)
85
+ xnew.r = xcur
86
+ else
87
+ xnew.l = xcur
88
+ end
89
+
90
+ xnew.parent = xcur.parent
91
+
92
+ if xcur.parent.nil?
93
+ self.head = xnew
94
+ elsif xcur.parent.r.equal?(xcur)
95
+ xcur.parent.r = xnew
96
+ else
97
+ xcur.parent.l = xnew
98
+ end
99
+
100
+ xcur.parent = xnew
101
+
102
+ return xnew
103
+ end
104
+
105
+ # case 4: need to add intermediate node to be parent of the
106
+ # both xnew and xcur
107
+
108
+ # last arg is the parent of the new node
109
+ xglue = Node.new(differ_bit, nil, nil, nil, xcur.parent)
110
+ self.num_active_nodes += 1
111
+
112
+ if bit_set?(arg_addr, differ_bit)
113
+ xglue.r = xnew
114
+ xglue.l = xcur
115
+ else
116
+ xglue.r = xcur
117
+ xglue.l = xnew
118
+ end
119
+
120
+ xnew.parent = xglue
121
+
122
+ if xcur.parent.nil?
123
+ self.head = xglue
124
+ elsif xcur.equal?(xcur.parent.r)
125
+ xcur.parent.r = xglue
126
+ else
127
+ xcur.parent.l = xglue
128
+ end
129
+
130
+ xcur.parent = xglue
131
+
132
+ xnew
133
+ end
134
+
135
+ # generate pdf with `dot -Tpdf <input> > foo.pdf`
136
+ def to_dot(header = true)
137
+ res = ''
138
+ res = "graph trie {\n" if header
139
+
140
+ next_name = 'a'
141
+ obj_label_map = Hash.new do |h, k|
142
+ h[k] = next_name
143
+ next_name = next_name.next
144
+ h[k]
145
+ end
146
+
147
+ head.walk(max_num_bits, true) do |node|
148
+ node_name = obj_label_map[node.object_id]
149
+
150
+ if node.empty?
151
+ label = "<glue at bit #{node.bit}>"
152
+ else
153
+ ip_addr = IPAddr.new(node.prefix.address, node.prefix.family)
154
+ label = ip_addr.to_s + '/' + node.prefix.bitlen.to_s
155
+ end
156
+ res += "#{node_name} [label=\"#{label}\"]\n"
157
+ res += "#{node_name} -- #{obj_label_map[node.l.object_id]} [label=\"l\"]\n" if node.l
158
+ res += "#{node_name} -- #{obj_label_map[node.r.object_id]} [label=\"r\"]\n" if node.r
159
+ end
160
+ res += "}\n" if header
161
+ res
162
+ end
163
+
164
+ def search_best(addr, family)
165
+ nodes = search_common(addr, family)
166
+ for i in (nodes.size - 1).downto(0)
167
+ xcur = nodes[i]
168
+ return node_to_ip_addr(xcur) if xcur.prefix.matches?(addr, family)
169
+ end
170
+
171
+ nil
172
+ end
173
+
174
+ def search_matching(addr, family)
175
+ nodes = search_common(addr, family)
176
+ nodes.select { |xcur| xcur.prefix.matches?(addr, family) }
177
+ .map { |xcur| node_to_ip_addr(xcur) }
178
+ .reverse
179
+ end
180
+
181
+ private
182
+
183
+ def node_to_ip_addr(node)
184
+ ret = IPAddr.new(node.prefix.address, node.prefix.family)
185
+ ret.singleton_class.send(:define_method, :data) { node.prefix.data }
186
+ ret
187
+ end
188
+
189
+ def bit_set?(addr, i)
190
+ addr[max_num_bits - i - 1] == 1
191
+ end
192
+
193
+ def search_common(addr, family)
194
+ raise 'family mismatch' unless family == self.family
195
+
196
+ xstack = []
197
+
198
+ xcur = head
199
+ while !xcur.nil?
200
+ unless xcur.empty?
201
+ xstack << xcur
202
+ end
203
+
204
+ xcur = bit_set?(addr, xcur.bit) ? xcur.r : xcur.l
205
+ end
206
+
207
+ xstack
208
+ end
209
+ end
210
+
211
+ Prefix = Struct.new(:family, :bitlen, :address, :data) do # addr is integer
212
+ def initialize(*args)
213
+ super
214
+ raise ArgumentError, 'no family given' unless family
215
+ raise ArgumentError, 'no bitlen given' unless bitlen
216
+ raise ArgumentError, 'no address given' unless address
217
+ end
218
+
219
+ def matches?(addr, family)
220
+ raise 'family mismatch' unless family == self.family
221
+ shift_amount = (family == Socket::AF_INET ? 32 : 128) - self.bitlen
222
+ (addr ^ self.address) >> shift_amount == 0
223
+ end
224
+ end
225
+
226
+ def Prefix.from_str(str, data = nil)
227
+ ip_addr = IPAddr.new(str)
228
+ if str =~ /\/(\d+)$/
229
+ bitlen = $~[1].to_i
230
+ else
231
+ bitlen = ip_addr.family == Socket::AF_INET6 ? 128 : 32
232
+ end
233
+ Prefix.new(ip_addr.family, bitlen, ip_addr.to_i, data)
234
+ end
235
+
236
+ # bit starts at 0 (most significant)
237
+ Node = Struct.new(:bit, :prefix, :l, :r, :parent) do
238
+ def initialize(*args)
239
+ super
240
+ raise ArgumentError, 'no bit given' if bit.nil?
241
+ end
242
+
243
+ def empty?
244
+ prefix.nil?
245
+ end
246
+
247
+ # cover the whole tree
248
+ def walk(max_bits, empty_nodes = false)
249
+ xstack = Array.new(max_bits + 1)
250
+ sidx = 0 # stack index
251
+ xhead = self
252
+ xcur = xhead
253
+ while !xcur.nil?
254
+ yield xcur unless xcur.empty? && !empty_nodes
255
+
256
+ if xcur.l
257
+ if xcur.r
258
+ xstack[sidx] = xcur.r
259
+ sidx += 1
260
+ end
261
+ xcur = xcur.l
262
+ elsif xcur.r
263
+ xcur = xcur.r
264
+ elsif sidx.nonzero?
265
+ sidx -= 1
266
+ xcur = xstack[sidx]
267
+ else
268
+ xcur = nil
269
+ end
270
+ end
271
+ end
272
+ end
273
+
274
+ end
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
2
  # Please refer to our terms for more information: https://www.sqreen.io/terms.html
3
3
  module Sqreen
4
- VERSION = '1.15.0'.freeze
4
+ VERSION = '1.15.5'.freeze
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sqreen
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.15.0
4
+ version: 1.15.5
5
5
  platform: java
6
6
  authors:
7
7
  - Sqreen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-24 00:00:00.000000000 Z
11
+ date: 2018-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -89,6 +89,7 @@ files:
89
89
  - lib/sqreen/metrics/sum.rb
90
90
  - lib/sqreen/metrics_store.rb
91
91
  - lib/sqreen/middleware.rb
92
+ - lib/sqreen/mono_time.rb
92
93
  - lib/sqreen/payload_creator.rb
93
94
  - lib/sqreen/performance_notifications.rb
94
95
  - lib/sqreen/performance_notifications/binned_metrics.rb
@@ -131,6 +132,7 @@ files:
131
132
  - lib/sqreen/session.rb
132
133
  - lib/sqreen/shared_storage.rb
133
134
  - lib/sqreen/shared_storage23.rb
135
+ - lib/sqreen/trie.rb
134
136
  - lib/sqreen/version.rb
135
137
  homepage: https://www.sqreen.io/
136
138
  licenses: []