rookout 0.1.40 → 0.1.50

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7605e9deab6fab2b1456185132e9db8100f143e0486a6cbef13a20a368047ad1
4
- data.tar.gz: 900c58be123cfad2b749a16dce8ed3e6fa572af1177ee3778fe9318c02a2f81b
3
+ metadata.gz: 72f208b3a47ef61e59b2123afe3e666a2f3efa8295ddec10950e221e5547770a
4
+ data.tar.gz: 216a478be4998de21db6b2df156123d6cde587a54369914d93ba2f3ef8f9b5a7
5
5
  SHA512:
6
- metadata.gz: 0d4bf7792481a091c0110353cf727f44486b08dd099bba996ce83c7b05e88213f8a714dcbfb2840944876a49a8a794f2496c501c1c19ec5c341f1493ab925ace
7
- data.tar.gz: 5069a96af2a1a11b0e7d07be6def3a42bdbf0b94658bc16ff652d06ae623295f5c9b4ea02cbee21cae3d68a236f283568d0136d04edcc51937c68c4a31ba635b
6
+ metadata.gz: c9c2e1c91cba199a499fb360f519dcce9081f9c5693cf9919aaff369cd2389534900be7b580e03a3b9ef24e91394db0eec9d25e3968163de87a9390aec288392
7
+ data.tar.gz: 476c8d023ae8e04214693c3b929d0dae31bcf364cf23cc443bf3aab2c29bd05f08db4646a366cb54b4b5208d188df22024886bd35421849c73e331db720eb960
@@ -16,6 +16,7 @@ module Rookout
16
16
  @condition = condition
17
17
  @limits_manager = limits_manager
18
18
 
19
+ @executed = false
19
20
  @enabled = true
20
21
  @status = nil
21
22
  @log_cache = []
@@ -27,14 +28,16 @@ module Rookout
27
28
  return unless @enabled
28
29
 
29
30
  if output.user_messages_queue_full?
30
- Logger.instance.warning "Skipping aug-\t#{id} execution because the queue is full"
31
+ output.send_output_queue_full_warning @id
31
32
  return
32
33
  end
33
34
 
34
35
  namespace = create_namespaces frame, extracted
35
36
  return if @condition && !@condition.evaluate(namespace)
36
37
 
37
- @limits_manager.with_limit do
38
+ should_skip_limiters = @condition.nil? && !@executed
39
+ @limits_manager.with_limit should_skip_limiters do
40
+ @executed = true
38
41
  report_id = Utils.uuid
39
42
  Logger.instance.info "Executing aug-\t#{id} (msg ID #{report_id})"
40
43
  @action.execute @id, report_id, namespace, output
@@ -68,7 +68,9 @@ module Rookout
68
68
  limiters = []
69
69
  if global_rate_limiter.nil?
70
70
  rate_limit = parse_rate_limit configuration["rateLimit"], configuration["rateLimitModifier"], 200, 5000
71
- limiters.append AugRateLimiter.new(*rate_limit)
71
+ unless rate_limit.nil?
72
+ limiters.append AugRateLimiter.new(*rate_limit)
73
+ end
72
74
  else
73
75
  limiters.append global_rate_limiter
74
76
  end
@@ -77,8 +79,20 @@ module Rookout
77
79
  end
78
80
 
79
81
  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
+ if @global_rate_limiter.nil? && Rookout::Config.global_rate_limit != ""
83
+ begin
84
+ rate_limit = parse_rate_limit Rookout::Config.global_rate_limit,
85
+ "0", 0, 0
86
+ if rate_limit.nil?
87
+ raise Exceptions::RookInvalidRateLimitConfiguration, Rookout::Config.global_rate_limit
88
+ end
89
+ rescue Exceptions::RookInvalidRateLimitConfiguration => e
90
+ Logger.instance.warning "Failed to create global rate limiter: #{e.message}"
91
+ err = Processor::RookError.new e
92
+ UserWarnings.notify_error err
93
+ return nil
94
+ end
95
+
82
96
  @global_rate_limiter = AugRateLimiter.new(*rate_limit)
83
97
  Logger.instance.debug "Using global rate limiter with configuration: #{rate_limit}"
84
98
  Rookout::Config.using_global_rate_limiter = true
@@ -93,7 +107,9 @@ module Rookout
93
107
 
94
108
  unless config.nil? || config.empty?
95
109
  rate_limit_split = config.split "/"
96
- unless rate_limit_split.length == 2 && rate_limit_split[0].is_number? && rate_limit_split[1].is_number?
110
+ unless rate_limit_split.length == 2 && \
111
+ Utils.is_number?(rate_limit_split[0]) && \
112
+ Utils.is_number?(rate_limit_split[1])
97
113
  raise Exceptions::RookInvalidRateLimitConfiguration, config
98
114
  end
99
115
 
@@ -105,6 +121,14 @@ module Rookout
105
121
  window_size_ns = Utils.milliseconds_to_nanoseconds window_size
106
122
  rate_limit_modifier = modifier_config.to_i || 5
107
123
 
124
+ if window_quota_ns == 0
125
+ return nil
126
+ end
127
+
128
+ if window_quota_ns >= window_size_ns
129
+ raise Exceptions::RookInvalidRateLimitConfiguration, config
130
+ end
131
+
108
132
  [window_quota_ns, window_size_ns, rate_limit_modifier]
109
133
  end
110
134
  end
@@ -5,13 +5,14 @@ module Rookout
5
5
  @limiters = limiters
6
6
  end
7
7
 
8
- def with_limit start_time = nil
8
+ def with_limit skip_limiters, start_time = nil
9
9
  start_time ||= Time.now
10
10
  can_execute = true
11
11
  after_execute = []
12
12
 
13
13
  @limiters.each do |limiter|
14
- if limiter.before_run start_time
14
+ limiter_passed = limiter.before_run start_time
15
+ if limiter_passed || skip_limiters
15
16
  after_execute.append -> { limiter.after_run start_time }
16
17
  else
17
18
  can_execute = false
@@ -53,7 +53,7 @@ module Rookout
53
53
  def notify_warning error
54
54
  return if silence_log? error
55
55
 
56
- Logger.instance.warning error.message
56
+ Logger.instance.warning error.message, error.exception
57
57
 
58
58
  # For easier testing
59
59
  return if @output.nil?
@@ -26,8 +26,12 @@ module Rookout
26
26
  attr_reader :pending_messages
27
27
 
28
28
  def initialize output, agent_host, agent_port, proxy, token, labels, print_on_connect
29
- agent_host_with_protocl = agent_host.include?("://") ? agent_host : "ws://#{agent_host}"
30
- @uri = "#{agent_host_with_protocl}:#{agent_port}/v1"
29
+ if agent_host.nil? || agent_host.empty?
30
+ @uri = ""
31
+ else
32
+ agent_host_with_protocl = agent_host.include?("://") ? agent_host : "ws://#{agent_host}"
33
+ @uri = "#{agent_host_with_protocl}:#{agent_port}/v1"
34
+ end
31
35
  if proxy.nil? || proxy.empty?
32
36
  @proxy = nil
33
37
  else
@@ -57,14 +61,7 @@ module Rookout
57
61
  msg_size = envelope_wrapper.calculate_size
58
62
  if @pending_messages_length + msg_size > Config.agent_com_max_queue_messages_length ||
59
63
  queue_full?
60
- exc = Exceptions::RookMessageSizeExceeded.new msg_size, Config.agent_com_max_queue_messages_length
61
- warning = Processor::RookError.new exc
62
- UserWarnings.notify_warning warning
63
-
64
- Logger.instance.warning "Dropping message, size was #{msg_size}, pedning messages: #{@pending_messages_length}
65
- which is over the message size limit #{Config.agent_com_max_queue_messages_length},
66
- queue length: #{@pending_messages.length}"
67
- return
64
+ raise Exceptions::RookOutputQueueFull
68
65
  end
69
66
 
70
67
  @pending_messages.push envelope_wrapper
@@ -108,7 +105,6 @@ module Rookout
108
105
 
109
106
  private
110
107
 
111
- # rubocop:disable Style/StderrPuts
112
108
  def connection_thread
113
109
  backoff = Backoff.new
114
110
 
@@ -118,7 +114,8 @@ module Rookout
118
114
 
119
115
  if @print_on_initial_connection
120
116
  @print_on_initial_connection = false
121
- $stderr.puts "[Rookout] Successfully connected to controller"
117
+ Utils.quiet_puts "[Rookout] Successfully connected to controller."
118
+ Logger.instance.debug "[Rookout] Agent ID is #{@agent_id}"
122
119
  end
123
120
  Logger.instance.debug "WebSocket connected successfully"
124
121
  Logger.instance.info "Finished initialization"
@@ -142,13 +139,11 @@ module Rookout
142
139
  rescue Exception => e
143
140
  Logger.instance.error "Unexpected error in connection_thread", e
144
141
  end
145
- # rubocop:enable Style/StderrPuts
146
142
 
147
143
  def open_new_connection
148
144
  client = WebsocketClient.new @uri, @proxy, @token
149
145
  client.connect
150
146
 
151
- Logger.instance.info "Registering agent with id #{@agent_id}"
152
147
  msg = Com::Rookout::NewAgentMessage.new agent_info: @info.pack
153
148
  client.send_frame wrap_in_envelope(msg)
154
149
 
@@ -29,17 +29,26 @@ class Variant2EnvelopeWrapper < EnvelopeWrapperBase
29
29
  report_id: report_id
30
30
  @serializer = Rookout::Processor::NamespaceSerializer2.new
31
31
  @aug_report_message.arguments2 = @serializer.dump arguments, true
32
- @serializer.string_cache.each { |key, value| @aug_report_message.strings_cache[key] = value }
33
- @envelope = wrap_in_envelope @aug_report_message
34
- @aug_report_message = nil
32
+
33
+ @estimated_length = @serializer.estimated_pending_bytes
34
+ @envelope = nil
35
35
  end
36
36
 
37
37
  def envelope
38
+ if @envelope.nil?
39
+ @serializer.string_cache.each do |key, value|
40
+ @aug_report_message.strings_cache[key.encode "UTF-8", invalid: :replace, undef: :replace, replace: "?"] = value
41
+ end
42
+ @envelope = wrap_in_envelope @aug_report_message
43
+
44
+ @serializer = nil
45
+ @aug_report_message = nil
46
+ end
38
47
  @envelope
39
48
  end
40
49
 
41
50
  def calculate_size
42
- @envelope.length
51
+ @estimated_length
43
52
  end
44
53
  end
45
54
 
@@ -11,11 +11,15 @@ module Rookout
11
11
  require_relative "token_bucket"
12
12
  require_relative "envelope_wrapper"
13
13
 
14
+ require "concurrent"
15
+
14
16
  class Output
15
17
  def initialize
16
18
  @agent_id = nil
17
19
  @agent_com = nil
18
20
 
21
+ @skipped_aug_ids = Concurrent::Set.new
22
+
19
23
  @rule_status_update_bucket = TokenBucket.new Config.output_max_status_updates,
20
24
  Config.output_bucket_refresh_rate do
21
25
  Logger.instance.error "Limit reached, dropping status updates"
@@ -55,6 +59,17 @@ module Rookout
55
59
  @user_message_bucket.exhausted? || (!@agent_com.nil? && @agent_com.queue_full?)
56
60
  end
57
61
 
62
+ def send_output_queue_full_warning aug_id
63
+ if @skipped_aug_ids.include? aug_id
64
+ return
65
+ end
66
+
67
+ @skipped_aug_ids.add aug_id
68
+ error = Processor::RookError.new Exceptions::RookOutputQueueFull.new
69
+ send_rule_status aug_id, :Warning, error
70
+ Logger.instance.warning "Skipping aug-\t#{aug_id} execution because the queue is full"
71
+ end
72
+
58
73
  def send_warning rule_id, error
59
74
  send_rule_status rule_id, :Warning, error
60
75
  end
@@ -63,6 +78,10 @@ module Rookout
63
78
  return if @closing || !@agent_com
64
79
 
65
80
  @rule_status_update_bucket.if_available do
81
+ if active == "Deleted"
82
+ @skipped_aug_ids.delete? rule_id
83
+ end
84
+
66
85
  status = Com::Rookout::RuleStatusMessage.new agent_id: @agent_id,
67
86
  rule_id: rule_id,
68
87
  active: active
@@ -73,7 +92,11 @@ module Rookout
73
92
 
74
93
  envelope_wrapper = EnvelopeWrapper.new status
75
94
 
76
- @agent_com.add envelope_wrapper
95
+ begin
96
+ @agent_com.add envelope_wrapper
97
+ rescue Exceptions::RookOutputQueueFull
98
+ # Ignored
99
+ end
77
100
  end
78
101
  end
79
102
 
@@ -100,7 +123,12 @@ module Rookout
100
123
  )
101
124
  end
102
125
 
103
- @agent_com.add envelope_wrapper
126
+ begin
127
+ @agent_com.add envelope_wrapper
128
+ @skipped_aug_ids.delete? aug_id
129
+ rescue Exceptions::RookOutputQueueFull
130
+ send_output_queue_full_warning aug_id
131
+ end
104
132
  end
105
133
  end
106
134
 
@@ -144,7 +172,11 @@ module Rookout
144
172
 
145
173
  envelope_wrapper = EnvelopeWrapper.new msg
146
174
 
147
- @agent_com.add envelope_wrapper
175
+ begin
176
+ @agent_com.add envelope_wrapper
177
+ rescue Exceptions::RookOutputQueueFull
178
+ # Ignored
179
+ end
148
180
  end
149
181
  end
150
182
  end
@@ -1,3 +1,3 @@
1
1
  module Rookout
2
- COMMIT = "c62d573f33d1f62ad05aec7d28a4757fafb9a2b4".freeze
2
+ COMMIT = "9f3ecb29fbadc0c8f66233c9c44be100a912e577".freeze
3
3
  end
@@ -6,8 +6,10 @@ module Rookout
6
6
  # Magic to allow for module variables to be easily accessible
7
7
  class << self
8
8
  attr_accessor :debug
9
+ attr_accessor :quiet
9
10
 
10
11
  Rookout::Config.debug = false
12
+ Rookout::Config.quiet = false
11
13
 
12
14
  attr_accessor :logger_filename
13
15
  attr_accessor :logger_log_to_stderr
@@ -76,10 +78,14 @@ module Rookout
76
78
 
77
79
  Rookout::Config.true_values = ["y", "Y", "yes", "Yes", "YES", "true", "True", "TRUE", "1"]
78
80
 
81
+ attr_accessor :global_rate_limit_quota
82
+ attr_accessor :global_rate_limit_window_size
79
83
  attr_accessor :global_rate_limit
80
84
  attr_accessor :using_global_rate_limiter
81
85
 
82
- Rookout::Config.global_rate_limit = nil
86
+ Rookout::Config.global_rate_limit_quota = ""
87
+ Rookout::Config.global_rate_limit_window_size = ""
88
+ Rookout::Config.global_rate_limit = ""
83
89
  Rookout::Config.using_global_rate_limiter = false
84
90
 
85
91
  def update_config configuration
@@ -103,10 +109,15 @@ module Rookout
103
109
  def update_global_rate_limit_config configuration
104
110
  global_rate_limit = ENV["ROOKOUT_GLOBAL_RATE_LIMIT"]
105
111
  if global_rate_limit.nil?
106
- global_rate_limit = configuration["RUBY_GLOBAL_RATE_LIMIT"]
112
+ quota = configuration["RUBY_GLOBAL_RATE_LIMIT_QUOTA_MS"]
113
+ window_size = configuration["RUBY_GLOBAL_RATE_LIMIT_WINDOW_SIZE_MS"]
114
+
115
+ if quota != "" && !quota.nil? && window_size != "" && !window_size.nil?
116
+ global_rate_limit = "#{quota}/#{window_size}"
117
+ end
107
118
  end
108
119
 
109
- return if global_rate_limit.nil?
120
+ return if global_rate_limit.nil? || global_rate_limit == ""
110
121
 
111
122
  @global_rate_limit = global_rate_limit
112
123
  Logger.instance.info "Updating global rate limit to: #{global_rate_limit}"
@@ -95,6 +95,13 @@ module Rookout
95
95
  end
96
96
  end
97
97
 
98
+ class RookOutputQueueFull < ToolException
99
+ def initialize
100
+ super "Breakpoint triggered but output queue is full. " \
101
+ "Data collection will be disabled until the queue has emptied."
102
+ end
103
+ end
104
+
98
105
  class RookRuleAugRateLimited < ToolException
99
106
  def initialize
100
107
  super "Breakpoint was disabled due to rate-limiting. " \
@@ -139,6 +146,13 @@ module Rookout
139
146
  end
140
147
  end
141
148
 
149
+ class RookInvalidPositionException < ToolException
150
+ def initialize filename, line
151
+ super "Invalid code position for TracePoint: #{filename}:#{line}",
152
+ { filename: filename, line: line }
153
+ end
154
+ end
155
+
142
156
  class RookObjectCannotBeSerialized < ToolException
143
157
  def initialize object, message
144
158
  super message, { "class" => object.class.to_s }
@@ -234,7 +248,7 @@ module Rookout
234
248
  def initialize config
235
249
  super "Invalid rate limit configuration: #{config}",
236
250
  {
237
- "rate_limit_config" => config
251
+ "config" => config
238
252
  }
239
253
  end
240
254
  end
@@ -4,6 +4,7 @@ module Rookout
4
4
  include Singleton
5
5
 
6
6
  require_relative "config"
7
+ require_relative "utils"
7
8
  require_relative "exceptions"
8
9
  include Exceptions
9
10
 
@@ -16,6 +16,13 @@ module Rookout
16
16
  MASH = nil
17
17
  end
18
18
 
19
+ begin
20
+ require "active_support/core_ext/hash/indifferent_access"
21
+ HASH_WITH_INDIFFERENT_ACCESS = ActiveSupport::HashWithIndifferentAccess
22
+ rescue LoadError
23
+ HASH_WITH_INDIFFERENT_ACCESS = nil
24
+ end
25
+
19
26
  def initialize
20
27
  @string_cache = {}
21
28
  @estimated_pending_bytes = 0
@@ -37,10 +44,12 @@ module Rookout
37
44
 
38
45
  def dump_variant_type variant, type
39
46
  variant.variant_type_max_depth = type << 1
47
+ @estimated_pending_bytes += 2 # Field header + short number
40
48
  end
41
49
 
42
50
  def dump_variant_type_max_depth variant, type
43
51
  variant.variant_type_max_depth = (type << 1) | 1
52
+ @estimated_pending_bytes += 2 # Field header + short number
44
53
  end
45
54
 
46
55
  def dump namespace, log_errors
@@ -57,6 +66,7 @@ module Rookout
57
66
  rescue StandardError => e
58
67
  message = "Failed to serialize namespace"
59
68
  variant = Com::Rookout::Variant2.new
69
+ @estimated_pending_bytes = 0
60
70
  dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_ERROR
61
71
 
62
72
  if log_errors
@@ -77,6 +87,7 @@ module Rookout
77
87
  rescue StandardError => e
78
88
  message = "Failed to serialize object"
79
89
  variant = Com::Rookout::Variant2.new
90
+ @estimated_pending_bytes = 0
80
91
  dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_ERROR
81
92
 
82
93
  if log_object_errors
@@ -105,7 +116,8 @@ module Rookout
105
116
  dump_time obj, variant
106
117
  elsif obj.class == Array
107
118
  dump_array obj, variant, current_depth, config, log_object_errors
108
- elsif obj.class == Hash || (!MASH.nil? && obj.is_a?(MASH))
119
+ elsif obj.class == Hash || (!MASH.nil? && obj.is_a?(MASH)) ||
120
+ (!HASH_WITH_INDIFFERENT_ACCESS.nil? && obj.is_a?(HASH_WITH_INDIFFERENT_ACCESS))
109
121
  dump_hash obj, variant, current_depth, config, log_object_errors
110
122
  elsif obj.is_a? Exception
111
123
  dump_exception obj, variant, current_depth, config, log_object_errors
@@ -137,20 +149,24 @@ module Rookout
137
149
  when true
138
150
  dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_LONG
139
151
  variant.long_value = 1
152
+ @estimated_pending_bytes += 2 # Header + short number
140
153
  when false
141
154
  dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_LONG
142
155
  variant.long_value = 0
156
+ @estimated_pending_bytes += 2 # Header + short number
143
157
  when Integer
144
158
  dump_integer obj, variant
145
159
  when Float
146
160
  dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_DOUBLE
147
161
  variant.double_value = obj.to_f
162
+ @estimated_pending_bytes += 7 # Header + 64 bit float
148
163
  when BigDecimal
149
164
  dump_string obj.to_s, variant, config # TODO: NS: This might cut the decimal value, is that ok?
150
165
  when Complex
151
166
  dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_COMPLEX
152
167
  variant.complex_value = Com::Rookout::Variant::Complex.new real: obj.real.to_f,
153
168
  imaginary: obj.imaginary.to_f
169
+ @estimated_pending_bytes += 8 # Large header + size + (header + 64 bit float) * 2
154
170
  else
155
171
  raise Exceptions::RookClassCannotBeSerialized.new(obj.class, "Unknown Numeric Type")
156
172
  end
@@ -165,6 +181,7 @@ module Rookout
165
181
  dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_LARGE_INT
166
182
  variant.bytes_index_in_cache = get_string_index_in_cache obj.to_s
167
183
  end
184
+ @estimated_pending_bytes += 3 # Header + number
168
185
  end
169
186
 
170
187
  def dump_string obj, variant, config
@@ -178,16 +195,20 @@ module Rookout
178
195
  variant.original_size = obj.length
179
196
  dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_STRING
180
197
  variant.bytes_index_in_cache = get_string_index_in_cache final_obj
198
+ @estimated_pending_bytes += 6 # Header + number + header + number
181
199
  end
182
200
 
183
201
  def dump_time obj, variant
184
202
  dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_TIME
185
203
  variant.time_value = Google::Protobuf::Timestamp.new
186
204
  variant.time_value.from_time obj
205
+
206
+ @estimated_pending_bytes += 16 # Header + size + (header + 32 bit number + header + 64 bit number)
187
207
  end
188
208
 
189
209
  def dump_array obj, variant, current_depth, config, log_object_errors
190
210
  variant.original_size = obj.length
211
+ @estimated_pending_bytes += 3 # Header + number
191
212
 
192
213
  weighted_children_depth = current_depth + 1
193
214
  if weighted_children_depth <= config.max_collection_depth
@@ -195,6 +216,7 @@ module Rookout
195
216
  obj.each_with_index do |value, index|
196
217
  break if index >= config.max_width
197
218
  variant.collection_values << dump_raw_object(value, weighted_children_depth, config, log_object_errors)
219
+ @estimated_pending_bytes += 3 # Header + size
198
220
  end
199
221
  else
200
222
  dump_variant_type_max_depth variant, Com::Rookout::Variant::Type::VARIANT_LIST
@@ -211,6 +233,7 @@ module Rookout
211
233
  break if index >= config.max_width
212
234
  variant.collection_keys << dump_raw_object(key, weighted_children_depth, config, log_object_errors)
213
235
  variant.collection_values << dump_raw_object(value, weighted_children_depth, config, log_object_errors)
236
+ @estimated_pending_bytes += 6 # Header + size + header + size
214
237
  end
215
238
  else
216
239
  dump_variant_type_max_depth variant, Com::Rookout::Variant::Type::VARIANT_MAP
@@ -221,12 +244,15 @@ module Rookout
221
244
  dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_OBJECT
222
245
  variant.attribute_names_in_cache << get_string_index_in_cache("message")
223
246
  variant.attribute_values << dump_raw_object(obj.message, current_depth + 1, config, log_object_errors)
247
+ @estimated_pending_bytes += 6 # Header + number + header + size
224
248
 
225
249
  variant.attribute_names_in_cache << get_string_index_in_cache("cause")
226
250
  variant.attribute_values << dump_raw_object(obj.cause, current_depth + 1, config, log_object_errors)
251
+ @estimated_pending_bytes += 6 # Header + number + header + size
227
252
 
228
253
  variant.attribute_names_in_cache << get_string_index_in_cache("backtrace")
229
254
  variant.attribute_values << dump_raw_object(obj.backtrace, current_depth + 1, config, log_object_errors)
255
+ @estimated_pending_bytes += 6 # Header + number + header + size
230
256
  end
231
257
 
232
258
  def dump_code_object obj, variant
@@ -247,6 +273,9 @@ module Rookout
247
273
  variant.code_values << Com::Rookout::Variant::CodeObject.new(name: name,
248
274
  filename: source_location[0],
249
275
  lineno: source_location[1])
276
+ # NOTE: This size is probably less, in Python we use the optional fields of CodeObject and in Ruby we don't,
277
+ # but it is better to estimate more
278
+ @estimated_pending_bytes += 14 # Header + size + (header + number) * 4
250
279
  end
251
280
 
252
281
  def dump_user_class variant, obj, current_depth, config, log_object_errors
@@ -258,6 +287,7 @@ module Rookout
258
287
  raw_value = obj.instance_variable_get name
259
288
  variant.attribute_names_in_cache << get_string_index_in_cache(name.to_s)
260
289
  variant.attribute_values << dump_raw_object(raw_value, weighted_children_depth, config, log_object_errors)
290
+ @estimated_pending_bytes += 6 # Header + number + header + number
261
291
  end
262
292
  else
263
293
  dump_variant_type_max_depth variant, Com::Rookout::Variant::Type::VARIANT_OBJECT
@@ -273,6 +303,8 @@ module Rookout
273
303
  variant.attribute_values << dump(value, log_errors)
274
304
  end
275
305
 
306
+ @estimated_pending_bytes += 4 # One number (packed field), One header + length
307
+
276
308
  variant
277
309
  end
278
310
 
@@ -289,6 +321,8 @@ module Rookout
289
321
  lineno: frame.source_location[1],
290
322
  name: frame.eval("__method__").to_s
291
323
  variant.code_values << code_object
324
+ # See dump_code_object
325
+ @estimated_pending_bytes += 14 # Header + size + (header + number) * 4
292
326
  end
293
327
  variant
294
328
  end
@@ -91,23 +91,23 @@ module Rookout
91
91
  def dump log_object_errors
92
92
  dump_raw_object @obj, 0, @dump_config, log_object_errors
93
93
  end
94
- end
95
94
 
96
- private
95
+ private
97
96
 
98
- def read_key_as_int key
99
- key_int = key.to_i
100
- return RubyObjectNamespace.new @obj[key_int] if key_int >= 0 && key_int < @obj.length
101
- raise Exceptions::RookKeyNotFound, key
102
- end
97
+ def read_key_as_int key
98
+ key_int = key.to_i
99
+ return RubyObjectNamespace.new @obj[key_int] if key_int >= 0 && key_int < @obj.length
100
+ raise Exceptions::RookKeyNotFound, key
101
+ end
103
102
 
104
- def read_key_from_hash key
105
- return RubyObjectNamespace.new @obj[key] if @obj.key? key
106
- return RubyObjectNamespace.new @obj[key.to_sym] if @obj.key? key.to_s.to_sym
103
+ def read_key_from_hash key
104
+ return RubyObjectNamespace.new @obj[key] if @obj.key? key
105
+ return RubyObjectNamespace.new @obj[key.to_sym] if @obj.key? key.to_s.to_sym
107
106
 
108
- @obj.each { |it, value| return RubyObjectNamespace.new value if it.to_s == key }
107
+ @obj.each { |it, value| return RubyObjectNamespace.new value if it.to_s == key }
109
108
 
110
- raise Exceptions::RookKeyNotFound, key
109
+ raise Exceptions::RookKeyNotFound, key
110
+ end
111
111
  end
112
112
  end
113
113
  end
@@ -21,6 +21,9 @@ module Rookout
21
21
  begin
22
22
  trace_point.enable target: position.method, target_line: position.lineno
23
23
  rescue RuntimeError, ArgumentError => e
24
+ if e.message.include? "can not enable any hooks"
25
+ raise Exceptions::RookInvalidPositionException.new(aug.filename, position.lineno)
26
+ end
24
27
  raise Exceptions::RookSetTracepointFailed.new(position.lineno, e)
25
28
  end
26
29
 
data/lib/rookout/utils.rb CHANGED
@@ -1,26 +1,34 @@
1
- module Utils
2
- require "securerandom"
1
+ module Rookout
2
+ module Utils
3
+ require "securerandom"
4
+ require_relative "config"
3
5
 
4
- module_function
6
+ module_function
5
7
 
6
- def uuid
7
- SecureRandom.uuid.gsub(/-/, "")
8
- end
8
+ def uuid
9
+ SecureRandom.uuid.gsub(/-/, "")
10
+ end
9
11
 
10
- def milliseconds_to_nanoseconds milliseconds
11
- nano = milliseconds * (10**6)
12
- nano.to_i
13
- end
12
+ def milliseconds_to_nanoseconds milliseconds
13
+ nano = milliseconds * (10**6)
14
+ nano.to_i
15
+ end
14
16
 
15
- def time_to_nanoseconds time_obj
16
- secs = time_obj.to_i
17
- nsecs = time_obj.nsec
18
- ((10**9) * secs) + nsecs
19
- end
20
- end
17
+ def time_to_nanoseconds time_obj
18
+ secs = time_obj.to_i
19
+ nsecs = time_obj.nsec
20
+ ((10**9) * secs) + nsecs
21
+ end
22
+
23
+ def quiet_puts msg
24
+ # rubocop:disable Style/StderrPuts
25
+ return if Config.quiet
26
+ $stderr.puts msg
27
+ # rubocop:enable Style/StderrPuts
28
+ end
21
29
 
22
- class String
23
- def is_number?
24
- to_f.to_s == self || to_i.to_s == self
30
+ def is_number? string
31
+ true if Float(string) rescue false
32
+ end
25
33
  end
26
34
  end
@@ -1,3 +1,3 @@
1
1
  module Rookout
2
- VERSION = "0.1.40".freeze
2
+ VERSION = "0.1.50".freeze
3
3
  end
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.40
4
+ version: 0.1.50
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-09-11 00:00:00.000000000 Z
11
+ date: 2023-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: binding_of_caller
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - '='
74
74
  - !ruby/object:Gem::Version
75
- version: 3.19.2
75
+ version: 3.21.7
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: 3.19.2
82
+ version: 3.21.7
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: google-style
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -301,7 +301,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
301
301
  - !ruby/object:Gem::Version
302
302
  version: '0'
303
303
  requirements: []
304
- rubygems_version: 3.3.7
304
+ rubygems_version: 3.3.26
305
305
  signing_key:
306
306
  specification_version: 4
307
307
  summary: rookout is the Ruby SDK for the Rookout Debugging Platform