rookout 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|