rookout 0.1.2 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 559c0c4b76d3815a418977ebe848a66f9640128be5a900286afedbf658a26e1e
4
- data.tar.gz: dfeb5ba84b8b6665de0b0c1e5dec2fe687c3cb420485664f4d626bbb24213c7a
3
+ metadata.gz: 0e078b8f3c64dbe7a289ead5d7a50abbaf002dc0b0148bc96dd05c04cd95c549
4
+ data.tar.gz: 62854fbcaeb3756e2e7d23241ae62f1372a3c9157e27be0e8425eb7bbd9b0db8
5
5
  SHA512:
6
- metadata.gz: d83bee904b048be0d9d4c221b2e5c797fa61a24a0dd43666b7211b8a5df917581aab351874cc819de11c853e08044454625d75d59594b197f8792d61e84f6d3c
7
- data.tar.gz: e59f969f44d7f8311dbb96c7724be58900b45d294ce868742baf468856cbeba9219b14e67a32985619e98af895676df0fcc89ac6828fd89ac75b66d0d04f084b
6
+ metadata.gz: 291fbf595b9000be2260adfd5a3fc4f5dbdcaf59b5fd3c66517d38a87f06c4371e91ce888ab130e57937cbeeeac39c9b5cc5bef62ea09a619c57abb8325eae89
7
+ data.tar.gz: beca8ae64522885a42c300685c16385b1b1b5f16925cf725b37bd9c5cb8363bc37aab76de7424d886c66a3da347d9f6d9fa20405cc7f6d3ea14573d03813b134
@@ -0,0 +1,73 @@
1
+ module Rookout
2
+ class ForkManager
3
+ require "singleton"
4
+ include Singleton
5
+
6
+ def initialize
7
+ @active = false
8
+ end
9
+
10
+ def activate!
11
+ @active = true
12
+ end
13
+
14
+ def disable!
15
+ @active = false
16
+ end
17
+
18
+ def active?
19
+ @active
20
+ end
21
+
22
+ def fork_hook original_fork
23
+ if block_given?
24
+ original_fork.call do
25
+ post_fork_child if active?
26
+ yield
27
+ end
28
+ else
29
+ res = original_fork.call
30
+ post_fork_child if active? && !res
31
+ res
32
+ end
33
+ end
34
+
35
+ def post_fork_child
36
+ require_relative "rookout_singleton"
37
+ require_relative "interface"
38
+
39
+ RookoutSingleton.instance.post_fork_clean
40
+ Interface.instance.stop
41
+ Interface.instance.start post_fork: true
42
+
43
+ # Disable fork handler in child process
44
+ disable!
45
+ end
46
+ end
47
+ end
48
+
49
+ alias _rookout_original_fork fork
50
+
51
+ def self.fork &block
52
+ Rookout::ForkManager.instance.fork_hook method(:_rookout_original_fork), &block
53
+ end
54
+
55
+ def fork &block
56
+ Rookout::ForkManager.instance.fork_hook method(:_rookout_original_fork), &block
57
+ end
58
+
59
+ module Kernel
60
+ alias _rookout_original_fork fork
61
+
62
+ def self.fork &block
63
+ Rookout::ForkManager.instance.fork_hook method(:_rookout_original_fork), &block
64
+ end
65
+ end
66
+
67
+ module Process
68
+ alias _rookout_original_fork fork
69
+
70
+ def self.fork &block
71
+ Rookout::ForkManager.instance.fork_hook method(:_rookout_original_fork), &block
72
+ end
73
+ end
@@ -46,7 +46,8 @@ module Rookout
46
46
  "store" => Processor::Namespaces::ContainerNamespace.new,
47
47
  "temp" => Processor::Namespaces::ContainerNamespace.new,
48
48
  "utils" => Processor::Namespaces::RubyUtilsNamespace.new,
49
- "trace" => Processor::Namespaces::NoopNamespace.new
49
+ "trace" => Processor::Namespaces::NoopNamespace.new,
50
+ "state" => Processor::Namespaces::NoopNamespace.new
50
51
  )
51
52
  end
52
53
  end
@@ -7,6 +7,7 @@ module Rookout
7
7
  require_relative "actions/action_run_processor"
8
8
  require_relative "conditions/condition"
9
9
  require_relative "locations/location_file_line"
10
+ require_relative "locations/location_exception_handler"
10
11
  require_relative "aug_rate_limiter"
11
12
  require_relative "aug"
12
13
 
@@ -45,9 +46,15 @@ module Rookout
45
46
  def create_location configuration, aug
46
47
  name = configuration["name"]
47
48
  raise Exceptions.RookObjectNameMissing if name.nil?
48
- raise Exceptions.RookUnsupportedLocation if name != "file_line"
49
49
 
50
- Locations::LocationFileLine.new configuration, @output, aug
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
51
58
  end
52
59
 
53
60
  def create_rate_limit configuration
@@ -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
@@ -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
@@ -39,7 +39,8 @@ module Rookout
39
39
  @info = Information.new labels
40
40
  reset_id
41
41
 
42
- @thread = nil
42
+ @main_thread = nil
43
+ @outgoing_thread = nil
43
44
  @pending_messages = Queue.new
44
45
 
45
46
  @running = false
@@ -64,8 +65,17 @@ module Rookout
64
65
  def connect
65
66
  @running = true
66
67
 
67
- @thread = Thread.new { connection_thread }
68
- @thread.name = "rookout-connection-thread"
68
+ @main_thread = Thread.new { connection_thread }
69
+ @main_thread.name = "rookout-connection-thread"
70
+ end
71
+
72
+ def stop
73
+ @running = false
74
+
75
+ # Ask outgoing thread to exit (if running)
76
+ @pending_messages << ExitMessage.new(@outgoing_thread)
77
+
78
+ @main_thread.join
69
79
  end
70
80
 
71
81
  def wait_for_ready
@@ -133,8 +143,8 @@ module Rookout
133
143
 
134
144
  def connection_pump client
135
145
  on_outgoing_exit = proc { client.close }
136
- send_thread = Thread.new { outgoing client, on_outgoing_exit }
137
- send_thread.name = "rookout-outgoing-thread"
146
+ @outgoing_thread = Thread.new { outgoing client, on_outgoing_exit }
147
+ @outgoing_thread.name = "rookout-outgoing-thread"
138
148
 
139
149
  message_handler = proc do |raw_message|
140
150
  envelope = Com::Rookout::Envelope.decode raw_message.pack("c*")
@@ -150,7 +160,8 @@ module Rookout
150
160
  Logger.instance.debug "Incoming loop - socket disconnected"
151
161
 
152
162
  @pending_messages.push ExitMessage.new(send_thread)
153
- send_thread.join
163
+ @outgoing_thread.join
164
+ @outgoing_thread = nil
154
165
  end
155
166
 
156
167
  def outgoing client, on_exit
@@ -57,19 +57,13 @@ module Rookout
57
57
  return if @closing || !@agent_com
58
58
 
59
59
  @rule_status_update_bucket.if_available do
60
- protobuf_error = nil
60
+ status = Com::Rookout::RuleStatusMessage.new agent_id: @agent_id,
61
+ rule_id: rule_id,
62
+ active: active
61
63
  if error
62
- protobuf_error = Com::Rookout::Error.new message: error.message,
63
- type: error.type
64
- protobuf_error.parameters.copy_from error.parameters
65
- protobuf_error.exc.copy_from error.exc
66
- protobuf_error.traceback.copy_from error.traceback
64
+ status.error = error.dumps
67
65
  end
68
66
 
69
- status = Com::Rookout::RuleStatusMessage.new agent_id: @agent_id,
70
- rule_id: rule_id,
71
- active: active,
72
- error: protobuf_error
73
67
  @agent_com.add status
74
68
  end
75
69
  end
@@ -9,6 +9,7 @@ module Rookout
9
9
 
10
10
  def initialize
11
11
  @rook = nil
12
+ @start_options = nil
12
13
  end
13
14
 
14
15
  def start options = {}
@@ -19,14 +20,20 @@ module Rookout
19
20
  begin
20
21
  require_relative "rookout_singleton"
21
22
 
22
- configure_logging options
23
- configure_git options
23
+ # If we are running post fork, use previous start_options
24
+ if options[:post_fork]
25
+ # Don't re-enable the fork handler
26
+ @start_options[:fork] = false
27
+ else
28
+ configure_logging options
29
+ configure_git options
24
30
 
25
- start_options = configure_start_options options
26
- print_config start_options
31
+ @start_options = configure_start_options options
32
+ print_config @start_options
33
+ end
27
34
 
28
35
  rook = RookoutSingleton.instance
29
- rook.connect(**start_options)
36
+ rook.connect(**@start_options)
30
37
  rescue RookMissingToken, RookInvalidToken, RookInvalidOptions, RookVersionNotSupported => e
31
38
  raise if throw_errors
32
39
  STDERR.puts "[Rookout] Failed to start Rookout: #{e.message}"
@@ -84,7 +91,7 @@ module Rookout
84
91
  raise RookMissingToken if token.nil? && host == "wss://control.rookout.com"
85
92
  verify_token token if token
86
93
 
87
- labels = options[:labels] || parse_labels(ENV["ROOKOUT_LABELS"])
94
+ labels = stringify_labels(options[:labels]) || parse_labels(ENV["ROOKOUT_LABELS"])
88
95
  validate_labels labels
89
96
 
90
97
  async_start = true? ENV["ROOKOUT_ASYNC_START"]
@@ -108,6 +115,18 @@ module Rookout
108
115
  default
109
116
  end
110
117
 
118
+ def stringify_labels labels
119
+ return nil unless labels
120
+
121
+ stringified_labels = {}
122
+
123
+ labels.each do |label_name, label_value|
124
+ stringified_labels[label_name.to_s] = label_value.to_s
125
+ end
126
+
127
+ stringified_labels
128
+ end
129
+
111
130
  def parse_labels raw_labels
112
131
  labels = {}
113
132
  return labels if raw_labels.nil?
@@ -12,6 +12,7 @@ module Rookout
12
12
  end
13
13
 
14
14
  def read_attribute name
15
+ return RubyObjectNamespace.new @binding.receiver if name == "self"
15
16
  raise Exceptions::RookAttributeNotFound, name unless @binding.local_variable_defined? name
16
17
  RubyObjectNamespace.new @binding.local_variable_get name
17
18
  end
@@ -123,6 +123,7 @@ module Rookout
123
123
  end
124
124
 
125
125
  def dump_string obj, variant, config
126
+ obj = obj.to_s
126
127
  if obj.length > config.max_string
127
128
  final_obj = obj[0...config.max_string]
128
129
  else
@@ -40,9 +40,14 @@ module Rookout
40
40
  @services_started = false
41
41
  end
42
42
 
43
- def connect token: nil, host: nil, port: nil, proxy: nil, labels: [], async_start: false, **_
43
+ def connect token: nil, host: nil, port: nil, proxy: nil, labels: [], async_start: false, fork: false
44
44
  raise Exceptions::RookInterfaceException, "Multiple connection attempts not supported!" unless @agent_com.nil?
45
45
 
46
+ if fork
47
+ require_relative "atfork"
48
+ Rookout::ForkManager.instance.activate!
49
+ end
50
+
46
51
  start_trigger_services
47
52
 
48
53
  Logger.instance.debug "Initiating AgentCom-\t#{host}:#{port}"
@@ -61,6 +66,16 @@ module Rookout
61
66
  @output.flush_messages if !@output.nil && !@agent_com.nil?
62
67
  end
63
68
 
69
+ def post_fork_clean
70
+ @agent_com.stop
71
+ @agent_com = nil
72
+
73
+ @command_handler = nil
74
+
75
+ # We don't disable services because we will lose all loaded scripts
76
+ @services.clear_augs
77
+ end
78
+
64
79
  attr_reader :services
65
80
 
66
81
  private
@@ -18,14 +18,14 @@ module Rookout
18
18
  def initialize tracer
19
19
  @tracer = tracer
20
20
  @augs = {}
21
- @iseqs = {}
21
+ @iseqs = []
22
22
  @trace_point = TracePoint.new :script_compiled do |tp|
23
23
  begin
24
24
  begin
25
25
  iseq = tp.instruction_sequence
26
26
  # Ignore script without sources
27
27
  if iseq.absolute_path
28
- @iseqs[tp.path] = iseq
28
+ @iseqs << iseq
29
29
  evaluate_script iseq
30
30
  end
31
31
  rescue Exception => e
@@ -83,7 +83,7 @@ module Rookout
83
83
 
84
84
  def evaluate_all_scripts_to_location location
85
85
  positions = []
86
- @iseqs.each_value do |iseq|
86
+ @iseqs.each do |iseq|
87
87
  position = evaluate_script_to_location iseq, iseq.absolute_path, location
88
88
  next if position.nil?
89
89
 
@@ -98,7 +98,7 @@ module Rookout
98
98
  lineno = find_updated_line filename, location
99
99
  return if lineno == -1
100
100
 
101
- PositionMarker.new location.lineno, iseq
101
+ PositionMarker.new lineno, iseq
102
102
  elsif suggested_match? location, filename
103
103
  warning = Exceptions::RookSourceFilePathSuggestion.new location.filename, filename
104
104
  location.notify_warning warning
@@ -1,3 +1,3 @@
1
1
  module Rookout
2
- VERSION = "0.1.2".freeze
2
+ VERSION = "0.1.7".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rookout
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Liran Haimovitch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-07 00:00:00.000000000 Z
11
+ date: 2020-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: binding_of_caller
@@ -189,6 +189,7 @@ files:
189
189
  - LICENSE
190
190
  - bin/rookout
191
191
  - lib/rookout.rb
192
+ - lib/rookout/atfork.rb
192
193
  - lib/rookout/augs/actions/action.rb
193
194
  - lib/rookout/augs/actions/action_run_processor.rb
194
195
  - lib/rookout/augs/aug.rb
@@ -197,6 +198,7 @@ files:
197
198
  - lib/rookout/augs/augs_manager.rb
198
199
  - lib/rookout/augs/conditions/condition.rb
199
200
  - lib/rookout/augs/locations/location.rb
201
+ - lib/rookout/augs/locations/location_exception_handler.rb
200
202
  - lib/rookout/augs/locations/location_file_line.rb
201
203
  - lib/rookout/com_ws/agent_com_ws.rb
202
204
  - lib/rookout/com_ws/backoff.rb