rookout 0.1.0

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 (58) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +12 -0
  3. data/bin/rookout +30 -0
  4. data/lib/rookout.rb +18 -0
  5. data/lib/rookout/augs/actions/action.rb +11 -0
  6. data/lib/rookout/augs/actions/action_run_processor.rb +29 -0
  7. data/lib/rookout/augs/aug.rb +121 -0
  8. data/lib/rookout/augs/aug_factory.rb +69 -0
  9. data/lib/rookout/augs/aug_rate_limiter.rb +96 -0
  10. data/lib/rookout/augs/augs_manager.rb +77 -0
  11. data/lib/rookout/augs/conditions/condition.rb +15 -0
  12. data/lib/rookout/augs/locations/location.rb +11 -0
  13. data/lib/rookout/augs/locations/location_file_line.rb +26 -0
  14. data/lib/rookout/com_ws/agent_com_ws.rb +221 -0
  15. data/lib/rookout/com_ws/backoff.rb +35 -0
  16. data/lib/rookout/com_ws/command_handler.rb +22 -0
  17. data/lib/rookout/com_ws/git.rb +53 -0
  18. data/lib/rookout/com_ws/information.rb +85 -0
  19. data/lib/rookout/com_ws/output.rb +135 -0
  20. data/lib/rookout/com_ws/token_bucket.rb +36 -0
  21. data/lib/rookout/config.rb +55 -0
  22. data/lib/rookout/exceptions.rb +140 -0
  23. data/lib/rookout/interface.rb +140 -0
  24. data/lib/rookout/logger.rb +158 -0
  25. data/lib/rookout/processor/namespace_serializer.rb +26 -0
  26. data/lib/rookout/processor/namespaces/container_namespace.rb +45 -0
  27. data/lib/rookout/processor/namespaces/frame_namespace.rb +65 -0
  28. data/lib/rookout/processor/namespaces/namespace.rb +28 -0
  29. data/lib/rookout/processor/namespaces/noop_namespace.rb +32 -0
  30. data/lib/rookout/processor/namespaces/ruby_object_namespace.rb +97 -0
  31. data/lib/rookout/processor/namespaces/ruby_object_serializer.rb +208 -0
  32. data/lib/rookout/processor/namespaces/ruby_utils_namespace.rb +65 -0
  33. data/lib/rookout/processor/namespaces/stack_namespace.rb +30 -0
  34. data/lib/rookout/processor/namespaces/traceback_namespace.rb +40 -0
  35. data/lib/rookout/processor/operations/operation.rb +11 -0
  36. data/lib/rookout/processor/operations/set_operation.rb +48 -0
  37. data/lib/rookout/processor/paths/arithmetic_path.rb +84 -0
  38. data/lib/rookout/processor/paths/canopy/actions.rb +184 -0
  39. data/lib/rookout/processor/paths/canopy/consts.rb +82 -0
  40. data/lib/rookout/processor/paths/canopy/maps.rb +2837 -0
  41. data/lib/rookout/processor/paths/canopy/markers.rb +186 -0
  42. data/lib/rookout/processor/paths/path.rb +15 -0
  43. data/lib/rookout/processor/processor.rb +34 -0
  44. data/lib/rookout/processor/processor_factory.rb +23 -0
  45. data/lib/rookout/processor/rook_error.rb +45 -0
  46. data/lib/rookout/protobuf/.gitignore +0 -0
  47. data/lib/rookout/protobuf/agent_info_pb.rb +68 -0
  48. data/lib/rookout/protobuf/controller_info_pb.rb +29 -0
  49. data/lib/rookout/protobuf/envelope_pb.rb +21 -0
  50. data/lib/rookout/protobuf/messages_pb.rb +189 -0
  51. data/lib/rookout/protobuf/variant_pb.rb +139 -0
  52. data/lib/rookout/rookout_singleton.rb +73 -0
  53. data/lib/rookout/services/position.rb +163 -0
  54. data/lib/rookout/services/tracer.rb +83 -0
  55. data/lib/rookout/trigger_services.rb +34 -0
  56. data/lib/rookout/user_warnings.rb +25 -0
  57. data/lib/rookout/version.rb +4 -0
  58. metadata +269 -0
@@ -0,0 +1,208 @@
1
+ module Rookout
2
+ module Processor
3
+ module Namespaces
4
+ module RubyObjectSerializer
5
+ require_relative "../../logger"
6
+ require_relative "../rook_error"
7
+
8
+ require_relative "../../protobuf/variant_pb"
9
+
10
+ def dump_raw_object obj, current_depth, config, log_object_errors
11
+ unsafe_dump_object obj, current_depth, config, log_object_errors
12
+ rescue StandardError => e
13
+ message = "Failed to serialize object"
14
+ variant = Com::Rookout::Variant.new variant_type: :VARIANT_ERROR
15
+
16
+ if log_object_errors
17
+ Logger.instance.exception message, e
18
+
19
+ error = RookError.new e, message
20
+ variant = error.dumps
21
+ end
22
+ variant
23
+ end
24
+
25
+ # rubocop:disable Metrics/PerceivedComplexity
26
+ # rubocop:disable Metrics/CyclomaticComplexity
27
+ def unsafe_dump_object obj, current_depth, config, log_object_errors
28
+ variant = create_base_variant obj, current_depth, config, log_object_errors
29
+
30
+ if obj.nil?
31
+ dump_nil variant
32
+ elsif obj.is_a?(Numeric) || obj == true || obj == false
33
+ dump_numeric obj, variant
34
+ elsif obj.is_a?(String) || obj.is_a?(Symbol)
35
+ dump_string obj, variant, config
36
+ elsif obj.is_a? Time
37
+ dump_time obj, variant
38
+ elsif obj.is_a? Array
39
+ dump_array obj, variant, current_depth, config, log_object_errors
40
+ elsif obj.is_a? Hash
41
+ dump_hash obj, variant, current_depth, config, log_object_errors
42
+ elsif obj.is_a? Exception
43
+ dump_exception obj, variant, current_depth, config, log_object_errors
44
+ elsif obj.is_a?(Method) || obj.is_a?(Proc) || obj.is_a?(Class) || obj.is_a?(Module)
45
+ dump_code_object obj, variant
46
+ else
47
+ dump_user_class variant
48
+ end
49
+
50
+ variant
51
+ end
52
+
53
+ # rubocop:enable Metrics/CyclomaticComplexity
54
+ # rubocop:enable Metrics/PerceivedComplexity
55
+
56
+ def create_base_variant obj, current_depth, config, log_object_errors
57
+ variant = Com::Rookout::Variant.new original_type: obj.class.to_s
58
+
59
+ object_weight = obj.instance_variables.length > config.max_width ? 2 : 1
60
+ next_depth = current_depth + object_weight
61
+ if next_depth >= config.max_depth
62
+ variant.max_depth = true
63
+ return variant
64
+ end
65
+
66
+ obj.instance_variables.each do |name|
67
+ raw_value = obj.instance_variable_get name
68
+ variant_value = dump_raw_object raw_value, current_depth + 1, config, log_object_errors
69
+ variant.attributes << Com::Rookout::Variant::NamedValue.new(name: name, value: variant_value)
70
+ end
71
+
72
+ variant
73
+ end
74
+
75
+ def dump_nil variant
76
+ variant.variant_type = :VARIANT_NONE
77
+ end
78
+
79
+ # Based off protobuf for Python
80
+ INT32_MIN = -2147483648
81
+ INT32_MAX = 2147483647
82
+ INT64_MIN = -(1 << 63)
83
+ INT64_MAX = (1 << 63) - 1
84
+
85
+ def dump_numeric obj, variant
86
+ if obj == true
87
+ variant.variant_type = :VARIANT_INT
88
+ variant.int_value = 1
89
+ elsif obj == false
90
+ variant.variant_type = :VARIANT_INT
91
+ variant.int_value = 0
92
+ elsif obj.is_a? Integer
93
+ dump_integer obj, variant
94
+ elsif obj.is_a? Float
95
+ variant.variant_type = :VARIANT_DOUBLE
96
+ variant.double_value = obj.to_f
97
+ elsif obj.is_a? BigDecimal
98
+ serialized_decimal = obj.to_s
99
+ variant.variant_type = :VARIANT_STRING
100
+ variant.string_value = Com::Rookout::Variant::String.new value: serialized_decimal,
101
+ original_size: serialized_decimal.length
102
+ elsif obj.is_a? Complex
103
+ variant.variant_type = :VARIANT_COMPLEX
104
+ variant.complex_value = Com::Rookout::Variant::Complex.new real: obj.real.to_f,
105
+ imaginary: obj.imaginary.to_f
106
+ else
107
+ raise Exceptions.RookClassCannotBeSerialized, obj.class, "Unknown Numeric Type"
108
+ end
109
+ # TODO: ADD SUPPORT FOR RATIONALS
110
+ end
111
+
112
+ def dump_integer obj, variant
113
+ if obj > INT32_MIN && obj < INT32_MAX
114
+ variant.variant_type = :VARIANT_INT
115
+ variant.int_value = obj
116
+ elsif obj > INT64_MIN && obj < INT64_MAX
117
+ variant.variant_type = :VARIANT_LONG
118
+ variant.long_value = obj
119
+ else
120
+ variant.variant_type = :VARIANT_LARGE_INT
121
+ variant.large_int_value = Com::Rookout::Variant::LargeInt.new value: obj.to_s
122
+ end
123
+ end
124
+
125
+ def dump_string obj, variant, config
126
+ if obj.length > config.max_string
127
+ final_obj = obj[0...config.max_string]
128
+ else
129
+ final_obj = obj
130
+ end
131
+
132
+ variant.variant_type = :VARIANT_STRING
133
+ variant.string_value = Com::Rookout::Variant::String.new value: final_obj, original_size: obj.length
134
+ end
135
+
136
+ def dump_time obj, variant
137
+ variant.variant_type = :VARIANT_TIME
138
+ variant.time_value = Google::Protobuf::Timestamp.new
139
+ variant.time_value.from_time obj
140
+ end
141
+
142
+ def dump_array obj, variant, current_depth, config, log_object_errors
143
+ variant.variant_type = :VARIANT_LIST
144
+ variant.list_value = Com::Rookout::Variant::List.new type: "array", original_size: obj.length
145
+
146
+ return unless current_depth < config.max_collection_depth
147
+
148
+ obj.each_with_index do |value, index|
149
+ break if index >= config.max_width
150
+ variant.list_value.values << dump_raw_object(value, current_depth + 1, config, log_object_errors)
151
+ end
152
+ end
153
+
154
+ def dump_hash obj, variant, current_depth, config, log_object_errors
155
+ variant.variant_type = :VARIANT_MAP
156
+ variant.map_value = Com::Rookout::Variant::Map.new original_size: obj.length
157
+
158
+ return unless current_depth < config.max_collection_depth
159
+
160
+ obj.each_with_index do |(key, value), index|
161
+ break if index >= config.max_width
162
+ key_variant = dump_raw_object key, current_depth + 1, config, log_object_errors
163
+ value_variant = dump_raw_object value, current_depth + 1, config, log_object_errors
164
+ pair = Com::Rookout::Variant::Pair.new first: key_variant, second: value_variant
165
+ variant.map_value.pairs << pair
166
+ end
167
+ end
168
+
169
+ def dump_exception obj, variant, current_depth, config, log_object_errors
170
+ variant.variant_type = :VARIANT_OBJECT
171
+
172
+ message = dump_raw_object obj.message, current_depth + 1, config, log_object_errors
173
+ variant.attributes << Com::Rookout::Variant::NamedValue.new(name: "message", value: message)
174
+
175
+ cause = dump_raw_object obj.cause, current_depth + 1, config, log_object_errors
176
+ variant.attributes << Com::Rookout::Variant::NamedValue.new(name: "cause", value: cause)
177
+
178
+ backtrace = dump_raw_object obj.backtrace, current_depth + 1, config, log_object_errors
179
+ variant.attributes << Com::Rookout::Variant::NamedValue.new(name: "backtrace", value: backtrace)
180
+ end
181
+
182
+ def dump_code_object obj, variant
183
+ variant.variant_type = :VARIANT_CODE_OBJECT
184
+
185
+ if obj.is_a?(Proc) || obj.is_a?(Method)
186
+ source_location = obj.source_location
187
+ else
188
+ source_location = [nil, nil]
189
+ end
190
+
191
+ if obj.is_a? Proc
192
+ name = ""
193
+ else
194
+ name = obj.name
195
+ end
196
+
197
+ variant.code_value = Com::Rookout::Variant::CodeObject.new name: name,
198
+ filename: source_location[0],
199
+ lineno: source_location[1]
200
+ end
201
+
202
+ def dump_user_class variant
203
+ variant.variant_type = :VARIANT_OBJECT
204
+ end
205
+ end
206
+ end
207
+ end
208
+ end
@@ -0,0 +1,65 @@
1
+ module Rookout
2
+ module Processor
3
+ module Namespaces
4
+ require "English"
5
+
6
+ require_relative "../../exceptions"
7
+
8
+ require_relative "namespace"
9
+ require_relative "ruby_object_namespace"
10
+
11
+ class RubyUtilsNamespace < Namespace
12
+ def initialize
13
+ super
14
+ end
15
+
16
+ def call_method name, args
17
+ case name
18
+ when "exception"
19
+ RubyObjectNamespace.new $ERROR_INFO
20
+ when "module"
21
+ find_module args
22
+ when "env"
23
+ raise Exceptions::RookKeyNotFound, args unless ENV.include? args
24
+ RubyObjectNamespace.new ENV[args]
25
+ when "thread_id"
26
+ RubyObjectNamespace.new Thread.current.__id__
27
+ when "thread_name"
28
+ RubyObjectNamespace.new Thread.current.name
29
+ when "threads"
30
+ RubyObjectNamespace.new Thread.list
31
+ when "thread_tracebacks"
32
+ thread_tracebacks
33
+ else
34
+ super
35
+ end
36
+ end
37
+
38
+ def read_attribute _name
39
+ RubyObjectNamespace.new nil
40
+ end
41
+
42
+ def read_key _key
43
+ RubyObjectNamespace.new nil
44
+ end
45
+
46
+ private
47
+
48
+ def find_module args
49
+ RubyObjectNamespace.new Object.const_get(args)
50
+ rescue NameError
51
+ raise Exceptions::RookKeyNotFound, args
52
+ end
53
+
54
+ def thread_tracebacks
55
+ result = Thread.list.map do |thread|
56
+ { id: thread.__id__,
57
+ name: thread.name,
58
+ traceback: thread.backtrace }
59
+ end
60
+ RubyObjectNamespace.new result
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,30 @@
1
+ module Rookout
2
+ module Processor
3
+ module Namespaces
4
+ require_relative "namespace"
5
+ require_relative "frame_namespace"
6
+ require_relative "traceback_namespace"
7
+
8
+ class StackNamespace < Namespace
9
+ def initialize backtrace, offset = 0
10
+ @backtrace = backtrace
11
+ @offset = offset
12
+ end
13
+
14
+ def read_key key
15
+ FrameNamespace.new @backtrace[key + @offset]
16
+ end
17
+
18
+ def call_method name, args
19
+ return create_traceback args if name == "traceback"
20
+ super
21
+ end
22
+
23
+ def create_traceback args
24
+ args = 1000 if args == ""
25
+ TracebackNamespace.new @backtrace, @offset, args.to_i
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,40 @@
1
+ module Rookout
2
+ module Processor
3
+ module Namespaces
4
+ require_relative "namespace"
5
+ require_relative "frame_namespace"
6
+
7
+ require_relative "../../protobuf/variant_pb"
8
+
9
+ class TracebackNamespace < Namespace
10
+ def initialize backtrace, offset, depth
11
+ @backtrace = backtrace
12
+ @offset = offset
13
+ @depth = depth
14
+ end
15
+
16
+ def read_key key
17
+ FrameNamespace.new @backtrace[key + @offset]
18
+ end
19
+
20
+ def dump _log_object_errors
21
+ traceback = Com::Rookout::Variant::Traceback.new
22
+
23
+ @depth.times do |i|
24
+ position = i + @offset
25
+ break if position >= @backtrace.length
26
+ frame = @backtrace[position]
27
+
28
+ code_object = Com::Rookout::Variant::CodeObject.new filename: frame.source_location[0],
29
+ lineno: frame.source_location[1],
30
+ name: frame.eval("__method__").to_s
31
+
32
+ traceback.locations << code_object
33
+ end
34
+
35
+ Com::Rookout::Variant.new variant_type: :VARIANT_TRACEBACK, traceback: traceback
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,11 @@
1
+ module Rookout
2
+ module Processor
3
+ module Operations
4
+ class Operation
5
+ def execute _namespace
6
+ raise NotImplementedError
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,48 @@
1
+ module Rookout
2
+ module Processor
3
+ module Operations
4
+ require_relative "operation"
5
+
6
+ require_relative "../rook_error"
7
+ require_relative "../../logger"
8
+ require_relative "../../user_warnings"
9
+
10
+ class SetOperation < Operation
11
+ def initialize configuration, factory
12
+ @paths = []
13
+
14
+ configuration["paths"].each do |key, value|
15
+ begin
16
+ dest_path = factory.create_path key
17
+ source_path = factory.create_path value
18
+ @paths.push [dest_path, source_path]
19
+ rescue StandardError => e
20
+ message = "Failed to load dest:source path pair"
21
+ Logger.instance.exception message, e
22
+ warning = RookError.new e, message
23
+ UserWarnings.notify_warning warning
24
+ end
25
+ end
26
+ end
27
+
28
+ def execute namespace
29
+ @paths.each do |dest_path, source_path|
30
+ begin
31
+ value = source_path.read_from namespace
32
+ if value.is_a?(RubyObjectNamespace) && value.dump_config == Namespaces::OBJECT_DUMP_CONFIG_DEFAULT
33
+ value.tailor_limits!
34
+ end
35
+
36
+ dest_path.write_to namespace, value
37
+ rescue StandardError => e
38
+ message = "Failed to execute dest:source path pair"
39
+ Logger.instance.exception message, e
40
+ warning = RookError.new e, message
41
+ UserWarnings.notify_warning warning
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,84 @@
1
+ module Rookout
2
+ module Processor
3
+ module Paths
4
+ require_relative "path"
5
+
6
+ require_relative "../../exceptions"
7
+
8
+ require_relative "../namespaces/ruby_object_namespace"
9
+
10
+ require_relative "canopy/maps"
11
+ require_relative "canopy/actions"
12
+ require_relative "canopy/markers"
13
+
14
+ class ArithmeticPath < Path
15
+ def initialize path
16
+ if path.is_a? Hash
17
+ path = path["path"] || path[:path]
18
+ end
19
+
20
+ @raw_path = path
21
+
22
+ if path.start_with?("NOT(") && path.end_with?(")")
23
+ @path = path["NOT(".length..-2]
24
+ @negation = true
25
+ else
26
+ @path = path
27
+ @negation = false
28
+ end
29
+
30
+ raise RookInvalidArithmeticPath, @raw_path if @path.empty?
31
+ end
32
+
33
+ def read_from namespace
34
+ begin
35
+ result = Maps.parse @path, actions: Canopy::Actions.new(namespace)
36
+ rescue Maps::ParseError => e
37
+ raise RookInvalidArithmeticPath.new(@path, e)
38
+ end
39
+
40
+ normalize result
41
+ end
42
+
43
+ def write_to namespace, value
44
+ context = Canopy::Actions.new namespace
45
+
46
+ begin
47
+ # initialize operations chain - by parsing the expression - ignore return value
48
+ Maps.parse @path, actions: context
49
+ rescue Maps::ParseError => e
50
+ raise RookInvalidArithmeticPath.new(@path, e)
51
+ end
52
+
53
+ raise RookInvalidArithmeticPath, @raw_path if context.operations.empty?
54
+
55
+ (context.operations.length - 1).times do |i|
56
+ namespace = context.operations[i].read namespace, true
57
+ end
58
+
59
+ context.operations[context.operations.length - 1].write namespace, value
60
+ end
61
+
62
+ def normalize result
63
+ if result.is_a? Canopy::List
64
+ new_array = result.obj.map(&:obj)
65
+ return Namespaces::RubyObjectNamespace.new new_array
66
+ end
67
+
68
+ if result.is_a? Canopy::NamespaceResult
69
+ return result.obj
70
+ end
71
+
72
+ if result.is_a? Canopy::ToolExceptionMarker
73
+ raise result.obj if result.obj.is_a? Exceptions::ToolException
74
+ raise Exceptions::RookInvalidArithmeticPath, @raw_path, result.obj
75
+ end
76
+
77
+ res = result.obj
78
+ res = !res if [true, false].include?(res) && @negation
79
+ Namespaces::RubyObjectNamespace.new res
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end