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.
- checksums.yaml +7 -0
- data/LICENSE +12 -0
- data/bin/rookout +30 -0
- data/lib/rookout.rb +18 -0
- data/lib/rookout/augs/actions/action.rb +11 -0
- data/lib/rookout/augs/actions/action_run_processor.rb +29 -0
- data/lib/rookout/augs/aug.rb +121 -0
- data/lib/rookout/augs/aug_factory.rb +69 -0
- data/lib/rookout/augs/aug_rate_limiter.rb +96 -0
- data/lib/rookout/augs/augs_manager.rb +77 -0
- data/lib/rookout/augs/conditions/condition.rb +15 -0
- data/lib/rookout/augs/locations/location.rb +11 -0
- data/lib/rookout/augs/locations/location_file_line.rb +26 -0
- data/lib/rookout/com_ws/agent_com_ws.rb +221 -0
- data/lib/rookout/com_ws/backoff.rb +35 -0
- data/lib/rookout/com_ws/command_handler.rb +22 -0
- data/lib/rookout/com_ws/git.rb +53 -0
- data/lib/rookout/com_ws/information.rb +85 -0
- data/lib/rookout/com_ws/output.rb +135 -0
- data/lib/rookout/com_ws/token_bucket.rb +36 -0
- data/lib/rookout/config.rb +55 -0
- data/lib/rookout/exceptions.rb +140 -0
- data/lib/rookout/interface.rb +140 -0
- data/lib/rookout/logger.rb +158 -0
- data/lib/rookout/processor/namespace_serializer.rb +26 -0
- data/lib/rookout/processor/namespaces/container_namespace.rb +45 -0
- data/lib/rookout/processor/namespaces/frame_namespace.rb +65 -0
- data/lib/rookout/processor/namespaces/namespace.rb +28 -0
- data/lib/rookout/processor/namespaces/noop_namespace.rb +32 -0
- data/lib/rookout/processor/namespaces/ruby_object_namespace.rb +97 -0
- data/lib/rookout/processor/namespaces/ruby_object_serializer.rb +208 -0
- data/lib/rookout/processor/namespaces/ruby_utils_namespace.rb +65 -0
- data/lib/rookout/processor/namespaces/stack_namespace.rb +30 -0
- data/lib/rookout/processor/namespaces/traceback_namespace.rb +40 -0
- data/lib/rookout/processor/operations/operation.rb +11 -0
- data/lib/rookout/processor/operations/set_operation.rb +48 -0
- data/lib/rookout/processor/paths/arithmetic_path.rb +84 -0
- data/lib/rookout/processor/paths/canopy/actions.rb +184 -0
- data/lib/rookout/processor/paths/canopy/consts.rb +82 -0
- data/lib/rookout/processor/paths/canopy/maps.rb +2837 -0
- data/lib/rookout/processor/paths/canopy/markers.rb +186 -0
- data/lib/rookout/processor/paths/path.rb +15 -0
- data/lib/rookout/processor/processor.rb +34 -0
- data/lib/rookout/processor/processor_factory.rb +23 -0
- data/lib/rookout/processor/rook_error.rb +45 -0
- data/lib/rookout/protobuf/.gitignore +0 -0
- data/lib/rookout/protobuf/agent_info_pb.rb +68 -0
- data/lib/rookout/protobuf/controller_info_pb.rb +29 -0
- data/lib/rookout/protobuf/envelope_pb.rb +21 -0
- data/lib/rookout/protobuf/messages_pb.rb +189 -0
- data/lib/rookout/protobuf/variant_pb.rb +139 -0
- data/lib/rookout/rookout_singleton.rb +73 -0
- data/lib/rookout/services/position.rb +163 -0
- data/lib/rookout/services/tracer.rb +83 -0
- data/lib/rookout/trigger_services.rb +34 -0
- data/lib/rookout/user_warnings.rb +25 -0
- data/lib/rookout/version.rb +4 -0
- 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
|