rookout 0.1.41 → 0.1.50

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 07a2d9fa41fdf140e81f22c1a46f47bbaf5412b31d1ab62c1f59460c07113c03
4
- data.tar.gz: 9dd40c49cc6b8417aa3424cedd26aad1b8e63813fe0e2fcc063749d03c20f602
3
+ metadata.gz: 72f208b3a47ef61e59b2123afe3e666a2f3efa8295ddec10950e221e5547770a
4
+ data.tar.gz: 216a478be4998de21db6b2df156123d6cde587a54369914d93ba2f3ef8f9b5a7
5
5
  SHA512:
6
- metadata.gz: 7204403b2efd52cce60b533b396c93ffc963b60554d3fbf4fbc414f4a2d6a80c0ced39e7d6c6cceda6d2470ee46563cc8704871b058957599f8b6f7ad1d433ff
7
- data.tar.gz: 2a05c92e5f984035bcbe84e5e4f2f25be8b2458032272c03fd4e94f8e94252bcaf8c11d7989c294e5a7d07773e95170bb7f479c3806945636869b2b7b491349d
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
@@ -78,7 +80,19 @@ module Rookout
78
80
 
79
81
  def global_rate_limiter
80
82
  if @global_rate_limiter.nil? && Rookout::Config.global_rate_limit != ""
81
- rate_limit = parse_rate_limit Rookout::Config.global_rate_limit, "0", 0, 0
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 = "ed682099e24a661d30178506cb58f2a25d4af877".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,9 +78,13 @@ 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
 
86
+ Rookout::Config.global_rate_limit_quota = ""
87
+ Rookout::Config.global_rate_limit_window_size = ""
82
88
  Rookout::Config.global_rate_limit = ""
83
89
  Rookout::Config.using_global_rate_limiter = false
84
90
 
@@ -103,7 +109,12 @@ 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
120
  return if global_rate_limit.nil? || 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.41".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.41
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-12 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