sqreen 1.15.0-java → 1.15.5-java

Sign up to get free protection for your applications and to get access to all the features.
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: []