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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rookout/augs/actions/action_run_processor.rb +3 -3
  3. data/lib/rookout/augs/aug.rb +24 -90
  4. data/lib/rookout/augs/aug_factory.rb +24 -14
  5. data/lib/rookout/augs/aug_rate_limiter.rb +3 -3
  6. data/lib/rookout/augs/augs_manager.rb +3 -1
  7. data/lib/rookout/augs/conditions/condition.rb +4 -2
  8. data/lib/rookout/augs/locations/location.rb +75 -1
  9. data/lib/rookout/augs/locations/location_exception_handler.rb +22 -0
  10. data/lib/rookout/augs/locations/location_file_line.rb +16 -4
  11. data/lib/rookout/com_ws/agent_com_ws.rb +28 -33
  12. data/lib/rookout/com_ws/information.rb +1 -1
  13. data/lib/rookout/com_ws/output.rb +4 -10
  14. data/lib/rookout/com_ws/pinger.rb +36 -0
  15. data/lib/rookout/com_ws/websocket_client.rb +143 -0
  16. data/lib/rookout/commit.rb +3 -0
  17. data/lib/rookout/config.rb +1 -0
  18. data/lib/rookout/exceptions.rb +40 -0
  19. data/lib/rookout/interface.rb +41 -24
  20. data/lib/rookout/logger.rb +16 -2
  21. data/lib/rookout/processor/namespace_serializer.rb +1 -1
  22. data/lib/rookout/processor/namespaces/frame_namespace.rb +1 -0
  23. data/lib/rookout/processor/namespaces/namespace.rb +2 -2
  24. data/lib/rookout/processor/namespaces/noop_namespace.rb +1 -1
  25. data/lib/rookout/processor/namespaces/ruby_object_serializer.rb +4 -3
  26. data/lib/rookout/processor/operations/set_operation.rb +4 -1
  27. data/lib/rookout/processor/paths/arithmetic_path.rb +1 -1
  28. data/lib/rookout/processor/paths/canopy/markers.rb +5 -2
  29. data/lib/rookout/rookout_singleton.rb +4 -3
  30. data/lib/rookout/services/position.rb +73 -73
  31. data/lib/rookout/services/tracer.rb +8 -5
  32. data/lib/rookout/trigger_services.rb +2 -2
  33. data/lib/rookout/user_warnings.rb +2 -0
  34. data/lib/rookout/utils.rb +9 -0
  35. data/lib/rookout/version.rb +1 -2
  36. metadata +37 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 17eda3a68e52adf758e353e65066c8e68e65c5df18e67299c95e111a60717260
4
- data.tar.gz: fd7cadcf2f2890130e9d92c6f56312c7c1a6bf1ad55efc84a83c39ad67f68020
3
+ metadata.gz: a651effede1b4bb60cf30bcc0ad23adac929ebb41ac69e0e059acc988542defc
4
+ data.tar.gz: dd89562cd624e99ee1dbac58a9f045ee49175ccf12b9341df5cd0fbae1122774
5
5
  SHA512:
6
- metadata.gz: c1968166a99e6c85d7476de449bea06d7105bd9b0b71681c8c4263ccc33d88440e2a956a1d29d4681db44af1d6a8ea5e1cfb142895c182bb1388868c6f920035
7
- data.tar.gz: f805c321af5605bade4d443557b3c575d7f432afa392820c4589bc8023af8a971e7a7d72f851ff2899ae7c4aca5fd3864f4e35dd0fb5e942cc4c3e570402cbdc
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, _output
18
+ def execute aug_id, report_id, namespace, output
19
19
  @processor.process namespace
20
- @output.send_user_message aug_id, report_id, namespace.read_attribute("store")
20
+ output.send_user_message aug_id, report_id, namespace.read_attribute("store")
21
21
  return unless @post_processor
22
22
 
23
- @output.flush_message
23
+ output.flush_message
24
24
  @post_processor.process namespace
25
25
  end
26
26
  end
@@ -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
- require "securerandom"
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, location, action, condition, rate_limiter, _max_aug_time, output
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
- def execute frame, extracted
50
- return unless @enabled
25
+ attr_reader :id
51
26
 
52
- UserWarnings.with self do
53
- begin
54
- namespace = create_namespaces frame, extracted
27
+ def execute frame, extracted, output
28
+ return unless @enabled
55
29
 
56
- return if @condition && !@condition.evaluate(namespace)
30
+ namespace = create_namespaces frame, extracted
31
+ return if @condition && !@condition.evaluate(namespace)
57
32
 
58
- @rate_limiter.with_limit do
59
- report_id = SecureRandom.uuid
60
- @action.execute @aug_id, report_id, namespace, @output
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
- def notify_error error
85
- send_rule_status :Error, error
86
- end
87
-
88
- def notify_warning error
89
- return if silence_log? error
90
- send_rule_status :Warning, error
91
- end
92
-
93
- private
94
-
95
- def create_namespaces frame, extracted
96
- ContainerNamespace.new("frame": Processor::Namespaces::FrameNamespace.new(frame[1]),
97
- "stack": Processor::Namespaces::StackNamespace.new(frame, 1),
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.RookAugInvalidKey "id", configuration unless aug_id.is_a? String
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.RookAugInvalidKey "action", configuration unless action_configuration.is_a? Hash
27
- action = Actions.ActionRunProcess.new action_configuration, @factory
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.INSTRUMENTATION_MAX_AUG_TIME
28
+ max_aug_time = configuration["maxAugTime"] || Config.instrumentation_max_aug_time
30
29
 
31
30
  condition_configuration = configuration["conditional"]
32
- raise Exceptions.RookAugInvalidKey "conditional", configuration unless condition_configuration.is_a? String
33
- condition = Conditions.Condition.new condition_configuration
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, location, action, condition, rate_limit, max_aug_time, @output
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
- Locations.LocationFileLine.new configuration, @factory
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.new
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 = (now * 1000).to_i
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] += max(duration, 5).to_f
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).object == true
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 add_aug _trigger_services, _aug
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, _processor_factory
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"] != 0
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, aug
21
- trigger_services.get_service("position").add_aug self, aug
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