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.
- checksums.yaml +4 -4
- data/lib/rookout/atfork.rb +73 -0
- data/lib/rookout/augs/actions/action_run_processor.rb +4 -3
- data/lib/rookout/augs/aug.rb +33 -91
- data/lib/rookout/augs/aug_factory.rb +94 -27
- data/lib/rookout/augs/aug_rate_limiter.rb +50 -47
- data/lib/rookout/augs/augs_manager.rb +3 -1
- data/lib/rookout/augs/conditions/condition.rb +4 -2
- data/lib/rookout/augs/limits_manager.rb +32 -0
- data/lib/rookout/augs/locations/location.rb +75 -1
- data/lib/rookout/augs/locations/location_exception_handler.rb +22 -0
- data/lib/rookout/augs/locations/location_file_line.rb +21 -5
- data/lib/rookout/com_ws/agent_com_ws.rb +97 -58
- data/lib/rookout/com_ws/backoff.rb +5 -10
- data/lib/rookout/com_ws/command_handler.rb +1 -1
- data/lib/rookout/com_ws/envelope_wrapper.rb +68 -0
- data/lib/rookout/com_ws/git.rb +1 -1
- data/lib/rookout/com_ws/information.rb +95 -4
- data/lib/rookout/com_ws/output.rb +69 -21
- data/lib/rookout/com_ws/pinger.rb +41 -0
- data/lib/rookout/com_ws/websocket_client.rb +173 -0
- data/lib/rookout/commit.rb +3 -0
- data/lib/rookout/config.rb +94 -18
- data/lib/rookout/exceptions.rb +147 -12
- data/lib/rookout/interface.rb +95 -32
- data/lib/rookout/logger.rb +39 -10
- data/lib/rookout/processor/namespace_serializer.rb +2 -2
- data/lib/rookout/processor/namespace_serializer2.rb +331 -0
- data/lib/rookout/processor/namespaces/container_namespace.rb +5 -0
- data/lib/rookout/processor/namespaces/frame_namespace.rb +20 -17
- data/lib/rookout/processor/namespaces/namespace.rb +3 -2
- data/lib/rookout/processor/namespaces/noop_namespace.rb +4 -8
- data/lib/rookout/processor/namespaces/ruby_object_namespace.rb +39 -22
- data/lib/rookout/processor/namespaces/ruby_object_serializer.rb +15 -12
- data/lib/rookout/processor/namespaces/ruby_utils_namespace.rb +0 -4
- data/lib/rookout/processor/namespaces/stack_namespace.rb +6 -4
- data/lib/rookout/processor/namespaces/traceback_namespace.rb +13 -9
- data/lib/rookout/processor/operations/set_operation.rb +6 -1
- data/lib/rookout/processor/paths/arithmetic_path.rb +5 -3
- data/lib/rookout/processor/paths/canopy/actions.rb +5 -1
- data/lib/rookout/processor/paths/canopy/consts.rb +6 -4
- data/lib/rookout/processor/paths/canopy/maps.rb +286 -286
- data/lib/rookout/processor/paths/canopy/markers.rb +35 -4
- data/lib/rookout/processor/processor_factory.rb +0 -2
- data/lib/rookout/processor/rook_error.rb +6 -1
- data/lib/rookout/protobuf/controller_info_pb.rb +1 -0
- data/lib/rookout/protobuf/messages_pb.rb +54 -0
- data/lib/rookout/protobuf/variant2_pb.rb +42 -0
- data/lib/rookout/protobuf/variant_pb.rb +22 -0
- data/lib/rookout/rookout_singleton.rb +23 -5
- data/lib/rookout/sanitizer.rb +22 -0
- data/lib/rookout/services/position.rb +92 -75
- data/lib/rookout/services/tracer.rb +30 -16
- data/lib/rookout/start.rb +12 -0
- data/lib/rookout/trigger_services.rb +2 -2
- data/lib/rookout/user_warnings.rb +2 -0
- data/lib/rookout/utils.rb +34 -0
- data/lib/rookout/version.rb +1 -2
- data/lib/rookout.rb +4 -0
- 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
|
11
|
-
|
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::
|
16
|
-
RubyObjectNamespace.new @
|
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 @
|
25
|
+
when "filename", "module"
|
26
|
+
RubyObjectNamespace.new @top_frame_info.path
|
23
27
|
when "line"
|
24
|
-
RubyObjectNamespace.new @
|
28
|
+
RubyObjectNamespace.new @top_frame_info.lineno
|
25
29
|
when "function"
|
26
|
-
RubyObjectNamespace.new @
|
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(@
|
34
|
-
"line" => RubyObjectNamespace.new(@
|
35
|
-
"function" => RubyObjectNamespace.new(@
|
36
|
-
"module" => RubyObjectNamespace.new(@
|
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 = @
|
55
|
+
local_variables = @frame_binding.local_variables
|
53
56
|
local_variables.each do |var|
|
54
|
-
value = @
|
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 @
|
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
|
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
|
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
|
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
|
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,
|
24
|
-
OBJECT_DUMP_CONFIG_DEFAULT = ObjectDumpConfig.new 4,
|
25
|
-
OBJECT_DUMP_CONFIG_TOLERANT = ObjectDumpConfig.new 5,
|
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,
|
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 =
|
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
|
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
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
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
|
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.
|
39
|
+
elsif obj.class == Array
|
39
40
|
dump_array obj, variant, current_depth, config, log_object_errors
|
40
|
-
elsif obj.
|
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
|
-
|
87
|
+
case obj
|
88
|
+
when true
|
87
89
|
variant.variant_type = :VARIANT_INT
|
88
90
|
variant.int_value = 1
|
89
|
-
|
91
|
+
when false
|
90
92
|
variant.variant_type = :VARIANT_INT
|
91
93
|
variant.int_value = 0
|
92
|
-
|
94
|
+
when Integer
|
93
95
|
dump_integer obj, variant
|
94
|
-
|
96
|
+
when Float
|
95
97
|
variant.variant_type = :VARIANT_DOUBLE
|
96
98
|
variant.double_value = obj.to_f
|
97
|
-
|
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
|
-
|
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.
|
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
|