rookout 0.1.38 → 0.1.39
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.
- 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
|