rookout 0.1.38 → 0.1.39
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rookout/augs/aug.rb +3 -5
- data/lib/rookout/augs/aug_factory.rb +38 -14
- data/lib/rookout/augs/aug_rate_limiter.rb +33 -34
- data/lib/rookout/augs/limits_manager.rb +31 -0
- data/lib/rookout/commit.rb +1 -1
- data/lib/rookout/config.rb +20 -0
- data/lib/rookout/exceptions.rb +9 -0
- data/lib/rookout/sanitizer.rb +22 -0
- data/lib/rookout/utils.rb +6 -0
- data/lib/rookout/version.rb +1 -1
- data/lib/rookout.rb +4 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb5d9fef64ead13081355d267ad49671d0ca9ddf3e916ab5cf556d6d3b5997be
|
4
|
+
data.tar.gz: e114be3eb5224761c01f5a64bd4f367a90effed5d130c61f90ab4a8328152928
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1da019cfc4c4cbeada393163a6fb4fa01826fdfe9d76edfd0926218b40d6dbedafb2291de4c63a558ac521bf6d360fee76a8522b2a10d021ce7d3538ce1ae530
|
7
|
+
data.tar.gz: 0a24f0bee3b44a23c9ad1ab7e1cdd6c6fc694e50358abd9d96b219ab3a5116c6567ebfd94a498de0de3cda523605fe2d0d27617d3aca7a9161689eeaa9132131
|
data/lib/rookout/augs/aug.rb
CHANGED
@@ -10,13 +10,11 @@ module Rookout
|
|
10
10
|
require_relative "../logger"
|
11
11
|
|
12
12
|
class Aug
|
13
|
-
def initialize aug_id, action, condition,
|
14
|
-
# NOTE: max_aux_time is not implemented
|
15
|
-
|
13
|
+
def initialize aug_id, action, condition, limits_manager, _max_aug_time
|
16
14
|
@id = aug_id
|
17
15
|
@action = action
|
18
16
|
@condition = condition
|
19
|
-
@
|
17
|
+
@limits_manager = limits_manager
|
20
18
|
|
21
19
|
@enabled = true
|
22
20
|
@status = nil
|
@@ -36,7 +34,7 @@ module Rookout
|
|
36
34
|
namespace = create_namespaces frame, extracted
|
37
35
|
return if @condition && !@condition.evaluate(namespace)
|
38
36
|
|
39
|
-
@
|
37
|
+
@limits_manager.with_limit do
|
40
38
|
report_id = Utils.uuid
|
41
39
|
Logger.instance.info "Executing aug-\t#{id} (msg ID #{report_id})"
|
42
40
|
@action.execute @id, report_id, namespace, output
|
@@ -10,7 +10,9 @@ module Rookout
|
|
10
10
|
require_relative "locations/location_exception_handler"
|
11
11
|
require_relative "aug_rate_limiter"
|
12
12
|
require_relative "aug"
|
13
|
+
require_relative "limits_manager"
|
13
14
|
require_relative "../utils"
|
15
|
+
require_relative "../logger"
|
14
16
|
|
15
17
|
class AugFactory
|
16
18
|
def initialize output
|
@@ -34,10 +36,10 @@ module Rookout
|
|
34
36
|
end
|
35
37
|
condition = condition_configuration.nil? ? nil : Conditions::Condition.new(condition_configuration)
|
36
38
|
|
37
|
-
|
39
|
+
limits_manager = create_limits_manager configuration
|
38
40
|
|
39
41
|
max_aug_time_ns = Utils.milliseconds_to_nanoseconds max_aug_time
|
40
|
-
aug = Aug.new aug_id, action, condition,
|
42
|
+
aug = Aug.new aug_id, action, condition, limits_manager, max_aug_time_ns
|
41
43
|
|
42
44
|
location_configuration = configuration["location"]
|
43
45
|
raise Exceptions::RookAugInvalidKey.new("location", configuration) unless location_configuration.is_a? Hash
|
@@ -62,25 +64,47 @@ module Rookout
|
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
65
|
-
def
|
66
|
-
|
67
|
-
|
67
|
+
def create_limits_manager configuration
|
68
|
+
limiters = []
|
69
|
+
if global_rate_limiter.nil?
|
70
|
+
rate_limit = parse_rate_limit configuration["rateLimit"], configuration["rateLimitModifier"], 200, 5000
|
71
|
+
limiters.append AugRateLimiter.new(*rate_limit)
|
72
|
+
else
|
73
|
+
limiters.append global_rate_limiter
|
74
|
+
end
|
68
75
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
+
LimitsManager.new limiters
|
77
|
+
end
|
78
|
+
|
79
|
+
def global_rate_limiter
|
80
|
+
if @global_rate_limiter.nil? && !Rookout::Config.global_rate_limit.nil?
|
81
|
+
rate_limit = parse_rate_limit Rookout::Config.global_rate_limit, "0", 0, 0
|
82
|
+
@global_rate_limiter = AugRateLimiter.new(*rate_limit)
|
83
|
+
Logger.instance.debug "Using global rate limiter with configuration: #{rate_limit}"
|
76
84
|
end
|
77
85
|
|
78
|
-
|
86
|
+
@global_rate_limiter
|
87
|
+
end
|
88
|
+
|
89
|
+
def parse_rate_limit config, modifier_config, default_quota, default_window
|
90
|
+
window_quota = default_quota
|
91
|
+
window_size = default_window
|
92
|
+
|
93
|
+
unless config.nil? || config.empty?
|
94
|
+
rate_limit_split = config.split "/"
|
95
|
+
unless rate_limit_split.length == 2 && rate_limit_split[0].is_number? && rate_limit_split[1].is_number?
|
96
|
+
raise Exceptions::RookInvalidRateLimitConfiguration, config
|
97
|
+
end
|
98
|
+
|
99
|
+
window_quota = rate_limit_split[0].to_i
|
100
|
+
window_size = rate_limit_split[1].to_i
|
101
|
+
end
|
79
102
|
|
80
103
|
window_quota_ns = Utils.milliseconds_to_nanoseconds window_quota
|
81
104
|
window_size_ns = Utils.milliseconds_to_nanoseconds window_size
|
105
|
+
rate_limit_modifier = modifier_config.to_i || 5
|
82
106
|
|
83
|
-
|
107
|
+
[window_quota_ns, window_size_ns, rate_limit_modifier]
|
84
108
|
end
|
85
109
|
end
|
86
110
|
end
|
@@ -8,51 +8,50 @@ module Rookout
|
|
8
8
|
@quota = quota
|
9
9
|
@has_quota = !@quota.nil? && (@quota > 0)
|
10
10
|
@window_size = window_size
|
11
|
-
|
11
|
+
if active_limit > 0
|
12
|
+
@active_weight = quota / active_limit
|
13
|
+
else
|
14
|
+
@active_weight = 0
|
15
|
+
end
|
12
16
|
|
13
17
|
@mutex = Mutex.new
|
14
18
|
@active_count = 0
|
15
19
|
@windows = {}
|
16
20
|
end
|
17
21
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
@
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
# If exceeding quota
|
38
|
-
if current_usage(now_ns, current_window_key, prev_window_key) > @quota
|
39
|
-
warning = Processor::RookError.new Exceptions::RookRuleRateLimited.new
|
40
|
-
UserWarnings.notify_warning warning
|
41
|
-
return
|
42
|
-
end
|
22
|
+
def before_run start_time
|
23
|
+
# If no quota, we can safely exit
|
24
|
+
unless @has_quota
|
25
|
+
return true
|
26
|
+
end
|
27
|
+
now_ns = Utils.time_to_nanoseconds start_time
|
28
|
+
current_window_key, prev_window_key = timestamp_to_window_keys now_ns
|
29
|
+
|
30
|
+
@mutex.synchronize do
|
31
|
+
# Clean old windows
|
32
|
+
cleanup now_ns
|
33
|
+
usage = current_usage now_ns, current_window_key, prev_window_key
|
34
|
+
@active_count += 1
|
35
|
+
|
36
|
+
# If exceeding quota
|
37
|
+
if usage > @quota
|
38
|
+
warning = Processor::RookError.new Exceptions::RookRuleRateLimited.new
|
39
|
+
UserWarnings.notify_warning warning
|
40
|
+
return false
|
43
41
|
end
|
42
|
+
|
43
|
+
return true
|
44
44
|
end
|
45
|
+
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
47
|
+
def after_run start_time
|
48
|
+
if @has_quota
|
49
|
+
now_ns = Utils.time_to_nanoseconds start_time
|
50
|
+
current_window_key, = timestamp_to_window_keys now_ns
|
51
|
+
@mutex.synchronize { record_usage current_window_key, Utils.time_to_nanoseconds(Time.now) - now_ns }
|
52
52
|
end
|
53
|
-
ensure
|
54
53
|
# Reduce active count
|
55
|
-
@mutex.synchronize { @active_count -= 1 }
|
54
|
+
@mutex.synchronize { @active_count -= 1 }
|
56
55
|
end
|
57
56
|
|
58
57
|
private
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Rookout
|
2
|
+
module Augs
|
3
|
+
class LimitsManager
|
4
|
+
def initialize limiters
|
5
|
+
@limiters = limiters
|
6
|
+
end
|
7
|
+
|
8
|
+
def with_limit start_time = nil
|
9
|
+
start_time ||= Time.now
|
10
|
+
can_execute = true
|
11
|
+
after_execute = []
|
12
|
+
|
13
|
+
@limiters.each do |limiter|
|
14
|
+
if limiter.before_run start_time
|
15
|
+
after_execute.append -> { limiter.after_run start_time }
|
16
|
+
else
|
17
|
+
can_execute = false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
if can_execute
|
22
|
+
yield
|
23
|
+
end
|
24
|
+
ensure
|
25
|
+
unless after_execute.nil?
|
26
|
+
after_execute.each(&:call)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/rookout/commit.rb
CHANGED
data/lib/rookout/config.rb
CHANGED
@@ -76,8 +76,16 @@ module Rookout
|
|
76
76
|
|
77
77
|
Rookout::Config.true_values = ["y", "Y", "yes", "Yes", "YES", "true", "True", "TRUE", "1"]
|
78
78
|
|
79
|
+
attr_accessor :global_rate_limit
|
80
|
+
|
81
|
+
Rookout::Config.global_rate_limit = nil
|
79
82
|
|
80
83
|
def update_config configuration
|
84
|
+
update_var2_config configuration
|
85
|
+
update_global_rate_limit_config configuration
|
86
|
+
end
|
87
|
+
|
88
|
+
def update_var2_config configuration
|
81
89
|
is_config_proto2 = configuration["RUBY_PROTOBUF_VERSION_2"]
|
82
90
|
return if is_config_proto2.nil?
|
83
91
|
is_env_proto2 = ENV["ROOKOUT_Protobuf_Version2"]
|
@@ -89,6 +97,18 @@ module Rookout
|
|
89
97
|
end
|
90
98
|
Logger.instance.info "Updating ROOKOUT_Protobuf_Version2 value to: #{@protobuf_version2}"
|
91
99
|
end
|
100
|
+
|
101
|
+
def update_global_rate_limit_config configuration
|
102
|
+
global_rate_limit = ENV["ROOKOUT_GLOBAL_RATE_LIMIT"]
|
103
|
+
if global_rate_limit.nil?
|
104
|
+
global_rate_limit = configuration["RUBY_GLOBAL_RATE_LIMIT"]
|
105
|
+
end
|
106
|
+
|
107
|
+
return if global_rate_limit.nil?
|
108
|
+
|
109
|
+
@global_rate_limit = global_rate_limit
|
110
|
+
Logger.instance.info "Updating global rate limit to: #{global_rate_limit}"
|
111
|
+
end
|
92
112
|
end
|
93
113
|
end
|
94
114
|
end
|
data/lib/rookout/exceptions.rb
CHANGED
@@ -214,6 +214,15 @@ module Rookout
|
|
214
214
|
end
|
215
215
|
end
|
216
216
|
|
217
|
+
class RookInvalidRateLimitConfiguration < ToolException
|
218
|
+
def initialize config
|
219
|
+
super "Invalid rate limit configuration: #{config}",
|
220
|
+
{
|
221
|
+
"rate_limit_config" => config
|
222
|
+
}
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
217
226
|
class RookUnsupportedLiveLogger < ToolException
|
218
227
|
def initialize
|
219
228
|
super "Live Logger is not supported. Try using Rookout Live Debugger instead."
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "set"
|
2
|
+
module Rookout
|
3
|
+
class Sanitizer
|
4
|
+
@@blacklisted_properties = Set["labels", "ROOKOUT_LABELS"]
|
5
|
+
|
6
|
+
def self.sanitize_object! obj
|
7
|
+
obj.each_key do |key|
|
8
|
+
if obj[key].is_a?(String) && !@@blacklisted_properties.include?(key.to_s)
|
9
|
+
obj[key] = obj[key].strip
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.sanitize_properties!
|
15
|
+
ENV.each do |key, val|
|
16
|
+
if key.start_with?("ROOKOUT_") && !@@blacklisted_properties.include?(key.to_s)
|
17
|
+
ENV[key] = val.strip
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/rookout/utils.rb
CHANGED
data/lib/rookout/version.rb
CHANGED
data/lib/rookout.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rookout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.39
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Liran Haimovitch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: binding_of_caller
|
@@ -225,6 +225,7 @@ files:
|
|
225
225
|
- lib/rookout/augs/aug_rate_limiter.rb
|
226
226
|
- lib/rookout/augs/augs_manager.rb
|
227
227
|
- lib/rookout/augs/conditions/condition.rb
|
228
|
+
- lib/rookout/augs/limits_manager.rb
|
228
229
|
- lib/rookout/augs/locations/location.rb
|
229
230
|
- lib/rookout/augs/locations/location_exception_handler.rb
|
230
231
|
- lib/rookout/augs/locations/location_file_line.rb
|
@@ -273,6 +274,7 @@ files:
|
|
273
274
|
- lib/rookout/protobuf/variant2_pb.rb
|
274
275
|
- lib/rookout/protobuf/variant_pb.rb
|
275
276
|
- lib/rookout/rookout_singleton.rb
|
277
|
+
- lib/rookout/sanitizer.rb
|
276
278
|
- lib/rookout/services/position.rb
|
277
279
|
- lib/rookout/services/tracer.rb
|
278
280
|
- lib/rookout/trigger_services.rb
|