rookout 0.1.37 → 0.1.40
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 +39 -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 +22 -0
- data/lib/rookout/exceptions.rb +26 -1
- data/lib/rookout/processor/namespace_serializer2.rb +8 -1
- 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 +19 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7605e9deab6fab2b1456185132e9db8100f143e0486a6cbef13a20a368047ad1
|
4
|
+
data.tar.gz: 900c58be123cfad2b749a16dce8ed3e6fa572af1177ee3778fe9318c02a2f81b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d4bf7792481a091c0110353cf727f44486b08dd099bba996ce83c7b05e88213f8a714dcbfb2840944876a49a8a794f2496c501c1c19ec5c341f1493ab925ace
|
7
|
+
data.tar.gz: 5069a96af2a1a11b0e7d07be6def3a42bdbf0b94658bc16ff652d06ae623295f5c9b4ea02cbee21cae3d68a236f283568d0136d04edcc51937c68c4a31ba635b
|
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,48 @@ 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}"
|
84
|
+
Rookout::Config.using_global_rate_limiter = true
|
76
85
|
end
|
77
86
|
|
78
|
-
|
87
|
+
@global_rate_limiter
|
88
|
+
end
|
89
|
+
|
90
|
+
def parse_rate_limit config, modifier_config, default_quota, default_window
|
91
|
+
window_quota = default_quota
|
92
|
+
window_size = default_window
|
93
|
+
|
94
|
+
unless config.nil? || config.empty?
|
95
|
+
rate_limit_split = config.split "/"
|
96
|
+
unless rate_limit_split.length == 2 && rate_limit_split[0].is_number? && rate_limit_split[1].is_number?
|
97
|
+
raise Exceptions::RookInvalidRateLimitConfiguration, config
|
98
|
+
end
|
99
|
+
|
100
|
+
window_quota = rate_limit_split[0].to_i
|
101
|
+
window_size = rate_limit_split[1].to_i
|
102
|
+
end
|
79
103
|
|
80
104
|
window_quota_ns = Utils.milliseconds_to_nanoseconds window_quota
|
81
105
|
window_size_ns = Utils.milliseconds_to_nanoseconds window_size
|
106
|
+
rate_limit_modifier = modifier_config.to_i || 5
|
82
107
|
|
83
|
-
|
108
|
+
[window_quota_ns, window_size_ns, rate_limit_modifier]
|
84
109
|
end
|
85
110
|
end
|
86
111
|
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.create
|
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,18 @@ 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
|
+
attr_accessor :using_global_rate_limiter
|
81
|
+
|
82
|
+
Rookout::Config.global_rate_limit = nil
|
83
|
+
Rookout::Config.using_global_rate_limiter = false
|
79
84
|
|
80
85
|
def update_config configuration
|
86
|
+
update_var2_config configuration
|
87
|
+
update_global_rate_limit_config configuration
|
88
|
+
end
|
89
|
+
|
90
|
+
def update_var2_config configuration
|
81
91
|
is_config_proto2 = configuration["RUBY_PROTOBUF_VERSION_2"]
|
82
92
|
return if is_config_proto2.nil?
|
83
93
|
is_env_proto2 = ENV["ROOKOUT_Protobuf_Version2"]
|
@@ -89,6 +99,18 @@ module Rookout
|
|
89
99
|
end
|
90
100
|
Logger.instance.info "Updating ROOKOUT_Protobuf_Version2 value to: #{@protobuf_version2}"
|
91
101
|
end
|
102
|
+
|
103
|
+
def update_global_rate_limit_config configuration
|
104
|
+
global_rate_limit = ENV["ROOKOUT_GLOBAL_RATE_LIMIT"]
|
105
|
+
if global_rate_limit.nil?
|
106
|
+
global_rate_limit = configuration["RUBY_GLOBAL_RATE_LIMIT"]
|
107
|
+
end
|
108
|
+
|
109
|
+
return if global_rate_limit.nil?
|
110
|
+
|
111
|
+
@global_rate_limit = global_rate_limit
|
112
|
+
Logger.instance.info "Updating global rate limit to: #{global_rate_limit}"
|
113
|
+
end
|
92
114
|
end
|
93
115
|
end
|
94
116
|
end
|
data/lib/rookout/exceptions.rb
CHANGED
@@ -95,13 +95,29 @@ module Rookout
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
-
class
|
98
|
+
class RookRuleAugRateLimited < ToolException
|
99
99
|
def initialize
|
100
100
|
super "Breakpoint was disabled due to rate-limiting. " \
|
101
101
|
"For more information: https://docs.rookout.com/docs/breakpoints-tasks.html#rate-limiting"
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
+
class RookRuleGlobalRateLimited < ToolException
|
106
|
+
def initialize
|
107
|
+
super "Breakpoint was disabled due to global rate-limiting. " \
|
108
|
+
"For more information: https://docs.rookout.com/docs/breakpoints-tasks.html#rate-limiting"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
class RookRuleRateLimited
|
113
|
+
def self.create
|
114
|
+
if Rookout::Config.using_global_rate_limiter
|
115
|
+
return RookRuleGlobalRateLimited.new
|
116
|
+
end
|
117
|
+
RookRuleAugRateLimited.new
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
105
121
|
class RookInvalidToken < ToolException
|
106
122
|
def initialize token = ""
|
107
123
|
super "The Rookout token supplied #{token[0..6]} is not valid; please check the token and try again",
|
@@ -214,6 +230,15 @@ module Rookout
|
|
214
230
|
end
|
215
231
|
end
|
216
232
|
|
233
|
+
class RookInvalidRateLimitConfiguration < ToolException
|
234
|
+
def initialize config
|
235
|
+
super "Invalid rate limit configuration: #{config}",
|
236
|
+
{
|
237
|
+
"rate_limit_config" => config
|
238
|
+
}
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
217
242
|
class RookUnsupportedLiveLogger < ToolException
|
218
243
|
def initialize
|
219
244
|
super "Live Logger is not supported. Try using Rookout Live Debugger instead."
|
@@ -9,6 +9,13 @@ module Rookout
|
|
9
9
|
require_relative "./namespaces/container_namespace"
|
10
10
|
require_relative "./namespaces/traceback_namespace"
|
11
11
|
|
12
|
+
begin
|
13
|
+
require "hashie/mash"
|
14
|
+
MASH = ::Hashie::Mash
|
15
|
+
rescue LoadError
|
16
|
+
MASH = nil
|
17
|
+
end
|
18
|
+
|
12
19
|
def initialize
|
13
20
|
@string_cache = {}
|
14
21
|
@estimated_pending_bytes = 0
|
@@ -98,7 +105,7 @@ module Rookout
|
|
98
105
|
dump_time obj, variant
|
99
106
|
elsif obj.class == Array
|
100
107
|
dump_array obj, variant, current_depth, config, log_object_errors
|
101
|
-
elsif obj.class == Hash
|
108
|
+
elsif obj.class == Hash || (!MASH.nil? && obj.is_a?(MASH))
|
102
109
|
dump_hash obj, variant, current_depth, config, log_object_errors
|
103
110
|
elsif obj.is_a? Exception
|
104
111
|
dump_exception obj, variant, current_depth, config, log_object_errors
|
@@ -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.40
|
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-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: binding_of_caller
|
@@ -192,6 +192,20 @@ dependencies:
|
|
192
192
|
- - ">="
|
193
193
|
- !ruby/object:Gem::Version
|
194
194
|
version: '1.0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: hashie
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: 5.0.0
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: 5.0.0
|
195
209
|
description: rookout is the Ruby SDK for the Rookout Debugging Platform
|
196
210
|
email:
|
197
211
|
- support@rookout.com
|
@@ -211,6 +225,7 @@ files:
|
|
211
225
|
- lib/rookout/augs/aug_rate_limiter.rb
|
212
226
|
- lib/rookout/augs/augs_manager.rb
|
213
227
|
- lib/rookout/augs/conditions/condition.rb
|
228
|
+
- lib/rookout/augs/limits_manager.rb
|
214
229
|
- lib/rookout/augs/locations/location.rb
|
215
230
|
- lib/rookout/augs/locations/location_exception_handler.rb
|
216
231
|
- lib/rookout/augs/locations/location_file_line.rb
|
@@ -259,6 +274,7 @@ files:
|
|
259
274
|
- lib/rookout/protobuf/variant2_pb.rb
|
260
275
|
- lib/rookout/protobuf/variant_pb.rb
|
261
276
|
- lib/rookout/rookout_singleton.rb
|
277
|
+
- lib/rookout/sanitizer.rb
|
262
278
|
- lib/rookout/services/position.rb
|
263
279
|
- lib/rookout/services/tracer.rb
|
264
280
|
- lib/rookout/trigger_services.rb
|
@@ -285,7 +301,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
285
301
|
- !ruby/object:Gem::Version
|
286
302
|
version: '0'
|
287
303
|
requirements: []
|
288
|
-
rubygems_version: 3.
|
304
|
+
rubygems_version: 3.3.7
|
289
305
|
signing_key:
|
290
306
|
specification_version: 4
|
291
307
|
summary: rookout is the Ruby SDK for the Rookout Debugging Platform
|