Module: Rookout::Processor::Namespaces::RubyObjectSerializer

Included in:
RubyObjectNamespace
Defined in:
lib/rookout/processor/namespaces/ruby_object_serializer.rb

Constant Summary collapse

INT32_MIN =

Based off protobuf for Python

-2147483648
INT32_MAX =
2147483647
INT64_MIN =
-(1 << 63)
INT64_MAX =
(1 << 63) - 1

Instance Method Summary collapse

Instance Method Details

#create_base_variant(obj, current_depth, config, log_object_errors) ⇒ Object

rubocop:enable Style/ClassEqualityComparison rubocop:enable Metrics/CyclomaticComplexity rubocop:enable Metrics/PerceivedComplexity



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/rookout/processor/namespaces/ruby_object_serializer.rb', line 57

def create_base_variant obj, current_depth, config, log_object_errors
  variant = Com::Rookout::Variant.new original_type: obj.class.to_s

  object_weight = obj.instance_variables.length > config.max_width ? 2 : 1
  next_depth = current_depth + object_weight
  if next_depth >= config.max_depth
    variant.max_depth = true
    return variant
  end

  obj.instance_variables.each do |name|
    raw_value = obj.instance_variable_get name
    variant_value = dump_raw_object raw_value, current_depth + 1, config, log_object_errors
    variant.attributes << Com::Rookout::Variant::NamedValue.new(name: name, value: variant_value)
  end

  variant
end

#dump_array(obj, variant, current_depth, config, log_object_errors) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
# File 'lib/rookout/processor/namespaces/ruby_object_serializer.rb', line 145

def dump_array obj, variant, current_depth, config, log_object_errors
  variant.variant_type = :VARIANT_LIST
  variant.list_value = Com::Rookout::Variant::List.new type: "array", original_size: obj.length

  return unless current_depth < config.max_collection_depth

  obj.each_with_index do |value, index|
    break if index >= config.max_width
    variant.list_value.values << dump_raw_object(value, current_depth + 1, config, log_object_errors)
  end
end

#dump_code_object(obj, variant) ⇒ Object



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/rookout/processor/namespaces/ruby_object_serializer.rb', line 185

def dump_code_object obj, variant
  variant.variant_type = :VARIANT_CODE_OBJECT

  if obj.is_a?(Proc) || obj.is_a?(Method)
    source_location = obj.source_location
  else
    source_location = [nil, nil]
  end

  if obj.is_a? Proc
    name = ""
  else
    name = obj.name
  end

  variant.code_value = Com::Rookout::Variant::CodeObject.new name: name,
                                                             filename: source_location[0],
                                                             lineno: source_location[1]
end

#dump_exception(obj, variant, current_depth, config, log_object_errors) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/rookout/processor/namespaces/ruby_object_serializer.rb', line 172

def dump_exception obj, variant, current_depth, config, log_object_errors
  variant.variant_type = :VARIANT_OBJECT

  message = dump_raw_object obj.message, current_depth + 1, config, log_object_errors
  variant.attributes << Com::Rookout::Variant::NamedValue.new(name: "message", value: message)

  cause = dump_raw_object obj.cause, current_depth + 1, config, log_object_errors
  variant.attributes << Com::Rookout::Variant::NamedValue.new(name: "cause", value: cause)

  backtrace = dump_raw_object obj.backtrace, current_depth + 1, config, log_object_errors
  variant.attributes << Com::Rookout::Variant::NamedValue.new(name: "backtrace", value: backtrace)
end

#dump_hash(obj, variant, current_depth, config, log_object_errors) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/rookout/processor/namespaces/ruby_object_serializer.rb', line 157

def dump_hash obj, variant, current_depth, config, log_object_errors
  variant.variant_type = :VARIANT_MAP
  variant.map_value = Com::Rookout::Variant::Map.new original_size: obj.length

  return unless current_depth < config.max_collection_depth

  obj.each_with_index do |(key, value), index|
    break if index >= config.max_width
    key_variant = dump_raw_object key, current_depth + 1, config, log_object_errors
    value_variant = dump_raw_object value, current_depth + 1, config, log_object_errors
    pair = Com::Rookout::Variant::Pair.new first: key_variant, second: value_variant
    variant.map_value.pairs << pair
  end
end

#dump_integer(obj, variant) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/rookout/processor/namespaces/ruby_object_serializer.rb', line 114

def dump_integer obj, variant
  if obj > INT32_MIN && obj < INT32_MAX
    variant.variant_type = :VARIANT_INT
    variant.int_value = obj
  elsif obj > INT64_MIN && obj < INT64_MAX
    variant.variant_type = :VARIANT_LONG
    variant.long_value = obj
  else
    variant.variant_type = :VARIANT_LARGE_INT
    variant.large_int_value = Com::Rookout::Variant::LargeInt.new value: obj.to_s
  end
end

#dump_nil(variant) ⇒ Object



76
77
78
# File 'lib/rookout/processor/namespaces/ruby_object_serializer.rb', line 76

def dump_nil variant
  variant.variant_type = :VARIANT_NONE
end

#dump_numeric(obj, variant) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/rookout/processor/namespaces/ruby_object_serializer.rb', line 86

def dump_numeric obj, variant
  case obj
  when true
    variant.variant_type = :VARIANT_INT
    variant.int_value = 1
  when false
    variant.variant_type = :VARIANT_INT
    variant.int_value = 0
  when Integer
    dump_integer obj, variant
  when Float
    variant.variant_type = :VARIANT_DOUBLE
    variant.double_value = obj.to_f
  when BigDecimal
    serialized_decimal = obj.to_s
    variant.variant_type = :VARIANT_STRING
    variant.string_value = Com::Rookout::Variant::String.new value: serialized_decimal,
                                                             original_size: serialized_decimal.length
  when Complex
    variant.variant_type = :VARIANT_COMPLEX
    variant.complex_value = Com::Rookout::Variant::Complex.new real: obj.real.to_f,
                                                               imaginary: obj.imaginary.to_f
  else
    raise Exceptions::RookClassCannotBeSerialized.new(obj.class, "Unknown Numeric Type")
  end
  # TODO: ADD SUPPORT FOR RATIONALS
end

#dump_raw_object(obj, current_depth, config, log_object_errors) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/rookout/processor/namespaces/ruby_object_serializer.rb', line 10

def dump_raw_object obj, current_depth, config, log_object_errors
  unsafe_dump_object obj, current_depth, config, log_object_errors
rescue StandardError => e
  message = "Failed to serialize object"
  variant = Com::Rookout::Variant.new variant_type: :VARIANT_ERROR

  if log_object_errors
    Logger.instance.exception message, e

    error = RookError.new e, message
    variant.error_value = error.dumps
  end
  variant
end

#dump_string(obj, variant, config) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
# File 'lib/rookout/processor/namespaces/ruby_object_serializer.rb', line 127

def dump_string obj, variant, config
  obj = obj.to_s
  if obj.length > config.max_string
    final_obj = obj[0...config.max_string]
  else
    final_obj = obj
  end

  variant.variant_type = :VARIANT_STRING
  variant.string_value = Com::Rookout::Variant::String.new value: final_obj, original_size: obj.length
end

#dump_time(obj, variant) ⇒ Object



139
140
141
142
143
# File 'lib/rookout/processor/namespaces/ruby_object_serializer.rb', line 139

def dump_time obj, variant
  variant.variant_type = :VARIANT_TIME
  variant.time_value = Google::Protobuf::Timestamp.new
  variant.time_value.from_time obj
end

#dump_user_class(variant) ⇒ Object



205
206
207
# File 'lib/rookout/processor/namespaces/ruby_object_serializer.rb', line 205

def dump_user_class variant
  variant.variant_type = :VARIANT_OBJECT
end

#unsafe_dump_object(obj, current_depth, config, log_object_errors) ⇒ Object

rubocop:disable Metrics/PerceivedComplexity rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Style/ClassEqualityComparison



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rookout/processor/namespaces/ruby_object_serializer.rb', line 28

def unsafe_dump_object obj, current_depth, config, log_object_errors
  variant = create_base_variant obj, current_depth, config, log_object_errors

  if obj.nil?
    dump_nil variant
  elsif obj.is_a?(Numeric) || obj.is_a?(TrueClass) || obj.is_a?(FalseClass)
    dump_numeric obj, variant
  elsif obj.is_a?(String) || obj.is_a?(Symbol)
    dump_string obj, variant, config
  elsif obj.is_a? Time
    dump_time obj, variant
  elsif obj.class == Array
    dump_array obj, variant, current_depth, config, log_object_errors
  elsif obj.class == Hash
    dump_hash obj, variant, current_depth, config, log_object_errors
  elsif obj.is_a? Exception
    dump_exception obj, variant, current_depth, config, log_object_errors
  elsif obj.is_a?(Method) || obj.is_a?(Proc) || obj.is_a?(Class) || obj.is_a?(Module)
    dump_code_object obj, variant
  else
    dump_user_class variant
  end

  variant
end