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,158 @@
1
+ module Rookout
2
+ require "fileutils"
3
+ require "English"
4
+
5
+ require_relative "config"
6
+
7
+ class Logger
8
+ require "singleton"
9
+ include Singleton
10
+
11
+ LOG_LEVELS = [:DEBUG, :INFO, :WARNING, :ERROR].freeze
12
+
13
+ def initialize
14
+ @verbosity = LOG_LEVELS.index(Config.logger_log_level) || LOG_LEVELS.index(:INFO)
15
+
16
+ @output = nil
17
+ @handlers = []
18
+ build_handlers
19
+ end
20
+
21
+ def register_output output
22
+ @output = output
23
+ end
24
+
25
+ def remove_output _output
26
+ @output = nil
27
+ end
28
+
29
+ def debug message, *args
30
+ log :DEBUG, message, args
31
+ end
32
+
33
+ def info message, *args
34
+ log :INFO, message, args
35
+ end
36
+
37
+ def warning message, *args
38
+ log :WARNING, message, args
39
+ end
40
+
41
+ def error message, *args
42
+ log :ERROR, message, args
43
+ end
44
+
45
+ def exception message, exc
46
+ # TODO: REVIEW HOW TO REPORT EXCEPTIONS
47
+ error message, exc
48
+ end
49
+
50
+ private
51
+
52
+ class LogRecord
53
+ def initialize level, message, arguments
54
+ @level = level
55
+ @time = Time.new
56
+ @message = message
57
+ @formatted_message = message % arguments
58
+ @arguments = arguments
59
+ set_caller
60
+ end
61
+
62
+ attr_reader :level, :time, :filename, :lineno, :message, :formatted_message, :arguments
63
+
64
+ def format
65
+ "#{@time} #{Process.pid}:#{Thread.current.name}-" \
66
+ "#{File.basename @filename}:#{@label}@#{lineno} - #{@level} - #{formatted_message}"
67
+ end
68
+
69
+ private
70
+
71
+ def set_caller
72
+ @filename = nil
73
+ @lineno = nil
74
+ @label = nil
75
+
76
+ caller_locations(4, 7).each do |caller|
77
+ next if caller.absolute_path.end_with? "lib/rookout/logger.rb"
78
+
79
+ @filename = caller.path
80
+ @lineno = caller.lineno
81
+ @label = caller.label
82
+ break
83
+ end
84
+ end
85
+ end
86
+
87
+ def log level, message, args
88
+ level_no = LOG_LEVELS.index level
89
+ if level_no.nil?
90
+ level = :ERROR
91
+ level_no = LOG_LEVELS.index level
92
+ end
93
+
94
+ return if level_no < @verbosity
95
+
96
+ record = LogRecord.new level, message, args
97
+ @handlers.each { |handler| handler.call record }
98
+ end
99
+
100
+ def build_handlers
101
+ @handlers.push new_file_handler unless Config.logger_filename.nil? || Config.logger_filename.empty?
102
+ @handlers.push new_stderr_handler if Config.logger_log_to_stderr
103
+ @handlers.push new_remote_handler
104
+ end
105
+
106
+ def new_file_handler
107
+ log_file_path = calculate_log_file_path
108
+ directory = File.dirname log_file_path
109
+
110
+ begin
111
+ FileUtils.mkdir_p directory
112
+ file = File.open log_file_path, "a"
113
+ rescue SystemCallError => e
114
+ file = nil
115
+
116
+ if Config.debug
117
+ STDERR.puts "[Rookout] Failed to open log file: #{log_file_path}"
118
+ STDERR.puts e.backtrace
119
+ end
120
+ end
121
+
122
+ ->(record) { file.write record.format + "\n" if file }
123
+ end
124
+
125
+ def calculate_log_file_path
126
+ return Config.logger_filename if absolute_path? Config.logger_filename
127
+
128
+ if RUBY_PLATFORM.include? "darwin"
129
+ File.join ENV["HOME"], Config.logger_filename
130
+ elsif RUBY_PLATFORM.match?(/cygwin|mswin|mingw|bccwin|wince|emx/)
131
+ File.join ENV["USERPROFILE"], Config.logger_filename
132
+ else
133
+ File.join "/var/log", Config.logger_filename
134
+ end
135
+ end
136
+
137
+ def new_stderr_handler
138
+ ->(record) { STDERR.puts record.format }
139
+ end
140
+
141
+ def new_remote_handler
142
+ lambda do |record|
143
+ return unless @output
144
+ @output.send_log_message record.level,
145
+ record.time,
146
+ record.filename,
147
+ record.lineno,
148
+ record.message,
149
+ record.formatted_message,
150
+ record.arguments
151
+ end
152
+ end
153
+
154
+ def absolute_path? path
155
+ path == File.absolute_path(path)
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,26 @@
1
+ module Rookout
2
+ module Processor
3
+ module NamespaceSerializer
4
+ require_relative "../logger"
5
+
6
+ require_relative "../protobuf/variant_pb"
7
+
8
+ module_function
9
+
10
+ def dump namespace, log_errors = true
11
+ namespace.dump log_errors
12
+ rescue StandardError => e
13
+ message = "Failed to serialize namespace"
14
+ variant = Com::Rookout::Variant.new variant_type: :VARIANT_ERROR
15
+
16
+ if log_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
+ end
25
+ end
26
+ end
@@ -0,0 +1,45 @@
1
+ module Rookout
2
+ module Processor
3
+ module Namespaces
4
+ require_relative "namespace"
5
+ require_relative "ruby_object_namespace"
6
+
7
+ require_relative "../../exceptions"
8
+
9
+ require_relative "../../protobuf/variant_pb"
10
+
11
+ class ContainerNamespace < Namespace
12
+ def initialize hash = {}
13
+ @hash = hash
14
+ end
15
+
16
+ def call_method name, args
17
+ return RubyObjectNamespace.new @hash.length if name == "size"
18
+ super
19
+ end
20
+
21
+ def read_attribute name
22
+ raise Exceptions::RookAttributeNotFound, name unless @hash.key? name
23
+ @hash[name]
24
+ end
25
+
26
+ def write_attribute name, value
27
+ @hash[name] = value
28
+ end
29
+
30
+ def dump log_object_errors
31
+ variant = Com::Rookout::Variant.new variant_type: :VARIANT_NAMESPACE,
32
+ namespace_value: Com::Rookout::Variant::Namespace.new
33
+
34
+ @hash.each do |key, value|
35
+ dumped_value = value.dump log_object_errors
36
+ namespace = Com::Rookout::Variant::NamedValue.new name: key, value: dumped_value
37
+ variant.namespace_value.attributes << namespace
38
+ end
39
+
40
+ variant
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,65 @@
1
+ module Rookout
2
+ module Processor
3
+ module Namespaces
4
+ require_relative "namespace"
5
+ require_relative "ruby_object_namespace"
6
+ require_relative "container_namespace"
7
+ require_relative "../../exceptions"
8
+
9
+ class FrameNamespace < Namespace
10
+ def initialize binding
11
+ @binding = binding
12
+ end
13
+
14
+ def read_attribute name
15
+ raise Exceptions::RookAttributeNotFound, name unless @binding.local_variable_defined? name
16
+ RubyObjectNamespace.new @binding.local_variable_get name
17
+ end
18
+
19
+ def call_method name, args
20
+ case name
21
+ when "filename"
22
+ RubyObjectNamespace.new @binding.source_location[0]
23
+ when "line"
24
+ RubyObjectNamespace.new @binding.source_location[1]
25
+ when "function"
26
+ RubyObjectNamespace.new @binding.eval("__method__").to_s
27
+ when "module"
28
+ RubyObjectNamespace.new @binding.source_location[0]
29
+ when "locals"
30
+ locals args
31
+ when "dump"
32
+ 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]),
37
+ "locals" => locals(args)
38
+ }
39
+ ContainerNamespace.new result
40
+ else
41
+ super
42
+ end
43
+ end
44
+
45
+ def locals args
46
+ dump_config = nil
47
+ unless args.nil?
48
+ dump_config = OBJECT_DUMP_TABLE[args.downcase]
49
+ end
50
+
51
+ hash = {}
52
+ local_variables = @binding.local_variables
53
+ local_variables.each do |var|
54
+ value = @binding.local_variable_get var
55
+ hash[var.to_s] = RubyObjectNamespace.new value, dump_config
56
+ end
57
+
58
+ hash["self"] = RubyObjectNamespace.new @binding.receiver, dump_config
59
+
60
+ ContainerNamespace.new hash
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,28 @@
1
+ module Rookout
2
+ module Processor
3
+ module Namespaces
4
+ class Namespace
5
+ require_relative "../../exceptions"
6
+ def call_method name, _args
7
+ raise Exceptions::RookMethodNotFound, self.class.to_s, name
8
+ end
9
+
10
+ def read_attribute name
11
+ raise Exceptions::RookAttributeNotFound, name
12
+ end
13
+
14
+ def write_attribute name, _value
15
+ raise Exceptions::RookWriteAttributeNotSupported, self.class.to_s, name
16
+ end
17
+
18
+ def read_key key
19
+ raise Exceptions::RookKeyNotFound, key
20
+ end
21
+
22
+ def dump _log_object_errors
23
+ raise NotImplementedError
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,32 @@
1
+ module Rookout
2
+ module Processor
3
+ module Namespaces
4
+ require_relative "namespace"
5
+ require_relative "ruby_object_namespace"
6
+
7
+ require_relative "../../protobuf/variant_pb"
8
+
9
+ class RubyUtilsNamespace < Namespace
10
+ def initialize
11
+ super
12
+ end
13
+
14
+ def call_method _name, _args
15
+ RubyObjectNamespace nil
16
+ end
17
+
18
+ def read_attribute _name
19
+ RubyObjectNamespace nil
20
+ end
21
+
22
+ def read_key _key
23
+ RubyObjectNamespace nil
24
+ end
25
+
26
+ def dump _log_object_errors
27
+ Com::Rookout::Variant.new variant_type: :VARIANT_NONE
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,97 @@
1
+ module Rookout
2
+ module Processor
3
+ module Namespaces
4
+ require "bigdecimal"
5
+ require "google/protobuf/well_known_types"
6
+
7
+ require_relative "../../exceptions"
8
+
9
+ require_relative "namespace"
10
+ require_relative "ruby_object_serializer"
11
+
12
+ class ObjectDumpConfig
13
+ def initialize max_depth, max_width, max_collection_depth, max_string
14
+ @max_depth = max_depth
15
+ @max_width = max_width
16
+ @max_collection_depth = max_collection_depth
17
+ @max_string = max_string
18
+ end
19
+
20
+ attr_reader :max_depth, :max_width, :max_collection_depth, :max_string
21
+ end
22
+
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
+
27
+ OBJECT_DUMP_CONFIG_STRING = ObjectDumpConfig.new 1, 0, 0, 64 * 1024
28
+ OBJECT_DUMP_CONFIG_COLLECTION = ObjectDumpConfig.new 4, 100, 2, 512
29
+
30
+ OBJECT_DUMP_TABLE = {
31
+ "" => OBJECT_DUMP_CONFIG_DEFAULT,
32
+ "strict" => OBJECT_DUMP_CONFIG_STRICT,
33
+ "default" => OBJECT_DUMP_CONFIG_DEFAULT,
34
+ "tolerant" => OBJECT_DUMP_CONFIG_TOLERANT
35
+ }.freeze
36
+
37
+ class RubyObjectNamespace < Namespace
38
+ include RubyObjectSerializer
39
+
40
+ def initialize obj, dump_config = OBJECT_DUMP_CONFIG_DEFAULT
41
+ @obj = obj
42
+ @dump_config = dump_config
43
+ end
44
+
45
+ attr_reader :obj, :dump_config
46
+
47
+ def tailor_limits!
48
+ if @obj.is_a? String
49
+ @dump_config = OBJECT_DUMP_CONFIG_STRING
50
+ elsif @obj.is_a?(Hash) || @obj.is_a?(Array)
51
+ @dump_config = OBJECT_DUMP_CONFIG_COLLECTION
52
+ end
53
+ self
54
+ end
55
+
56
+ def read_attribute name
57
+ attributes = @obj.instance_variables
58
+ raise RookAttributeNotFound, name unless attributes.include? name.to_sym
59
+ RubyObjectNamespace.new @obj.instance_variable_get(name)
60
+ end
61
+
62
+ 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
75
+ else
76
+ raise Exceptions::RookInvalidObjectForAccess.new(obj.class.to_s, "ReadKey")
77
+ end
78
+ end
79
+
80
+ def call_method name, args
81
+ case name
82
+ when "type"
83
+ RubyObjectNamespace.new @obj.class.to_s
84
+ when "size"
85
+ RubyObjectNamespace.new @obj.length
86
+ else
87
+ super
88
+ end
89
+ end
90
+
91
+ def dump log_object_errors
92
+ dump_raw_object @obj, 0, @dump_config, log_object_errors
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end