rookout 0.1.52 → 0.1.54

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8854b65da599e09232b62dadbe87cb092dccd93e2a3153dae13e5aa703fcd4e0
4
- data.tar.gz: 8fb0f255e23b6eac93f293632a4230e7b24fa80fcdd49d0288d78582ebd121e0
3
+ metadata.gz: e96a2d7b2fdc74a8731a9c547940f6c03a1bf2ee103ed433a65fdac6bff90e40
4
+ data.tar.gz: 21bdac9616f7b5f7bcbcf781fdb2df81ff8ad7bfb0413ed96dea91565df61652
5
5
  SHA512:
6
- metadata.gz: a0008b3f484e1967418b7cd8bd9db5b8550658a1eb211b5f1ce6f6e731a9fca6733361fd03413f1904dd2aebea889be20418b5fcde963ffd14d116290e8421cf
7
- data.tar.gz: 3d2282c21829a747f961e6063435433aa19e88be46ae3f572c8239355ef6dfda585fd12c8d12c4b401d427d7fd0f9040c744b0c27a673b2d9a87a0ac6705ca56
6
+ metadata.gz: 9886ef4e56f478fa227a5a50281179df07b2dc3aa28573d815969b2a57e0935b8b783ebe2738dee480de5eb559b28f5ab8f51357af3d21a50b3e3a2a95fcb7f6
7
+ data.tar.gz: 65e7aa8a863b61994278f58540b95c27166543141145545f463cf2f0bd9a2cc989de3cdd6449353110659cca7558dd892214901008f862fcf3716d2da1c0af3f
@@ -24,7 +24,7 @@ module Rookout
24
24
 
25
25
  attr_reader :id
26
26
 
27
- def execute frame, extracted, output
27
+ def execute frame_binding, stack_trace, extracted, output
28
28
  return unless @enabled
29
29
 
30
30
  if output.user_messages_queue_full?
@@ -32,7 +32,7 @@ module Rookout
32
32
  return
33
33
  end
34
34
 
35
- namespace = create_namespaces frame, extracted
35
+ namespace = create_namespaces frame_binding, stack_trace, extracted
36
36
  return if @condition && !@condition.evaluate(namespace)
37
37
 
38
38
  should_skip_limiters = @condition.nil? && !@executed
@@ -46,10 +46,10 @@ module Rookout
46
46
 
47
47
  private
48
48
 
49
- def create_namespaces frame, extracted
49
+ def create_namespaces frame_binding, stack_trace, extracted
50
50
  Processor::Namespaces::ContainerNamespace.new(
51
- "frame" => Processor::Namespaces::FrameNamespace.new(frame[1]),
52
- "stack" => Processor::Namespaces::StackNamespace.new(frame, 1),
51
+ "frame" => Processor::Namespaces::FrameNamespace.new(frame_binding, stack_trace[0]),
52
+ "stack" => Processor::Namespaces::StackNamespace.new(stack_trace),
53
53
  "extracted" => Processor::Namespaces::ContainerNamespace.new(extracted),
54
54
  "store" => Processor::Namespaces::ContainerNamespace.new,
55
55
  "temp" => Processor::Namespaces::ContainerNamespace.new,
@@ -20,10 +20,10 @@ module Rookout
20
20
  @aug.id
21
21
  end
22
22
 
23
- def execute frame, extracted
23
+ def execute frame_binding, stack_trace, extracted
24
24
  UserWarnings.with self do
25
25
  begin
26
- @aug.execute frame, extracted, @output
26
+ @aug.execute frame_binding, stack_trace, extracted, @output
27
27
  rescue SystemExit
28
28
  raise
29
29
  rescue Exception => e
@@ -130,6 +130,11 @@ module Rookout
130
130
  @ready_event.set
131
131
  end
132
132
 
133
+ if e.message.include? "400"
134
+ @connection_error = Exceptions::RookWebSocketError.new 400
135
+ @ready_event.set
136
+ end
137
+
133
138
  Logger.instance.warning "Connection failed; reason = #{e.message}"
134
139
  end
135
140
 
@@ -85,10 +85,40 @@ module Rookout
85
85
  return_value
86
86
  end
87
87
 
88
+ def parse_raw_git_sources
89
+ git_sources_raw = ENV["ROOKOUT_SOURCES"]
90
+ if git_sources_raw.nil?
91
+ return nil
92
+ end
93
+
94
+ git_sources = git_sources_raw.split ";"
95
+ user_git_sources = {}
96
+ git_sources.each do |url|
97
+ url_parts = url.split "#"
98
+ if url_parts.length != 2
99
+ next
100
+ end
101
+
102
+ remote_url = url_parts[0]
103
+ commit = url_parts[1]
104
+ user_git_sources[remote_url] = commit
105
+ end
106
+
107
+ user_git_sources
108
+ end
109
+
88
110
  def create_scm_information
89
111
  user_git_origin = Config.user_git_origin || ENV["ROOKOUT_REMOTE_ORIGIN"]
90
112
  user_git_commit = Config.user_git_commit || ENV["ROOKOUT_COMMIT"]
91
113
 
114
+ user_git_sources = Config.user_git_sources || parse_raw_git_sources
115
+
116
+ if !user_git_sources.nil? && !user_git_sources.empty?
117
+ user_git_sources = user_git_sources.map do |remote_url, commit|
118
+ Com::Rookout::SCMInformation::SourceInfo.new remoteOriginUrl: remote_url, commit: commit
119
+ end
120
+ end
121
+
92
122
  if user_git_origin.nil? && user_git_commit.nil?
93
123
  search_path = File.dirname File.absolute_path($PROGRAM_NAME)
94
124
  git_root = find_root search_path
@@ -98,7 +128,7 @@ module Rookout
98
128
  end
99
129
  end
100
130
 
101
- Com::Rookout::SCMInformation.new origin: user_git_origin, commit: user_git_commit
131
+ Com::Rookout::SCMInformation.new origin: user_git_origin, commit: user_git_commit, sources: user_git_sources
102
132
  end
103
133
 
104
134
  def aws_lambda?
@@ -1,3 +1,3 @@
1
1
  module Rookout
2
- COMMIT = "3e5cbb5882385eff12a3113f93dfde79418d5061".freeze
2
+ COMMIT = "9db1dfad4593de7df40d98fba0722f8778ef7528".freeze
3
3
  end
@@ -60,9 +60,11 @@ module Rookout
60
60
 
61
61
  attr_accessor :user_git_commit
62
62
  attr_accessor :user_git_origin
63
+ attr_accessor :user_git_sources
63
64
 
64
65
  Rookout::Config.user_git_commit = nil
65
66
  Rookout::Config.user_git_origin = nil
67
+ Rookout::Config.user_git_sources = nil
66
68
 
67
69
  attr_accessor :rookout_version
68
70
  attr_accessor :rookout_commit
@@ -132,6 +132,13 @@ module Rookout
132
132
  end
133
133
  end
134
134
 
135
+ class RookWebSocketError < ToolException
136
+ def initialize http_status
137
+ super "Received HTTP status #{http_status} from the controller," \
138
+ "Please make sure WebSocket is enabled on the load balancer."
139
+ end
140
+ end
141
+
135
142
  class RookSourceFilePathSuggestion < ToolException
136
143
  def initialize wanted_path, matching_path
137
144
  super "Rookout found alternative file path: #{matching_path}",
@@ -258,5 +265,11 @@ module Rookout
258
265
  super "Live Logger is not supported. Try using Rookout Live Debugger instead."
259
266
  end
260
267
  end
268
+
269
+ class RookLocalsUnavailable < ToolException
270
+ def initialize
271
+ super "Can't collect local variables up the stack"
272
+ end
273
+ end
261
274
  end
262
275
  end
@@ -39,7 +39,8 @@ module Rookout
39
39
  raise if throw_errors
40
40
  $stderr.puts "[Rookout] Failed to load Rookout. Please make sure to force build native extensions by setting" \
41
41
  "'bundle config force_ruby_platform true'"
42
- rescue RookMissingToken, RookInvalidToken, RookInvalidOptions, RookVersionNotSupported, RookBadProtobuf => e
42
+ rescue RookMissingToken, RookInvalidToken, RookInvalidOptions,
43
+ RookVersionNotSupported, RookBadProtobuf, RookWebSocketError => e
43
44
  raise if throw_errors
44
45
  $stderr.puts "[Rookout] Failed to start Rookout: #{e.message}"
45
46
  rescue RookCommunicationException => e
@@ -92,6 +93,12 @@ module Rookout
92
93
  $stderr.puts error.message
93
94
  end
94
95
 
96
+ def configure_scm options
97
+ Config.user_git_origin = options[:git_origin] if options[:git_origin]
98
+ Config.user_git_commit = options[:git_commit] if options[:git_commit]
99
+ Config.user_git_sources = options[:git_sources] if options[:git_sources] && options[:git_sources].is_a?(Hash)
100
+ end
101
+
95
102
  def configure_globals options
96
103
  if Config.debug
97
104
  log_to_stderr = true
@@ -107,8 +114,7 @@ module Rookout
107
114
  Config.logger_filename = log_file unless log_file.nil?
108
115
  Config.logger_log_level = log_level unless log_level.nil?
109
116
 
110
- Config.user_git_origin = options[:git_origin] if options[:git_origin]
111
- Config.user_git_commit = options[:git_commit] if options[:git_commit]
117
+ configure_scm options
112
118
  end
113
119
 
114
120
  def configure_start_options options
@@ -314,12 +314,12 @@ module Rookout
314
314
 
315
315
  namespace.depth.times do |i|
316
316
  position = i + namespace.offset
317
- break if position >= namespace.backtrace.length
318
- frame = namespace.backtrace[position]
317
+ break if position >= namespace.stack_trace.length
318
+ frame_info = namespace.stack_trace[position]
319
319
 
320
- code_object = Com::Rookout::Variant::CodeObject.new filename: frame.source_location[0],
321
- lineno: frame.source_location[1],
322
- name: frame.eval("__method__").to_s
320
+ code_object = Com::Rookout::Variant::CodeObject.new filename: frame_info.path,
321
+ lineno: frame_info.lineno,
322
+ name: frame_info.label
323
323
  variant.code_values << code_object
324
324
  # See dump_code_object
325
325
  @estimated_pending_bytes += 14 # Header + size + (header + number) * 4
@@ -7,33 +7,35 @@ module Rookout
7
7
  require_relative "../../exceptions"
8
8
 
9
9
  class FrameNamespace < Namespace
10
- def initialize binding
10
+ def initialize frame_binding, top_frame_info
11
11
  super()
12
- @binding = binding
12
+ @frame_binding = frame_binding
13
+ @top_frame_info = top_frame_info
13
14
  end
14
15
 
15
16
  def read_attribute name
16
- return RubyObjectNamespace.new @binding.receiver if name == "self"
17
- raise Exceptions::RookAttributeNotFound, name unless @binding.local_variable_defined? name
18
- RubyObjectNamespace.new @binding.local_variable_get name
17
+ raise Exceptions::RookLocalsUnavailable if @frame_binding.nil?
18
+ return RubyObjectNamespace.new @frame_binding.receiver if name == "self"
19
+ raise Exceptions::RookAttributeNotFound, name unless @frame_binding.local_variable_defined? name
20
+ RubyObjectNamespace.new @frame_binding.local_variable_get name
19
21
  end
20
22
 
21
23
  def call_method name, args
22
24
  case name
23
25
  when "filename", "module"
24
- RubyObjectNamespace.new @binding.source_location[0]
26
+ RubyObjectNamespace.new @top_frame_info.path
25
27
  when "line"
26
- RubyObjectNamespace.new @binding.source_location[1]
28
+ RubyObjectNamespace.new @top_frame_info.lineno
27
29
  when "function"
28
- RubyObjectNamespace.new @binding.eval("__method__").to_s
30
+ RubyObjectNamespace.new @top_frame_info.label
29
31
  when "locals"
30
32
  locals args
31
33
  when "dump"
32
34
  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]),
35
+ "filename" => RubyObjectNamespace.new(@top_frame_info.path),
36
+ "line" => RubyObjectNamespace.new(@top_frame_info.lineno),
37
+ "function" => RubyObjectNamespace.new(@top_frame_info.label),
38
+ "module" => RubyObjectNamespace.new(@top_frame_info.path),
37
39
  "locals" => locals(args)
38
40
  }
39
41
  ContainerNamespace.new result
@@ -43,19 +45,20 @@ module Rookout
43
45
  end
44
46
 
45
47
  def locals args
48
+ raise Exceptions::RookLocalsUnavailable if @frame_binding.nil?
46
49
  dump_config = nil
47
50
  unless args.nil?
48
51
  dump_config = OBJECT_DUMP_TABLE[args.downcase]
49
52
  end
50
53
 
51
54
  hash = {}
52
- local_variables = @binding.local_variables
55
+ local_variables = @frame_binding.local_variables
53
56
  local_variables.each do |var|
54
- value = @binding.local_variable_get var
57
+ value = @frame_binding.local_variable_get var
55
58
  hash[var.to_s] = RubyObjectNamespace.new value, dump_config
56
59
  end
57
60
 
58
- hash["self"] = RubyObjectNamespace.new @binding.receiver, dump_config
61
+ hash["self"] = RubyObjectNamespace.new @frame_binding.receiver, dump_config
59
62
 
60
63
  ContainerNamespace.new hash
61
64
  end
@@ -5,15 +5,16 @@ module Rookout
5
5
  require_relative "frame_namespace"
6
6
  require_relative "traceback_namespace"
7
7
 
8
+
8
9
  class StackNamespace < Namespace
9
- def initialize backtrace, offset = 0
10
+ def initialize stack_trace, offset = 0
10
11
  super()
11
- @backtrace = backtrace
12
+ @stack_trace = stack_trace
12
13
  @offset = offset
13
14
  end
14
15
 
15
16
  def read_key key
16
- FrameNamespace.new @backtrace[key + @offset]
17
+ FrameNamespace.new nil, @stack_trace[key + @offset]
17
18
  end
18
19
 
19
20
  def call_method name, args
@@ -23,7 +24,7 @@ module Rookout
23
24
 
24
25
  def create_traceback args
25
26
  args = 1000 if args == ""
26
- TracebackNamespace.new @backtrace, @offset, args.to_i
27
+ TracebackNamespace.new @stack_trace, @offset, args.to_i
27
28
  end
28
29
  end
29
30
  end
@@ -3,23 +3,22 @@ module Rookout
3
3
  module Namespaces
4
4
  require_relative "namespace"
5
5
  require_relative "frame_namespace"
6
-
7
6
  require_relative "../../protobuf/variant_pb"
8
7
 
9
8
  class TracebackNamespace < Namespace
10
- def initialize backtrace, offset, depth
9
+ def initialize stack_trace, offset, depth
11
10
  super()
12
- @backtrace = backtrace
11
+ @stack_trace = stack_trace
13
12
  @offset = offset
14
13
  @depth = depth
15
14
  end
16
15
 
17
- attr_reader :backtrace
16
+ attr_reader :stack_trace
18
17
  attr_reader :offset
19
18
  attr_reader :depth
20
19
 
21
20
  def read_key key
22
- FrameNamespace.new @backtrace[key + @offset]
21
+ FrameNamespace.new nil, @stack_trace[key + @offset]
23
22
  end
24
23
 
25
24
  def dump _log_object_errors
@@ -27,12 +26,12 @@ module Rookout
27
26
 
28
27
  @depth.times do |i|
29
28
  position = i + @offset
30
- break if position >= @backtrace.length
31
- frame = @backtrace[position]
29
+ break if position >= @stack_trace.length
30
+ frame_info = @stack_trace[position]
32
31
 
33
- code_object = Com::Rookout::Variant::CodeObject.new filename: frame.source_location[0],
34
- lineno: frame.source_location[1],
35
- name: frame.eval("__method__").to_s
32
+ code_object = Com::Rookout::Variant::CodeObject.new filename: frame_info.path,
33
+ lineno: frame_info.lineno,
34
+ name: frame_info.label
36
35
 
37
36
  traceback.locations << code_object
38
37
  end
@@ -14,7 +14,7 @@ module Rookout
14
14
  def self.sanitize_properties!
15
15
  ENV.each do |key, val|
16
16
  if key.start_with?("ROOKOUT_") && !@@blacklisted_properties.include?(key.to_s)
17
- ENV[key] = val.strip
17
+ ENV[key] = val.strip.delete_suffix("/")
18
18
  end
19
19
  end
20
20
  end
@@ -3,9 +3,6 @@ module Rookout
3
3
  require_relative "../logger"
4
4
 
5
5
  class Tracer
6
- require "binding_of_caller"
7
- include BindingOfCaller::BindingExtensions
8
-
9
6
  def initialize
10
7
  @trace_points = {}
11
8
  @augs = {}
@@ -17,22 +14,25 @@ module Rookout
17
14
  aug_trace_points = []
18
15
  positions.each do |position|
19
16
  trace_point = create_trace_point aug
20
-
21
17
  begin
22
18
  trace_point.enable target: position.method, target_line: position.lineno
23
19
  rescue RuntimeError, ArgumentError => e
20
+ trace_point.disable # just to make sure if something was partially added to clear everything
24
21
  if e.message.include? "can not enable any hooks"
25
22
  raise Exceptions::RookInvalidPositionException.new(aug.filename, position.lineno)
26
23
  end
27
24
  raise Exceptions::RookSetTracepointFailed.new(position.lineno, e)
25
+ ensure
26
+ # We add and remove a dummy trace point to re-align the tracing mechanism as a result of some bug in adding
27
+ # a breakpoint https://bugs.ruby-lang.org/issues/17302
28
+ begin
29
+ dummy_trace_point = TracePoint.new(:line) {} # Dummy
30
+ dummy_trace_point.enable target: position.method, target_line: position.lineno
31
+ dummy_trace_point.disable
32
+ rescue
33
+ # IGNORE
34
+ end
28
35
  end
29
-
30
- # We add and remove a dummy trace point to re-align the tracing mechanism as a result of some bug in adding
31
- # a breakpoint
32
- dummy_trace_point = TracePoint.new(:line) {} # Dummy
33
- dummy_trace_point.enable target: position.method, target_line: position.lineno
34
- dummy_trace_point.disable
35
-
36
36
  aug_trace_points.push trace_point
37
37
  end
38
38
 
@@ -71,11 +71,19 @@ module Rookout
71
71
  private
72
72
 
73
73
  def create_trace_point aug
74
- TracePoint.new :line do
74
+ TracePoint.new :line do |tp|
75
75
  begin
76
76
  begin
77
- # TODO: consider delaying callers (get bindings) until we actually need them in Aug.rb
78
- aug.execute callers, nil
77
+ # tp.binding - Binding object of the frame in the location that triggered the TracePoint.
78
+ # This allows us to collect locals.
79
+ # caller_locations - returns the stacktrace. Allows us to collect files, lines and function names.
80
+ # We used to also collect the Bindings up the stack (allowed us to also collect locals up the stack),
81
+ # but we don't actually need that. If we'll ever need this functionality again, we'll have to use the
82
+ # binding_of_caller gem:
83
+ # require "binding_of_caller"
84
+ # include BindingOfCaller::BindingExtensions
85
+ # callers_bindings = callers - The "callers" function retrieves the bindings up the stack
86
+ aug.execute tp.binding, caller_locations, nil
79
87
  rescue Exception => e
80
88
  Logger.instance.exception "Exception calling aug", e
81
89
  end
@@ -1,3 +1,3 @@
1
1
  module Rookout
2
- VERSION = "0.1.52".freeze
2
+ VERSION = "0.1.54".freeze
3
3
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rookout
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.52
4
+ version: 0.1.54
5
5
  platform: ruby
6
6
  authors:
7
7
  - Liran Haimovitch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-26 00:00:00.000000000 Z
11
+ date: 2023-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: binding_of_caller
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0.7'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0.7'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: concurrent-ruby
29
15
  requirement: !ruby/object:Gem::Requirement