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.
- checksums.yaml +4 -4
- data/lib/sqreen/actions.rb +114 -43
- data/lib/sqreen/callback_tree.rb +16 -3
- data/lib/sqreen/callbacks.rb +7 -34
- data/lib/sqreen/capped_queue.rb +5 -1
- data/lib/sqreen/configuration.rb +4 -0
- data/lib/sqreen/deliveries/batch.rb +7 -4
- data/lib/sqreen/event.rb +4 -0
- data/lib/sqreen/events/request_record.rb +40 -7
- data/lib/sqreen/frameworks/generic.rb +0 -2
- data/lib/sqreen/frameworks/request_recorder.rb +14 -1
- data/lib/sqreen/instrumentation.rb +57 -33
- data/lib/sqreen/js/mini_racer_adapter.rb +46 -8
- data/lib/sqreen/metrics/average.rb +1 -1
- data/lib/sqreen/metrics/base.rb +4 -2
- data/lib/sqreen/metrics/binning.rb +3 -2
- data/lib/sqreen/metrics/collect.rb +1 -1
- data/lib/sqreen/metrics/sum.rb +1 -1
- data/lib/sqreen/metrics_store.rb +10 -5
- data/lib/sqreen/mono_time.rb +18 -0
- data/lib/sqreen/performance_notifications.rb +13 -38
- data/lib/sqreen/performance_notifications/binned_metrics.rb +12 -14
- data/lib/sqreen/performance_notifications/log.rb +6 -1
- data/lib/sqreen/performance_notifications/log_performance.rb +3 -1
- data/lib/sqreen/performance_notifications/metrics.rb +6 -3
- data/lib/sqreen/performance_notifications/newrelic.rb +6 -2
- data/lib/sqreen/remote_command.rb +26 -0
- data/lib/sqreen/rule_attributes.rb +1 -0
- data/lib/sqreen/rule_callback.rb +38 -0
- data/lib/sqreen/rules_callbacks/binding_accessor_matcher.rb +3 -2
- data/lib/sqreen/rules_callbacks/blacklist_ips.rb +1 -1
- data/lib/sqreen/rules_callbacks/run_block_user_actions.rb +1 -1
- data/lib/sqreen/rules_callbacks/run_req_start_actions.rb +8 -2
- data/lib/sqreen/runner.rb +11 -8
- data/lib/sqreen/sdk.rb +7 -1
- data/lib/sqreen/session.rb +4 -0
- data/lib/sqreen/trie.rb +274 -0
- data/lib/sqreen/version.rb +1 -1
- 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[
|
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
|
39
|
-
actions_repo
|
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)
|
data/lib/sqreen/runner.rb
CHANGED
@@ -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.
|
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("
|
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
|
data/lib/sqreen/sdk.rb
CHANGED
@@ -24,7 +24,13 @@ module Sqreen
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def track(event_name, options = {})
|
27
|
-
|
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.')
|
data/lib/sqreen/session.rb
CHANGED
@@ -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
|
|
data/lib/sqreen/trie.rb
ADDED
@@ -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
|
data/lib/sqreen/version.rb
CHANGED
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.
|
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-
|
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: []
|