rookout 0.1.0 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rookout/augs/actions/action_run_processor.rb +3 -3
- data/lib/rookout/augs/aug.rb +24 -90
- data/lib/rookout/augs/aug_factory.rb +24 -14
- data/lib/rookout/augs/aug_rate_limiter.rb +3 -3
- data/lib/rookout/augs/augs_manager.rb +3 -1
- data/lib/rookout/augs/conditions/condition.rb +4 -2
- data/lib/rookout/augs/locations/location.rb +75 -1
- data/lib/rookout/augs/locations/location_exception_handler.rb +22 -0
- data/lib/rookout/augs/locations/location_file_line.rb +16 -4
- data/lib/rookout/com_ws/agent_com_ws.rb +28 -33
- data/lib/rookout/com_ws/information.rb +1 -1
- data/lib/rookout/com_ws/output.rb +4 -10
- data/lib/rookout/com_ws/pinger.rb +36 -0
- data/lib/rookout/com_ws/websocket_client.rb +143 -0
- data/lib/rookout/commit.rb +3 -0
- data/lib/rookout/config.rb +1 -0
- data/lib/rookout/exceptions.rb +40 -0
- data/lib/rookout/interface.rb +41 -24
- data/lib/rookout/logger.rb +16 -2
- data/lib/rookout/processor/namespace_serializer.rb +1 -1
- data/lib/rookout/processor/namespaces/frame_namespace.rb +1 -0
- data/lib/rookout/processor/namespaces/namespace.rb +2 -2
- data/lib/rookout/processor/namespaces/noop_namespace.rb +1 -1
- data/lib/rookout/processor/namespaces/ruby_object_serializer.rb +4 -3
- data/lib/rookout/processor/operations/set_operation.rb +4 -1
- data/lib/rookout/processor/paths/arithmetic_path.rb +1 -1
- data/lib/rookout/processor/paths/canopy/markers.rb +5 -2
- data/lib/rookout/rookout_singleton.rb +4 -3
- data/lib/rookout/services/position.rb +73 -73
- data/lib/rookout/services/tracer.rb +8 -5
- data/lib/rookout/trigger_services.rb +2 -2
- data/lib/rookout/user_warnings.rb +2 -0
- data/lib/rookout/utils.rb +9 -0
- data/lib/rookout/version.rb +1 -2
- metadata +37 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a651effede1b4bb60cf30bcc0ad23adac929ebb41ac69e0e059acc988542defc
|
4
|
+
data.tar.gz: dd89562cd624e99ee1dbac58a9f045ee49175ccf12b9341df5cd0fbae1122774
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42e4512c638fa18f2e75ac71154422a6a4a953ac013f070dfe07276f582aa695336baff015233df77bfe3daa36c44784ba65147c5d89682eacd6d985fa7d63aa
|
7
|
+
data.tar.gz: 71926999899dd01a46af82f6ac5884f543b56804e91559f7085256e09d9a172541baf55b3f0a712d06b9997e3ec9f90ac372a028c5a4bf5839a539b17e5d6497
|
@@ -15,12 +15,12 @@ module Rookout
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def execute aug_id, report_id, namespace,
|
18
|
+
def execute aug_id, report_id, namespace, output
|
19
19
|
@processor.process namespace
|
20
|
-
|
20
|
+
output.send_user_message aug_id, report_id, namespace.read_attribute("store")
|
21
21
|
return unless @post_processor
|
22
22
|
|
23
|
-
|
23
|
+
output.flush_message
|
24
24
|
@post_processor.process namespace
|
25
25
|
end
|
26
26
|
end
|
data/lib/rookout/augs/aug.rb
CHANGED
@@ -1,11 +1,6 @@
|
|
1
|
-
require_relative "../logger"
|
2
|
-
require_relative "../user_warnings"
|
3
|
-
require_relative "../processor/rook_error"
|
4
|
-
|
5
1
|
module Rookout
|
6
2
|
module Augs
|
7
|
-
|
8
|
-
require "concurrent-ruby/concurrent/atom"
|
3
|
+
require_relative "../utils"
|
9
4
|
|
10
5
|
require_relative "../processor/namespaces/frame_namespace"
|
11
6
|
require_relative "../processor/namespaces/stack_namespace"
|
@@ -13,109 +8,48 @@ module Rookout
|
|
13
8
|
require_relative "../processor/namespaces/ruby_utils_namespace"
|
14
9
|
require_relative "../processor/namespaces/noop_namespace"
|
15
10
|
|
16
|
-
require_relative "../logger"
|
17
|
-
|
18
|
-
MAX_LOG_CACHE_SIZE = 10
|
19
|
-
|
20
11
|
class Aug
|
21
|
-
def initialize aug_id,
|
12
|
+
def initialize aug_id, action, condition, rate_limiter, _max_aug_time
|
22
13
|
# NOTE: max_aux_time is not implemented
|
23
14
|
|
24
15
|
@id = aug_id
|
25
|
-
@location = location
|
26
16
|
@action = action
|
27
17
|
@condition = condition
|
28
18
|
@rate_limiter = rate_limiter
|
29
|
-
@output = output
|
30
19
|
|
31
20
|
@enabled = true
|
32
21
|
@status = nil
|
33
22
|
@log_cache = []
|
34
23
|
end
|
35
|
-
end
|
36
|
-
|
37
|
-
attr_reader :id
|
38
|
-
|
39
|
-
def add_aug trigger_services
|
40
|
-
@location.add_aug trigger_services, self
|
41
|
-
rescue SystemExit
|
42
|
-
raise
|
43
|
-
rescue Exception => e
|
44
|
-
message = "Exception when adding aug"
|
45
|
-
Logger.instance.error message, e
|
46
|
-
notify_error RookError.new e, message
|
47
|
-
end
|
48
24
|
|
49
|
-
|
50
|
-
return unless @enabled
|
25
|
+
attr_reader :id
|
51
26
|
|
52
|
-
|
53
|
-
|
54
|
-
namespace = create_namespaces frame, extracted
|
27
|
+
def execute frame, extracted, output
|
28
|
+
return unless @enabled
|
55
29
|
|
56
|
-
|
30
|
+
namespace = create_namespaces frame, extracted
|
31
|
+
return if @condition && !@condition.evaluate(namespace)
|
57
32
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
end
|
62
|
-
rescue SystemExit
|
63
|
-
raise
|
64
|
-
rescue Exception => e
|
65
|
-
message = "Exception while processing Aug"
|
66
|
-
error = RookError.new e, message
|
67
|
-
notify_warning error unless silence_log? error
|
33
|
+
@rate_limiter.with_limit do
|
34
|
+
report_id = Utils.uuid
|
35
|
+
@action.execute @id, report_id, namespace, output
|
68
36
|
end
|
69
37
|
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def notify_active
|
73
|
-
send_rule_status :Active
|
74
|
-
end
|
75
|
-
|
76
|
-
def notify_pending
|
77
|
-
send_rule_status :Pending
|
78
|
-
end
|
79
|
-
|
80
|
-
def notify_removed
|
81
|
-
send_rule_status :Deleted
|
82
|
-
end
|
83
38
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
"extracted": Processor::Namespaces::ContainerNamespace.new(extracted),
|
99
|
-
"store": Processor::Namespaces::ContainerNamespace.new,
|
100
|
-
"temp": Processor::Namespaces::ContainerNamespace.new,
|
101
|
-
"utils": Processor::Namespaces::RubyUtisNamespace.new,
|
102
|
-
"trace": Processor::Namespaces::NoopNamespace.new)
|
103
|
-
end
|
104
|
-
|
105
|
-
def silence_log? error
|
106
|
-
return true if @log_cache.length >= MAX_LOG_CACHE_SIZE || @log_cache.include(error.message)
|
107
|
-
|
108
|
-
@log_cache << error.message
|
109
|
-
false
|
110
|
-
end
|
111
|
-
|
112
|
-
def send_rule_status status, error = nil
|
113
|
-
return unless @status != status
|
114
|
-
|
115
|
-
Logger.instance.info "Updating rule status for #{@id} to #{status}"
|
116
|
-
@status = status
|
117
|
-
|
118
|
-
@output.send_rule_status @id, status, error
|
39
|
+
private
|
40
|
+
|
41
|
+
def create_namespaces frame, extracted
|
42
|
+
Processor::Namespaces::ContainerNamespace.new(
|
43
|
+
"frame" => Processor::Namespaces::FrameNamespace.new(frame[1]),
|
44
|
+
"stack" => Processor::Namespaces::StackNamespace.new(frame, 1),
|
45
|
+
"extracted" => Processor::Namespaces::ContainerNamespace.new(extracted),
|
46
|
+
"store" => Processor::Namespaces::ContainerNamespace.new,
|
47
|
+
"temp" => Processor::Namespaces::ContainerNamespace.new,
|
48
|
+
"utils" => Processor::Namespaces::RubyUtilsNamespace.new,
|
49
|
+
"trace" => Processor::Namespaces::NoopNamespace.new,
|
50
|
+
"state" => Processor::Namespaces::NoopNamespace.new
|
51
|
+
)
|
52
|
+
end
|
119
53
|
end
|
120
54
|
end
|
121
55
|
end
|
@@ -6,7 +6,10 @@ module Rookout
|
|
6
6
|
|
7
7
|
require_relative "actions/action_run_processor"
|
8
8
|
require_relative "conditions/condition"
|
9
|
+
require_relative "locations/location_file_line"
|
10
|
+
require_relative "locations/location_exception_handler"
|
9
11
|
require_relative "aug_rate_limiter"
|
12
|
+
require_relative "aug"
|
10
13
|
|
11
14
|
class AugFactory
|
12
15
|
def initialize output
|
@@ -16,35 +19,42 @@ module Rookout
|
|
16
19
|
|
17
20
|
def create_aug configuration
|
18
21
|
aug_id = configuration["id"]
|
19
|
-
raise Exceptions.
|
20
|
-
|
21
|
-
location_configuration = configuration["location"]
|
22
|
-
raise Exceptions.RookAugInvalidKey "location", configuration unless location_configuration.is_a? Hash
|
23
|
-
location = create_location location_configuration
|
22
|
+
raise Exceptions::RookAugInvalidKey.new("id", configuration) unless aug_id.is_a? String
|
24
23
|
|
25
24
|
action_configuration = configuration["action"]
|
26
|
-
raise Exceptions.
|
27
|
-
action = Actions.
|
25
|
+
raise Exceptions::RookAugInvalidKey.new("action", configuration) unless action_configuration.is_a? Hash
|
26
|
+
action = Actions::ActionRunProcessor.new action_configuration, @factory
|
28
27
|
|
29
|
-
max_aug_time = configuration["maxAugTime"] || Config.
|
28
|
+
max_aug_time = configuration["maxAugTime"] || Config.instrumentation_max_aug_time
|
30
29
|
|
31
30
|
condition_configuration = configuration["conditional"]
|
32
|
-
raise Exceptions.
|
33
|
-
|
31
|
+
raise Exceptions::RookAugInvalidKey.new("conditional", configuration) unless
|
32
|
+
condition_configuration.nil? || condition_configuration.is_a?(String)
|
33
|
+
condition = condition_configuration.nil? ? nil : Conditions::Condition.new(condition_configuration)
|
34
34
|
|
35
35
|
rate_limit = create_rate_limit configuration
|
36
36
|
|
37
|
-
Aug.new aug_id,
|
37
|
+
aug = Aug.new aug_id, action, condition, rate_limit, max_aug_time
|
38
|
+
|
39
|
+
location_configuration = configuration["location"]
|
40
|
+
raise Exceptions::RookAugInvalidKey.new("location", configuration) unless location_configuration.is_a? Hash
|
41
|
+
create_location location_configuration, aug
|
38
42
|
end
|
39
43
|
|
40
44
|
private
|
41
45
|
|
42
|
-
def create_location configuration
|
46
|
+
def create_location configuration, aug
|
43
47
|
name = configuration["name"]
|
44
48
|
raise Exceptions.RookObjectNameMissing if name.nil?
|
45
|
-
raise Exceptions.RookUnsupportedLocation if name != "file_line"
|
46
49
|
|
47
|
-
|
50
|
+
case name
|
51
|
+
when "file_line"
|
52
|
+
return Locations::LocationFileLine.new configuration, @output, aug
|
53
|
+
when "exception_handler"
|
54
|
+
return Locations::LocationExceptionHandler.new configuration, @output, aug
|
55
|
+
else
|
56
|
+
raise Exceptions.RookUnsupportedLocation if name != "file_line"
|
57
|
+
end
|
48
58
|
end
|
49
59
|
|
50
60
|
def create_rate_limit configuration
|
@@ -15,12 +15,12 @@ module Rookout
|
|
15
15
|
|
16
16
|
def with_limit start_time = nil
|
17
17
|
active = false
|
18
|
-
start_time ||= Time.
|
18
|
+
start_time ||= Time.now
|
19
19
|
|
20
20
|
# If quota, verify it
|
21
21
|
if @quota
|
22
22
|
# Get current time
|
23
|
-
now_ms = (
|
23
|
+
now_ms = (start_time.to_f * 1000).to_i
|
24
24
|
|
25
25
|
# Calculate window keys
|
26
26
|
current_window_key = (now_ms / @window_size) * @window_size
|
@@ -77,7 +77,7 @@ module Rookout
|
|
77
77
|
return if prev_value.nil?
|
78
78
|
|
79
79
|
# Add value to quota
|
80
|
-
@windows[current_window_key] +=
|
80
|
+
@windows[current_window_key] += [duration, 5].max.to_f
|
81
81
|
end
|
82
82
|
|
83
83
|
def cleanup now_ms
|
@@ -2,6 +2,8 @@ module Rookout
|
|
2
2
|
module Augs
|
3
3
|
require_relative "../logger"
|
4
4
|
|
5
|
+
require_relative "../processor/rook_error"
|
6
|
+
|
5
7
|
require_relative "aug_factory"
|
6
8
|
|
7
9
|
class AugsManager
|
@@ -43,7 +45,7 @@ module Rookout
|
|
43
45
|
return
|
44
46
|
end
|
45
47
|
|
46
|
-
error = RookError.new e, message
|
48
|
+
error = Rookout::Processor::RookError.new e, message
|
47
49
|
@output.send_rule_status aug_id, "Error", error
|
48
50
|
return
|
49
51
|
end
|
@@ -1,13 +1,15 @@
|
|
1
1
|
module Rookout
|
2
2
|
module Augs
|
3
3
|
module Conditions
|
4
|
+
require_relative "../../processor/paths/arithmetic_path"
|
5
|
+
|
4
6
|
class Condition
|
5
7
|
def initialize condition
|
6
|
-
@path = ArithmeticPath.new condition
|
8
|
+
@path = Processor::Paths::ArithmeticPath.new condition
|
7
9
|
end
|
8
10
|
|
9
11
|
def evaluate namespace
|
10
|
-
@path.read_from(namespace).
|
12
|
+
@path.read_from(namespace).obj == true
|
11
13
|
end
|
12
14
|
end
|
13
15
|
end
|
@@ -1,10 +1,84 @@
|
|
1
1
|
module Rookout
|
2
2
|
module Augs
|
3
3
|
module Locations
|
4
|
+
require_relative "../../processor/rook_error"
|
5
|
+
|
6
|
+
MAX_LOG_CACHE_SIZE = 10
|
7
|
+
|
4
8
|
class Location
|
5
|
-
def
|
9
|
+
def initialize output, aug
|
10
|
+
@output = output
|
11
|
+
@aug = aug
|
12
|
+
@log_cache = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_aug _trigger_services
|
6
16
|
raise NotImplementedError
|
7
17
|
end
|
18
|
+
|
19
|
+
def id
|
20
|
+
@aug.id
|
21
|
+
end
|
22
|
+
|
23
|
+
def execute frame, extracted
|
24
|
+
UserWarnings.with self do
|
25
|
+
begin
|
26
|
+
@aug.execute frame, extracted, @output
|
27
|
+
rescue SystemExit
|
28
|
+
raise
|
29
|
+
rescue Exception => e
|
30
|
+
message = "Exception while processing Aug"
|
31
|
+
puts e.message + "\n" + e.backtrace.join("\n\t")
|
32
|
+
error = Processor::RookError.new e, message
|
33
|
+
notify_warning error
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def notify_active
|
39
|
+
send_rule_status :Active
|
40
|
+
end
|
41
|
+
|
42
|
+
def notify_pending
|
43
|
+
send_rule_status :Pending
|
44
|
+
end
|
45
|
+
|
46
|
+
def notify_removed
|
47
|
+
send_rule_status :Deleted
|
48
|
+
end
|
49
|
+
|
50
|
+
def notify_error error
|
51
|
+
send_rule_status :Error, error
|
52
|
+
end
|
53
|
+
|
54
|
+
def notify_warning error
|
55
|
+
return if silence_log? error
|
56
|
+
|
57
|
+
Logger.instance.warning error.message
|
58
|
+
|
59
|
+
send_rule_status :Warning, error
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def silence_log? error
|
65
|
+
return true if @log_cache.length >= MAX_LOG_CACHE_SIZE || @log_cache.include?(error.message)
|
66
|
+
|
67
|
+
@log_cache << error.message
|
68
|
+
false
|
69
|
+
end
|
70
|
+
|
71
|
+
def send_rule_status status, error = nil
|
72
|
+
return if @status == status
|
73
|
+
|
74
|
+
Logger.instance.info "Updating rule status for #{@id} to #{status}"
|
75
|
+
@status = status
|
76
|
+
|
77
|
+
# For easier testing
|
78
|
+
return if @output.nil?
|
79
|
+
|
80
|
+
@output.send_rule_status id, status, error
|
81
|
+
end
|
8
82
|
end
|
9
83
|
end
|
10
84
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Rookout
|
2
|
+
module Augs
|
3
|
+
require_relative "../../logger"
|
4
|
+
|
5
|
+
require_relative "../../processor/rook_error"
|
6
|
+
|
7
|
+
module Locations
|
8
|
+
require_relative "location"
|
9
|
+
|
10
|
+
class LocationExceptionHandler < Location
|
11
|
+
NAME = "exception_handler".freeze
|
12
|
+
|
13
|
+
def initialize _arguments, output, aug
|
14
|
+
super output, aug
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_aug _trigger_services
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,24 +1,36 @@
|
|
1
1
|
module Rookout
|
2
2
|
module Augs
|
3
|
+
require_relative "../../logger"
|
4
|
+
|
5
|
+
require_relative "../../processor/rook_error"
|
6
|
+
|
3
7
|
module Locations
|
4
8
|
require_relative "location"
|
5
9
|
|
6
10
|
class LocationFileLine < Location
|
7
11
|
NAME = "file_line".freeze
|
8
12
|
|
9
|
-
def initialize arguments,
|
13
|
+
def initialize arguments, output, aug
|
14
|
+
super output, aug
|
10
15
|
@filename = arguments["filename"]
|
11
16
|
@lineno = arguments["lineno"]
|
12
17
|
|
18
|
+
# NOTE: Hashes are only used for suggestions, not for verification
|
13
19
|
@file_hash = arguments["sha256"]
|
14
20
|
@line_crc = arguments["line_crc32_2"]
|
15
|
-
@line_unique = arguments["line_unique"]
|
21
|
+
@line_unique = arguments["line_unique"] || false
|
16
22
|
end
|
17
23
|
|
18
24
|
attr_reader :filename, :lineno, :file_hash, :line_crc, :line_unique
|
19
25
|
|
20
|
-
def add_aug trigger_services
|
21
|
-
trigger_services.get_service("position").add_aug self
|
26
|
+
def add_aug trigger_services
|
27
|
+
trigger_services.get_service("position").add_aug self
|
28
|
+
rescue SystemExit
|
29
|
+
raise
|
30
|
+
rescue Exception => e
|
31
|
+
message = "Exception when adding aug"
|
32
|
+
Logger.instance.error message, e
|
33
|
+
notify_error Processor::RookError.new e, message
|
22
34
|
end
|
23
35
|
end
|
24
36
|
end
|