rookout 0.1.0 → 0.1.56

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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rookout/atfork.rb +73 -0
  3. data/lib/rookout/augs/actions/action_run_processor.rb +4 -3
  4. data/lib/rookout/augs/aug.rb +33 -91
  5. data/lib/rookout/augs/aug_factory.rb +94 -27
  6. data/lib/rookout/augs/aug_rate_limiter.rb +50 -47
  7. data/lib/rookout/augs/augs_manager.rb +3 -1
  8. data/lib/rookout/augs/conditions/condition.rb +4 -2
  9. data/lib/rookout/augs/limits_manager.rb +32 -0
  10. data/lib/rookout/augs/locations/location.rb +75 -1
  11. data/lib/rookout/augs/locations/location_exception_handler.rb +22 -0
  12. data/lib/rookout/augs/locations/location_file_line.rb +21 -5
  13. data/lib/rookout/com_ws/agent_com_ws.rb +97 -58
  14. data/lib/rookout/com_ws/backoff.rb +5 -10
  15. data/lib/rookout/com_ws/command_handler.rb +1 -1
  16. data/lib/rookout/com_ws/envelope_wrapper.rb +68 -0
  17. data/lib/rookout/com_ws/git.rb +1 -1
  18. data/lib/rookout/com_ws/information.rb +95 -4
  19. data/lib/rookout/com_ws/output.rb +69 -21
  20. data/lib/rookout/com_ws/pinger.rb +41 -0
  21. data/lib/rookout/com_ws/websocket_client.rb +173 -0
  22. data/lib/rookout/commit.rb +3 -0
  23. data/lib/rookout/config.rb +94 -18
  24. data/lib/rookout/exceptions.rb +147 -12
  25. data/lib/rookout/interface.rb +95 -32
  26. data/lib/rookout/logger.rb +39 -10
  27. data/lib/rookout/processor/namespace_serializer.rb +2 -2
  28. data/lib/rookout/processor/namespace_serializer2.rb +331 -0
  29. data/lib/rookout/processor/namespaces/container_namespace.rb +5 -0
  30. data/lib/rookout/processor/namespaces/frame_namespace.rb +20 -17
  31. data/lib/rookout/processor/namespaces/namespace.rb +3 -2
  32. data/lib/rookout/processor/namespaces/noop_namespace.rb +4 -8
  33. data/lib/rookout/processor/namespaces/ruby_object_namespace.rb +39 -22
  34. data/lib/rookout/processor/namespaces/ruby_object_serializer.rb +15 -12
  35. data/lib/rookout/processor/namespaces/ruby_utils_namespace.rb +0 -4
  36. data/lib/rookout/processor/namespaces/stack_namespace.rb +6 -4
  37. data/lib/rookout/processor/namespaces/traceback_namespace.rb +13 -9
  38. data/lib/rookout/processor/operations/set_operation.rb +6 -1
  39. data/lib/rookout/processor/paths/arithmetic_path.rb +5 -3
  40. data/lib/rookout/processor/paths/canopy/actions.rb +5 -1
  41. data/lib/rookout/processor/paths/canopy/consts.rb +6 -4
  42. data/lib/rookout/processor/paths/canopy/maps.rb +286 -286
  43. data/lib/rookout/processor/paths/canopy/markers.rb +35 -4
  44. data/lib/rookout/processor/processor_factory.rb +0 -2
  45. data/lib/rookout/processor/rook_error.rb +6 -1
  46. data/lib/rookout/protobuf/controller_info_pb.rb +1 -0
  47. data/lib/rookout/protobuf/messages_pb.rb +54 -0
  48. data/lib/rookout/protobuf/variant2_pb.rb +42 -0
  49. data/lib/rookout/protobuf/variant_pb.rb +22 -0
  50. data/lib/rookout/rookout_singleton.rb +23 -5
  51. data/lib/rookout/sanitizer.rb +22 -0
  52. data/lib/rookout/services/position.rb +92 -75
  53. data/lib/rookout/services/tracer.rb +30 -16
  54. data/lib/rookout/start.rb +12 -0
  55. data/lib/rookout/trigger_services.rb +2 -2
  56. data/lib/rookout/user_warnings.rb +2 -0
  57. data/lib/rookout/utils.rb +34 -0
  58. data/lib/rookout/version.rb +1 -2
  59. data/lib/rookout.rb +4 -0
  60. metadata +77 -51
@@ -0,0 +1,331 @@
1
+ module Rookout
2
+ module Processor
3
+ class NamespaceSerializer2
4
+ require_relative "../logger"
5
+
6
+ require_relative "../protobuf/variant_pb"
7
+ require_relative "../protobuf/variant2_pb"
8
+ require_relative "../user_warnings"
9
+ require_relative "./namespaces/container_namespace"
10
+ require_relative "./namespaces/traceback_namespace"
11
+
12
+ begin
13
+ require "hashie/mash"
14
+ MASH = ::Hashie::Mash
15
+ rescue LoadError
16
+ MASH = nil
17
+ end
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
+
26
+ def initialize
27
+ @string_cache = {}
28
+ @estimated_pending_bytes = 0
29
+ end
30
+
31
+ attr_reader :string_cache
32
+ attr_reader :estimated_pending_bytes
33
+
34
+ def get_string_index_in_cache str
35
+ if @string_cache.key? str
36
+ @string_cache[str]
37
+ else
38
+ @estimated_pending_bytes += str.length + 5
39
+ current_size = @string_cache.size
40
+ @string_cache.store str, current_size
41
+ current_size
42
+ end
43
+ end
44
+
45
+ def dump_variant_type variant, type
46
+ variant.variant_type_max_depth = type << 1
47
+ @estimated_pending_bytes += 2 # Field header + short number
48
+ end
49
+
50
+ def dump_variant_type_max_depth variant, type
51
+ variant.variant_type_max_depth = (type << 1) | 1
52
+ @estimated_pending_bytes += 2 # Field header + short number
53
+ end
54
+
55
+ def dump namespace, log_errors
56
+ case namespace
57
+ when Namespaces::RubyObjectNamespace
58
+ dump_ruby_object_namespace namespace, log_errors
59
+ when Namespaces::ContainerNamespace
60
+ dump_container_namespace namespace, log_errors
61
+ when Namespaces::TracebackNamespace
62
+ dump_traceback_namespace namespace
63
+ else
64
+ raise NotImplementedError
65
+ end
66
+ rescue StandardError => e
67
+ message = "Failed to serialize namespace"
68
+ variant = Com::Rookout::Variant2.new
69
+ @estimated_pending_bytes = 0
70
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_ERROR
71
+
72
+ if log_errors
73
+ Logger.instance.exception message, e
74
+
75
+ error = RookError.new e, message
76
+ UserWarnings.notify_warning error
77
+ end
78
+ variant
79
+ end
80
+
81
+ def dump_ruby_object_namespace namespace, log_errors
82
+ dump_raw_object namespace.obj, 0, namespace.dump_config, log_errors
83
+ end
84
+
85
+ def dump_raw_object obj, current_depth, config, log_object_errors
86
+ unsafe_dump_object obj, current_depth, config, log_object_errors
87
+ rescue StandardError => e
88
+ message = "Failed to serialize object"
89
+ variant = Com::Rookout::Variant2.new
90
+ @estimated_pending_bytes = 0
91
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_ERROR
92
+
93
+ if log_object_errors
94
+ Logger.instance.exception message, e
95
+
96
+ error = RookError.new e, message
97
+ UserWarnings.notify_warning error
98
+ end
99
+ variant
100
+ end
101
+
102
+ # rubocop:disable Metrics/AbcSize
103
+ # rubocop:disable Metrics/PerceivedComplexity
104
+ # rubocop:disable Metrics/CyclomaticComplexity
105
+ # rubocop:disable Style/ClassEqualityComparison
106
+ def unsafe_dump_object obj, current_depth, config, log_object_errors
107
+ variant = Com::Rookout::Variant2.new original_type_index_in_cache: get_string_index_in_cache(obj.class.to_s)
108
+
109
+ if obj.nil?
110
+ dump_nil variant
111
+ elsif obj.is_a?(Numeric) || obj.is_a?(TrueClass) || obj.is_a?(FalseClass)
112
+ dump_numeric obj, variant, config
113
+ elsif obj.is_a?(String) || obj.is_a?(Symbol)
114
+ dump_string obj, variant, config
115
+ elsif obj.is_a? Time
116
+ dump_time obj, variant
117
+ elsif obj.class == Array
118
+ dump_array obj, variant, current_depth, config, log_object_errors
119
+ elsif obj.class == Hash || (!MASH.nil? && obj.is_a?(MASH)) ||
120
+ (!HASH_WITH_INDIFFERENT_ACCESS.nil? && obj.is_a?(HASH_WITH_INDIFFERENT_ACCESS))
121
+ dump_hash obj, variant, current_depth, config, log_object_errors
122
+ elsif obj.is_a? Exception
123
+ dump_exception obj, variant, current_depth, config, log_object_errors
124
+ elsif obj.is_a?(Method) || obj.is_a?(Proc) || obj.is_a?(Class) || obj.is_a?(Module)
125
+ dump_code_object obj, variant
126
+ else
127
+ dump_user_class variant, obj, current_depth, config, log_object_errors
128
+ end
129
+
130
+ variant
131
+ end
132
+ # rubocop:enable Style/ClassEqualityComparison
133
+ # rubocop:enable Metrics/AbcSize
134
+ # rubocop:enable Metrics/PerceivedComplexity
135
+ # rubocop:enable Metrics/CyclomaticComplexity
136
+
137
+ def dump_nil variant
138
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_NONE
139
+ end
140
+
141
+ # Based off protobuf for Python
142
+ INT32_MIN = -2147483648
143
+ INT32_MAX = 2147483647
144
+ INT64_MIN = -(1 << 63)
145
+ INT64_MAX = (1 << 63) - 1
146
+
147
+ def dump_numeric obj, variant, config
148
+ case obj
149
+ when true
150
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_LONG
151
+ variant.long_value = 1
152
+ @estimated_pending_bytes += 2 # Header + short number
153
+ when false
154
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_LONG
155
+ variant.long_value = 0
156
+ @estimated_pending_bytes += 2 # Header + short number
157
+ when Integer
158
+ dump_integer obj, variant
159
+ when Float
160
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_DOUBLE
161
+ variant.double_value = obj.to_f
162
+ @estimated_pending_bytes += 7 # Header + 64 bit float
163
+ when BigDecimal
164
+ dump_string obj.to_s, variant, config # TODO: NS: This might cut the decimal value, is that ok?
165
+ when Complex
166
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_COMPLEX
167
+ variant.complex_value = Com::Rookout::Variant::Complex.new real: obj.real.to_f,
168
+ imaginary: obj.imaginary.to_f
169
+ @estimated_pending_bytes += 8 # Large header + size + (header + 64 bit float) * 2
170
+ else
171
+ raise Exceptions::RookClassCannotBeSerialized.new(obj.class, "Unknown Numeric Type")
172
+ end
173
+ # TODO: ADD SUPPORT FOR RATIONALS
174
+ end
175
+
176
+ def dump_integer obj, variant
177
+ if obj > INT32_MIN && obj < INT64_MAX
178
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_LONG
179
+ variant.long_value = obj
180
+ else
181
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_LARGE_INT
182
+ variant.bytes_index_in_cache = get_string_index_in_cache obj.to_s
183
+ end
184
+ @estimated_pending_bytes += 3 # Header + number
185
+ end
186
+
187
+ def dump_string obj, variant, config
188
+ obj = obj.to_s
189
+ if obj.length > config.max_string
190
+ final_obj = obj[0...config.max_string]
191
+ else
192
+ final_obj = obj
193
+ end
194
+
195
+ variant.original_size = obj.length
196
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_STRING
197
+ variant.bytes_index_in_cache = get_string_index_in_cache final_obj
198
+ @estimated_pending_bytes += 6 # Header + number + header + number
199
+ end
200
+
201
+ def dump_time obj, variant
202
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_TIME
203
+ variant.time_value = Google::Protobuf::Timestamp.new
204
+ variant.time_value.from_time obj
205
+
206
+ @estimated_pending_bytes += 16 # Header + size + (header + 32 bit number + header + 64 bit number)
207
+ end
208
+
209
+ def dump_array obj, variant, current_depth, config, log_object_errors
210
+ variant.original_size = obj.length
211
+ @estimated_pending_bytes += 3 # Header + number
212
+
213
+ weighted_children_depth = current_depth + 1
214
+ if weighted_children_depth <= config.max_collection_depth
215
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_LIST
216
+ obj.each_with_index do |value, index|
217
+ break if index >= config.max_width
218
+ variant.collection_values << dump_raw_object(value, weighted_children_depth, config, log_object_errors)
219
+ @estimated_pending_bytes += 3 # Header + size
220
+ end
221
+ else
222
+ dump_variant_type_max_depth variant, Com::Rookout::Variant::Type::VARIANT_LIST
223
+ end
224
+ end
225
+
226
+ def dump_hash obj, variant, current_depth, config, log_object_errors
227
+ variant.original_size = obj.length
228
+
229
+ weighted_children_depth = current_depth + 1
230
+ if current_depth <= config.max_collection_depth
231
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_MAP
232
+ obj.each_with_index do |(key, value), index|
233
+ break if index >= config.max_width
234
+ variant.collection_keys << dump_raw_object(key, weighted_children_depth, config, log_object_errors)
235
+ variant.collection_values << dump_raw_object(value, weighted_children_depth, config, log_object_errors)
236
+ @estimated_pending_bytes += 6 # Header + size + header + size
237
+ end
238
+ else
239
+ dump_variant_type_max_depth variant, Com::Rookout::Variant::Type::VARIANT_MAP
240
+ end
241
+ end
242
+
243
+ def dump_exception obj, variant, current_depth, config, log_object_errors
244
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_OBJECT
245
+ variant.attribute_names_in_cache << get_string_index_in_cache("message")
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
248
+
249
+ variant.attribute_names_in_cache << get_string_index_in_cache("cause")
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
252
+
253
+ variant.attribute_names_in_cache << get_string_index_in_cache("backtrace")
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
256
+ end
257
+
258
+ def dump_code_object obj, variant
259
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_CODE_OBJECT
260
+
261
+ if obj.is_a?(Proc) || obj.is_a?(Method)
262
+ source_location = obj.source_location
263
+ else
264
+ source_location = [nil, nil]
265
+ end
266
+
267
+ if obj.is_a? Proc
268
+ name = ""
269
+ else
270
+ name = obj.name
271
+ end
272
+
273
+ variant.code_values << Com::Rookout::Variant::CodeObject.new(name: name,
274
+ filename: source_location[0],
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
279
+ end
280
+
281
+ def dump_user_class variant, obj, current_depth, config, log_object_errors
282
+ weighted_children_depth = current_depth + 1
283
+ if weighted_children_depth <= config.max_collection_depth
284
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_OBJECT
285
+
286
+ obj.instance_variables.each do |name|
287
+ raw_value = obj.instance_variable_get name
288
+ variant.attribute_names_in_cache << get_string_index_in_cache(name.to_s)
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
291
+ end
292
+ else
293
+ dump_variant_type_max_depth variant, Com::Rookout::Variant::Type::VARIANT_OBJECT
294
+ end
295
+ end
296
+
297
+ def dump_container_namespace namespace, log_errors
298
+ variant = Com::Rookout::Variant2.new
299
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_NAMESPACE
300
+
301
+ namespace.hash.each do |key, value|
302
+ variant.attribute_names_in_cache << get_string_index_in_cache(key.to_s)
303
+ variant.attribute_values << dump(value, log_errors)
304
+ end
305
+
306
+ @estimated_pending_bytes += 4 # One number (packed field), One header + length
307
+
308
+ variant
309
+ end
310
+
311
+ def dump_traceback_namespace namespace
312
+ variant = Com::Rookout::Variant2.new
313
+ dump_variant_type variant, Com::Rookout::Variant::Type::VARIANT_TRACEBACK
314
+
315
+ namespace.depth.times do |i|
316
+ position = i + namespace.offset
317
+ break if position >= namespace.stack_trace.length
318
+ frame_info = namespace.stack_trace[position]
319
+
320
+ code_object = Com::Rookout::Variant::CodeObject.new filename: frame_info.path,
321
+ lineno: frame_info.lineno,
322
+ name: frame_info.label
323
+ variant.code_values << code_object
324
+ # See dump_code_object
325
+ @estimated_pending_bytes += 14 # Header + size + (header + number) * 4
326
+ end
327
+ variant
328
+ end
329
+ end
330
+ end
331
+ end
@@ -8,11 +8,16 @@ module Rookout
8
8
 
9
9
  require_relative "../../protobuf/variant_pb"
10
10
 
11
+
11
12
  class ContainerNamespace < Namespace
12
13
  def initialize hash = {}
14
+ super()
13
15
  @hash = hash
14
16
  end
15
17
 
18
+ attr_reader :hash
19
+
20
+
16
21
  def call_method name, args
17
22
  return RubyObjectNamespace.new @hash.length if name == "size"
18
23
  super
@@ -7,33 +7,35 @@ module Rookout
7
7
  require_relative "../../exceptions"
8
8
 
9
9
  class FrameNamespace < Namespace
10
- def initialize binding
11
- @binding = binding
10
+ def initialize frame_binding, top_frame_info
11
+ super()
12
+ @frame_binding = frame_binding
13
+ @top_frame_info = top_frame_info
12
14
  end
13
15
 
14
16
  def read_attribute name
15
- raise Exceptions::RookAttributeNotFound, name unless @binding.local_variable_defined? name
16
- RubyObjectNamespace.new @binding.local_variable_get name
17
+ raise Exceptions::RookLocalsUnavailable if @frame_binding.nil?
18
+ return RubyObjectNamespace.new @frame_binding.receiver if name == "self"
19
+ raise Exceptions::RookAttributeNotFound, name unless @frame_binding.local_variable_defined? name
20
+ RubyObjectNamespace.new @frame_binding.local_variable_get name
17
21
  end
18
22
 
19
23
  def call_method name, args
20
24
  case name
21
- when "filename"
22
- RubyObjectNamespace.new @binding.source_location[0]
25
+ when "filename", "module"
26
+ RubyObjectNamespace.new @top_frame_info.path
23
27
  when "line"
24
- RubyObjectNamespace.new @binding.source_location[1]
28
+ RubyObjectNamespace.new @top_frame_info.lineno
25
29
  when "function"
26
- RubyObjectNamespace.new @binding.eval("__method__").to_s
27
- when "module"
28
- RubyObjectNamespace.new @binding.source_location[0]
30
+ RubyObjectNamespace.new @top_frame_info.label
29
31
  when "locals"
30
32
  locals args
31
33
  when "dump"
32
34
  result = {
33
- "filename" => RubyObjectNamespace.new(@binding.source_location[0]),
34
- "line" => RubyObjectNamespace.new(@binding.source_location[1]),
35
- "function" => RubyObjectNamespace.new(@binding.eval("__method__").to_s),
36
- "module" => RubyObjectNamespace.new(@binding.source_location[0]),
35
+ "filename" => RubyObjectNamespace.new(@top_frame_info.path),
36
+ "line" => RubyObjectNamespace.new(@top_frame_info.lineno),
37
+ "function" => RubyObjectNamespace.new(@top_frame_info.label),
38
+ "module" => RubyObjectNamespace.new(@top_frame_info.path),
37
39
  "locals" => locals(args)
38
40
  }
39
41
  ContainerNamespace.new result
@@ -43,19 +45,20 @@ module Rookout
43
45
  end
44
46
 
45
47
  def locals args
48
+ raise Exceptions::RookLocalsUnavailable if @frame_binding.nil?
46
49
  dump_config = nil
47
50
  unless args.nil?
48
51
  dump_config = OBJECT_DUMP_TABLE[args.downcase]
49
52
  end
50
53
 
51
54
  hash = {}
52
- local_variables = @binding.local_variables
55
+ local_variables = @frame_binding.local_variables
53
56
  local_variables.each do |var|
54
- value = @binding.local_variable_get var
57
+ value = @frame_binding.local_variable_get var
55
58
  hash[var.to_s] = RubyObjectNamespace.new value, dump_config
56
59
  end
57
60
 
58
- hash["self"] = RubyObjectNamespace.new @binding.receiver, dump_config
61
+ hash["self"] = RubyObjectNamespace.new @frame_binding.receiver, dump_config
59
62
 
60
63
  ContainerNamespace.new hash
61
64
  end
@@ -3,8 +3,9 @@ module Rookout
3
3
  module Namespaces
4
4
  class Namespace
5
5
  require_relative "../../exceptions"
6
+
6
7
  def call_method name, _args
7
- raise Exceptions::RookMethodNotFound, self.class.to_s, name
8
+ raise Exceptions::RookMethodNotFound.new(self.class.to_s, name)
8
9
  end
9
10
 
10
11
  def read_attribute name
@@ -12,7 +13,7 @@ module Rookout
12
13
  end
13
14
 
14
15
  def write_attribute name, _value
15
- raise Exceptions::RookWriteAttributeNotSupported, self.class.to_s, name
16
+ raise Exceptions::RookWriteAttributeNotSupported.new(self.class.to_s, name)
16
17
  end
17
18
 
18
19
  def read_key key
@@ -6,21 +6,17 @@ module Rookout
6
6
 
7
7
  require_relative "../../protobuf/variant_pb"
8
8
 
9
- class RubyUtilsNamespace < Namespace
10
- def initialize
11
- super
12
- end
13
-
9
+ class NoopNamespace < Namespace
14
10
  def call_method _name, _args
15
- RubyObjectNamespace nil
11
+ Rookout::Processor::Namespaces::RubyObjectNamespace.new nil
16
12
  end
17
13
 
18
14
  def read_attribute _name
19
- RubyObjectNamespace nil
15
+ Rookout::Processor::Namespaces::RubyObjectNamespace.new nil
20
16
  end
21
17
 
22
18
  def read_key _key
23
- RubyObjectNamespace nil
19
+ Rookout::Processor::Namespaces::RubyObjectNamespace.new nil
24
20
  end
25
21
 
26
22
  def dump _log_object_errors
@@ -17,15 +17,18 @@ module Rookout
17
17
  @max_string = max_string
18
18
  end
19
19
 
20
- attr_reader :max_depth, :max_width, :max_collection_depth, :max_string
20
+ attr_reader :max_depth
21
+ attr_reader :max_width
22
+ attr_reader :max_collection_depth
23
+ attr_reader :max_string
21
24
  end
22
25
 
23
- OBJECT_DUMP_CONFIG_STRICT = ObjectDumpConfig.new 2, 10, 1, 128
24
- OBJECT_DUMP_CONFIG_DEFAULT = ObjectDumpConfig.new 4, 20, 2, 512
25
- OBJECT_DUMP_CONFIG_TOLERANT = ObjectDumpConfig.new 5, 50, 4, 4 * 1024
26
+ OBJECT_DUMP_CONFIG_STRICT = ObjectDumpConfig.new 2, 10, 2, 128
27
+ OBJECT_DUMP_CONFIG_DEFAULT = ObjectDumpConfig.new 4, 15, 4, 512
28
+ OBJECT_DUMP_CONFIG_TOLERANT = ObjectDumpConfig.new 5, 20, 5, 4 * 1024
26
29
 
27
30
  OBJECT_DUMP_CONFIG_STRING = ObjectDumpConfig.new 1, 0, 0, 64 * 1024
28
- OBJECT_DUMP_CONFIG_COLLECTION = ObjectDumpConfig.new 4, 100, 2, 512
31
+ OBJECT_DUMP_CONFIG_COLLECTION = ObjectDumpConfig.new 4, 100, 4, 512
29
32
 
30
33
  OBJECT_DUMP_TABLE = {
31
34
  "" => OBJECT_DUMP_CONFIG_DEFAULT,
@@ -37,18 +40,22 @@ module Rookout
37
40
  class RubyObjectNamespace < Namespace
38
41
  include RubyObjectSerializer
39
42
 
40
- def initialize obj, dump_config = OBJECT_DUMP_CONFIG_DEFAULT
43
+ def initialize obj, dump_config = nil
44
+ super()
41
45
  @obj = obj
42
- @dump_config = dump_config
46
+ @dump_config = dump_config || OBJECT_DUMP_CONFIG_DEFAULT
43
47
  end
44
48
 
45
- attr_reader :obj, :dump_config
49
+ attr_reader :obj
50
+ attr_reader :dump_config
46
51
 
47
52
  def tailor_limits!
48
53
  if @obj.is_a? String
49
54
  @dump_config = OBJECT_DUMP_CONFIG_STRING
50
- elsif @obj.is_a?(Hash) || @obj.is_a?(Array)
55
+ elsif (@obj.is_a?(Hash) || @obj.is_a?(Array)) && @obj.length > OBJECT_DUMP_CONFIG_TOLERANT.max_width
51
56
  @dump_config = OBJECT_DUMP_CONFIG_COLLECTION
57
+ else
58
+ @dump_config = OBJECT_DUMP_CONFIG_TOLERANT
52
59
  end
53
60
  self
54
61
  end
@@ -60,20 +67,13 @@ module Rookout
60
67
  end
61
68
 
62
69
  def read_key key
63
- if @obj.is_a? Array
64
- key_int = key.to_i
65
- return RubyObjectNamespace.new @obj[key_int] if key_int >= 0 && key_int < @obj.length
66
- raise Exceptions::RookKeyNotFound, key
67
-
68
- elsif @obj.is_a? Hash
69
- return RubyObjectNamespace.new @obj[key] if @obj.key? key
70
- return RubyObjectNamespace.new @obj[key.to_sym] if key.is_a?(String) && @obj.key?(key.to_sym)
71
-
72
- @obj.each { |it, value| return RubyObjectNamespace.new value if it.to_s == key }
73
-
74
- raise Exceptions::RookKeyNotFound, key
70
+ case @obj
71
+ when Array, String
72
+ read_key_as_int key
73
+ when Hash
74
+ read_key_from_hash key
75
75
  else
76
- raise Exceptions::RookInvalidObjectForAccess.new(obj.class.to_s, "ReadKey")
76
+ raise Exceptions::RookInvalidObjectForAccess.new(@obj.class.to_s, "ReadKey")
77
77
  end
78
78
  end
79
79
 
@@ -91,6 +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
+
95
+ private
96
+
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
102
+
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
106
+
107
+ @obj.each { |it, value| return RubyObjectNamespace.new value if it.to_s == key }
108
+
109
+ raise Exceptions::RookKeyNotFound, key
110
+ end
94
111
  end
95
112
  end
96
113
  end
@@ -17,27 +17,28 @@ module Rookout
17
17
  Logger.instance.exception message, e
18
18
 
19
19
  error = RookError.new e, message
20
- variant = error.dumps
20
+ variant.error_value = error.dumps
21
21
  end
22
22
  variant
23
23
  end
24
24
 
25
25
  # rubocop:disable Metrics/PerceivedComplexity
26
26
  # rubocop:disable Metrics/CyclomaticComplexity
27
+ # rubocop:disable Style/ClassEqualityComparison
27
28
  def unsafe_dump_object obj, current_depth, config, log_object_errors
28
29
  variant = create_base_variant obj, current_depth, config, log_object_errors
29
30
 
30
31
  if obj.nil?
31
32
  dump_nil variant
32
- elsif obj.is_a?(Numeric) || obj == true || obj == false
33
+ elsif obj.is_a?(Numeric) || obj.is_a?(TrueClass) || obj.is_a?(FalseClass)
33
34
  dump_numeric obj, variant
34
35
  elsif obj.is_a?(String) || obj.is_a?(Symbol)
35
36
  dump_string obj, variant, config
36
37
  elsif obj.is_a? Time
37
38
  dump_time obj, variant
38
- elsif obj.is_a? Array
39
+ elsif obj.class == Array
39
40
  dump_array obj, variant, current_depth, config, log_object_errors
40
- elsif obj.is_a? Hash
41
+ elsif obj.class == Hash
41
42
  dump_hash obj, variant, current_depth, config, log_object_errors
42
43
  elsif obj.is_a? Exception
43
44
  dump_exception obj, variant, current_depth, config, log_object_errors
@@ -49,7 +50,7 @@ module Rookout
49
50
 
50
51
  variant
51
52
  end
52
-
53
+ # rubocop:enable Style/ClassEqualityComparison
53
54
  # rubocop:enable Metrics/CyclomaticComplexity
54
55
  # rubocop:enable Metrics/PerceivedComplexity
55
56
 
@@ -83,28 +84,29 @@ module Rookout
83
84
  INT64_MAX = (1 << 63) - 1
84
85
 
85
86
  def dump_numeric obj, variant
86
- if obj == true
87
+ case obj
88
+ when true
87
89
  variant.variant_type = :VARIANT_INT
88
90
  variant.int_value = 1
89
- elsif obj == false
91
+ when false
90
92
  variant.variant_type = :VARIANT_INT
91
93
  variant.int_value = 0
92
- elsif obj.is_a? Integer
94
+ when Integer
93
95
  dump_integer obj, variant
94
- elsif obj.is_a? Float
96
+ when Float
95
97
  variant.variant_type = :VARIANT_DOUBLE
96
98
  variant.double_value = obj.to_f
97
- elsif obj.is_a? BigDecimal
99
+ when BigDecimal
98
100
  serialized_decimal = obj.to_s
99
101
  variant.variant_type = :VARIANT_STRING
100
102
  variant.string_value = Com::Rookout::Variant::String.new value: serialized_decimal,
101
103
  original_size: serialized_decimal.length
102
- elsif obj.is_a? Complex
104
+ when Complex
103
105
  variant.variant_type = :VARIANT_COMPLEX
104
106
  variant.complex_value = Com::Rookout::Variant::Complex.new real: obj.real.to_f,
105
107
  imaginary: obj.imaginary.to_f
106
108
  else
107
- raise Exceptions.RookClassCannotBeSerialized, obj.class, "Unknown Numeric Type"
109
+ raise Exceptions::RookClassCannotBeSerialized.new(obj.class, "Unknown Numeric Type")
108
110
  end
109
111
  # TODO: ADD SUPPORT FOR RATIONALS
110
112
  end
@@ -123,6 +125,7 @@ module Rookout
123
125
  end
124
126
 
125
127
  def dump_string obj, variant, config
128
+ obj = obj.to_s
126
129
  if obj.length > config.max_string
127
130
  final_obj = obj[0...config.max_string]
128
131
  else
@@ -9,10 +9,6 @@ module Rookout
9
9
  require_relative "ruby_object_namespace"
10
10
 
11
11
  class RubyUtilsNamespace < Namespace
12
- def initialize
13
- super
14
- end
15
-
16
12
  def call_method name, args
17
13
  case name
18
14
  when "exception"