rookout 0.1.0 → 0.1.5
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 +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
|