rookout 0.1.0 → 0.1.56

Sign up to get free protection for your applications and to get access to all the features.
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"