rookout 0.1.0 → 0.1.56
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/atfork.rb +73 -0
- data/lib/rookout/augs/actions/action_run_processor.rb +4 -3
- data/lib/rookout/augs/aug.rb +33 -91
- data/lib/rookout/augs/aug_factory.rb +94 -27
- data/lib/rookout/augs/aug_rate_limiter.rb +50 -47
- data/lib/rookout/augs/augs_manager.rb +3 -1
- data/lib/rookout/augs/conditions/condition.rb +4 -2
- data/lib/rookout/augs/limits_manager.rb +32 -0
- 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 +21 -5
- data/lib/rookout/com_ws/agent_com_ws.rb +97 -58
- data/lib/rookout/com_ws/backoff.rb +5 -10
- data/lib/rookout/com_ws/command_handler.rb +1 -1
- data/lib/rookout/com_ws/envelope_wrapper.rb +68 -0
- data/lib/rookout/com_ws/git.rb +1 -1
- data/lib/rookout/com_ws/information.rb +95 -4
- data/lib/rookout/com_ws/output.rb +69 -21
- data/lib/rookout/com_ws/pinger.rb +41 -0
- data/lib/rookout/com_ws/websocket_client.rb +173 -0
- data/lib/rookout/commit.rb +3 -0
- data/lib/rookout/config.rb +94 -18
- data/lib/rookout/exceptions.rb +147 -12
- data/lib/rookout/interface.rb +95 -32
- data/lib/rookout/logger.rb +39 -10
- data/lib/rookout/processor/namespace_serializer.rb +2 -2
- data/lib/rookout/processor/namespace_serializer2.rb +331 -0
- data/lib/rookout/processor/namespaces/container_namespace.rb +5 -0
- data/lib/rookout/processor/namespaces/frame_namespace.rb +20 -17
- data/lib/rookout/processor/namespaces/namespace.rb +3 -2
- data/lib/rookout/processor/namespaces/noop_namespace.rb +4 -8
- data/lib/rookout/processor/namespaces/ruby_object_namespace.rb +39 -22
- data/lib/rookout/processor/namespaces/ruby_object_serializer.rb +15 -12
- data/lib/rookout/processor/namespaces/ruby_utils_namespace.rb +0 -4
- data/lib/rookout/processor/namespaces/stack_namespace.rb +6 -4
- data/lib/rookout/processor/namespaces/traceback_namespace.rb +13 -9
- data/lib/rookout/processor/operations/set_operation.rb +6 -1
- data/lib/rookout/processor/paths/arithmetic_path.rb +5 -3
- data/lib/rookout/processor/paths/canopy/actions.rb +5 -1
- data/lib/rookout/processor/paths/canopy/consts.rb +6 -4
- data/lib/rookout/processor/paths/canopy/maps.rb +286 -286
- data/lib/rookout/processor/paths/canopy/markers.rb +35 -4
- data/lib/rookout/processor/processor_factory.rb +0 -2
- data/lib/rookout/processor/rook_error.rb +6 -1
- data/lib/rookout/protobuf/controller_info_pb.rb +1 -0
- data/lib/rookout/protobuf/messages_pb.rb +54 -0
- data/lib/rookout/protobuf/variant2_pb.rb +42 -0
- data/lib/rookout/protobuf/variant_pb.rb +22 -0
- data/lib/rookout/rookout_singleton.rb +23 -5
- data/lib/rookout/sanitizer.rb +22 -0
- data/lib/rookout/services/position.rb +92 -75
- data/lib/rookout/services/tracer.rb +30 -16
- data/lib/rookout/start.rb +12 -0
- data/lib/rookout/trigger_services.rb +2 -2
- data/lib/rookout/user_warnings.rb +2 -0
- data/lib/rookout/utils.rb +34 -0
- data/lib/rookout/version.rb +1 -2
- data/lib/rookout.rb +4 -0
- metadata +77 -51
@@ -4,7 +4,14 @@ module Rookout
|
|
4
4
|
module Canopy
|
5
5
|
require_relative "consts"
|
6
6
|
|
7
|
-
|
7
|
+
require_relative "../../../exceptions"
|
8
|
+
require_relative "../../namespaces/container_namespace"
|
9
|
+
|
10
|
+
# rubocop:disable Lint/EmptyClass
|
11
|
+
class Marker
|
12
|
+
# Empty base class
|
13
|
+
end
|
14
|
+
# rubocop:enable Lint/EmptyClass
|
8
15
|
|
9
16
|
class Operation < Marker
|
10
17
|
def read _namespace, _create
|
@@ -12,12 +19,13 @@ module Rookout
|
|
12
19
|
end
|
13
20
|
|
14
21
|
def write _namespace, _value
|
15
|
-
raise Exception
|
22
|
+
raise Exception::RookOperationReadOnly, self.class.to_s
|
16
23
|
end
|
17
24
|
end
|
18
25
|
|
19
26
|
class FunctionOperation < Operation
|
20
27
|
def initialize name, args
|
28
|
+
super()
|
21
29
|
@name = name
|
22
30
|
@args = args
|
23
31
|
end
|
@@ -29,6 +37,7 @@ module Rookout
|
|
29
37
|
|
30
38
|
class AttributeOperation < Operation
|
31
39
|
def initialize name
|
40
|
+
super()
|
32
41
|
@name = name
|
33
42
|
end
|
34
43
|
|
@@ -36,7 +45,7 @@ module Rookout
|
|
36
45
|
namespace.read_attribute @name
|
37
46
|
rescue Exceptions::RookAttributeNotFound
|
38
47
|
raise unless create
|
39
|
-
namespace.write_attribute name, ContainerNamespace.new
|
48
|
+
namespace.write_attribute @name, Namespaces::ContainerNamespace.new
|
40
49
|
end
|
41
50
|
|
42
51
|
def write namespace, value
|
@@ -46,6 +55,7 @@ module Rookout
|
|
46
55
|
|
47
56
|
class LookupOperation < Operation
|
48
57
|
def initialize text
|
58
|
+
super()
|
49
59
|
if (text.start_with?("'") && text.end_with?("'")) || (text.start_with?("\"") && text.end_with?("\""))
|
50
60
|
@key = text[1...-1]
|
51
61
|
else
|
@@ -60,11 +70,13 @@ module Rookout
|
|
60
70
|
|
61
71
|
class ObjectMarker < Marker
|
62
72
|
def initialize text, obj
|
73
|
+
super()
|
63
74
|
@text = text
|
64
75
|
@obj = obj
|
65
76
|
end
|
66
77
|
|
67
|
-
attr_reader :text
|
78
|
+
attr_reader :text
|
79
|
+
attr_reader :obj
|
68
80
|
|
69
81
|
def to_s
|
70
82
|
@obj.to_s
|
@@ -133,6 +145,8 @@ module Rookout
|
|
133
145
|
|
134
146
|
class Opt < Marker
|
135
147
|
def initialize opt
|
148
|
+
super()
|
149
|
+
|
136
150
|
@opt = opt
|
137
151
|
@level = nil
|
138
152
|
|
@@ -151,6 +165,21 @@ module Rookout
|
|
151
165
|
|
152
166
|
attr_reader :level
|
153
167
|
|
168
|
+
def check_result result, first_obj, second_obj
|
169
|
+
return unless [true, false].include? result
|
170
|
+
if result
|
171
|
+
return
|
172
|
+
end
|
173
|
+
|
174
|
+
if !first_obj.nil? && !(PRIMITIVES.include? first_obj.class)
|
175
|
+
raise Exceptions::RookNonPrimitiveObjectType, first_obj.class.to_s
|
176
|
+
end
|
177
|
+
|
178
|
+
return if second_obj.nil?
|
179
|
+
raise Exceptions::RookNonPrimitiveObjectType, second_obj.class.to_s unless
|
180
|
+
PRIMITIVES.include? second_obj.class
|
181
|
+
end
|
182
|
+
|
154
183
|
def execute_operation first, second
|
155
184
|
# Remove wrapping of objects as needed
|
156
185
|
first_obj = decapsulate_item first
|
@@ -163,6 +192,8 @@ module Rookout
|
|
163
192
|
raise Exceptions::RookExceptionEvaluationFailed.new "", e
|
164
193
|
end
|
165
194
|
|
195
|
+
check_result result, first_obj, second_obj
|
196
|
+
|
166
197
|
# If we don't have a result
|
167
198
|
if result.nil?
|
168
199
|
# Verify objects are primitives
|
@@ -25,12 +25,17 @@ module Rookout
|
|
25
25
|
end
|
26
26
|
|
27
27
|
attr_reader :message
|
28
|
+
attr_reader :exception
|
29
|
+
attr_reader :parameters
|
28
30
|
|
29
31
|
def dumps
|
30
32
|
parameters = NamespaceSerializer.dump Namespaces::RubyObjectNamespace.new(@parameters), false
|
31
33
|
exception = NamespaceSerializer.dump Namespaces::RubyObjectNamespace.new(@exception), false
|
32
34
|
|
33
|
-
backtrace_string =
|
35
|
+
backtrace_string = ""
|
36
|
+
unless @exception.backtrace.nil?
|
37
|
+
backtrace_string = @exception.backtrace.join "\n\t"
|
38
|
+
end
|
34
39
|
backtrace_object = Namespaces::RubyObjectNamespace.new(backtrace_string).tailor_limits!
|
35
40
|
traceback = NamespaceSerializer.dump backtrace_object, false
|
36
41
|
|
@@ -4,6 +4,7 @@
|
|
4
4
|
require 'google/protobuf'
|
5
5
|
|
6
6
|
require_relative 'variant_pb'
|
7
|
+
require_relative 'variant2_pb'
|
7
8
|
require_relative 'agent_info_pb'
|
8
9
|
require_relative 'controller_info_pb'
|
9
10
|
require 'google/protobuf/any_pb'
|
@@ -87,6 +88,11 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
87
88
|
optional :aug_id, :string, 2
|
88
89
|
optional :arguments, :message, 3, "com.rookout.Variant"
|
89
90
|
optional :report_id, :string, 4
|
91
|
+
map :strings_cache, :string, :uint32, 5
|
92
|
+
repeated :buffer_cache_buffers, :bytes, 6
|
93
|
+
repeated :buffer_cache_indexes, :uint32, 7
|
94
|
+
optional :arguments2, :message, 8, "com.rookout.Variant2"
|
95
|
+
optional :reverse_list_order, :bool, 9
|
90
96
|
end
|
91
97
|
add_message "com.rookout.UserMsg" do
|
92
98
|
optional :aug_report, :message, 1, "com.rookout.AugReportMessage"
|
@@ -98,6 +104,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
98
104
|
end
|
99
105
|
add_message "com.rookout.InitialAugsCommand" do
|
100
106
|
repeated :augs, :string, 1
|
107
|
+
map :sdk_configuration, :string, :string, 2
|
101
108
|
end
|
102
109
|
add_message "com.rookout.RemoveAugCommand" do
|
103
110
|
optional :aug_id, :string, 1
|
@@ -117,6 +124,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
117
124
|
repeated :connectedAgents, :string, 2
|
118
125
|
end
|
119
126
|
add_message "com.rookout.DataOnPremTokenRequest" do
|
127
|
+
optional :access_type, :enum, 1, "com.rookout.DataOnPremTokenAccessType"
|
120
128
|
end
|
121
129
|
add_message "com.rookout.DataOnPremTokenResponse" do
|
122
130
|
optional :token, :bytes, 1
|
@@ -150,6 +158,44 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
150
158
|
optional :message, :message, 2, "google.protobuf.Any"
|
151
159
|
optional :error, :string, 3
|
152
160
|
end
|
161
|
+
add_message "com.rookout.StartDatastoreConnectivityTestCommand" do
|
162
|
+
optional :orgId, :string, 1
|
163
|
+
optional :controllerId, :string, 2
|
164
|
+
optional :datastoreUrl, :string, 3
|
165
|
+
optional :workspaceId, :string, 4
|
166
|
+
end
|
167
|
+
add_message "com.rookout.DatastoreConnectivityTestC2cResponse" do
|
168
|
+
optional :controllerId, :string, 1
|
169
|
+
optional :TestMessageId, :string, 2
|
170
|
+
optional :isSuccess, :bool, 3
|
171
|
+
optional :errorString, :string, 4
|
172
|
+
end
|
173
|
+
add_message "com.rookout.PingDatastoreCommand" do
|
174
|
+
optional :datastoreUrl, :string, 1
|
175
|
+
end
|
176
|
+
add_message "com.rookout.DatastoreInformation" do
|
177
|
+
optional :version, :string, 1
|
178
|
+
optional :hostname, :string, 2
|
179
|
+
optional :machine_type, :string, 3
|
180
|
+
optional :network, :string, 4
|
181
|
+
optional :ip, :string, 5
|
182
|
+
optional :os, :string, 6
|
183
|
+
optional :os_release, :string, 7
|
184
|
+
optional :os_version, :string, 8
|
185
|
+
optional :os_string, :string, 9
|
186
|
+
end
|
187
|
+
add_message "com.rookout.OrgLanguagesConfigsRequest" do
|
188
|
+
end
|
189
|
+
add_message "com.rookout.LanguageConfig" do
|
190
|
+
map :config, :string, :string, 1
|
191
|
+
end
|
192
|
+
add_message "com.rookout.OrgLanguagesConfigsResponse" do
|
193
|
+
map :OrgConfig, :string, :message, 1, "com.rookout.LanguageConfig"
|
194
|
+
end
|
195
|
+
add_enum "com.rookout.DataOnPremTokenAccessType" do
|
196
|
+
value :WRITE, 0
|
197
|
+
value :READ, 1
|
198
|
+
end
|
153
199
|
end
|
154
200
|
end
|
155
201
|
|
@@ -185,5 +231,13 @@ module Com
|
|
185
231
|
HitCountUpdateMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.HitCountUpdateMessage").msgclass
|
186
232
|
C2cRpcRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.C2cRpcRequest").msgclass
|
187
233
|
C2cRpcResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.C2cRpcResponse").msgclass
|
234
|
+
StartDatastoreConnectivityTestCommand = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.StartDatastoreConnectivityTestCommand").msgclass
|
235
|
+
DatastoreConnectivityTestC2cResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.DatastoreConnectivityTestC2cResponse").msgclass
|
236
|
+
PingDatastoreCommand = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.PingDatastoreCommand").msgclass
|
237
|
+
DatastoreInformation = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.DatastoreInformation").msgclass
|
238
|
+
OrgLanguagesConfigsRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.OrgLanguagesConfigsRequest").msgclass
|
239
|
+
LanguageConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.LanguageConfig").msgclass
|
240
|
+
OrgLanguagesConfigsResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.OrgLanguagesConfigsResponse").msgclass
|
241
|
+
DataOnPremTokenAccessType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.DataOnPremTokenAccessType").enummodule
|
188
242
|
end
|
189
243
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
2
|
+
# source: variant2.proto
|
3
|
+
|
4
|
+
require 'google/protobuf'
|
5
|
+
|
6
|
+
require 'google/protobuf/timestamp_pb'
|
7
|
+
require_relative 'variant_pb'
|
8
|
+
Google::Protobuf::DescriptorPool.generated_pool.build do
|
9
|
+
add_file("variant2.proto", :syntax => :proto3) do
|
10
|
+
add_message "com.rookout.Error2" do
|
11
|
+
optional :message, :string, 1
|
12
|
+
optional :type, :string, 2
|
13
|
+
optional :parameters, :message, 3, "com.rookout.Variant2"
|
14
|
+
optional :exc, :message, 4, "com.rookout.Variant2"
|
15
|
+
optional :traceback, :message, 5, "com.rookout.Variant2"
|
16
|
+
end
|
17
|
+
add_message "com.rookout.Variant2" do
|
18
|
+
optional :variant_type_max_depth, :uint32, 1
|
19
|
+
optional :original_type_index_in_cache, :uint32, 2
|
20
|
+
repeated :attribute_names_in_cache, :uint32, 3
|
21
|
+
repeated :attribute_values, :message, 4, "com.rookout.Variant2"
|
22
|
+
optional :original_size, :uint32, 5
|
23
|
+
optional :long_value, :int64, 6
|
24
|
+
optional :bytes_index_in_cache, :uint32, 7
|
25
|
+
repeated :collection_keys, :message, 8, "com.rookout.Variant2"
|
26
|
+
repeated :collection_values, :message, 9, "com.rookout.Variant2"
|
27
|
+
optional :double_value, :double, 10
|
28
|
+
repeated :code_values, :message, 11, "com.rookout.Variant.CodeObject"
|
29
|
+
optional :time_value, :message, 12, "google.protobuf.Timestamp"
|
30
|
+
optional :error_value, :message, 16, "com.rookout.Error2"
|
31
|
+
optional :complex_value, :message, 17, "com.rookout.Variant.Complex"
|
32
|
+
optional :livetail, :message, 18, "com.rookout.Variant.LiveTailMessage"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module Com
|
38
|
+
module Rookout
|
39
|
+
Error2 = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.Error2").msgclass
|
40
|
+
Variant2 = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.Variant2").msgclass
|
41
|
+
end
|
42
|
+
end
|
@@ -18,6 +18,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
18
18
|
optional :original_type, :string, 2
|
19
19
|
repeated :attributes, :message, 3, "com.rookout.Variant.NamedValue"
|
20
20
|
optional :max_depth, :bool, 4
|
21
|
+
optional :original_type_index_in_cache, :uint32, 5
|
21
22
|
oneof :value do
|
22
23
|
optional :int_value, :int32, 11
|
23
24
|
optional :long_value, :int64, 12
|
@@ -35,6 +36,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
35
36
|
optional :complex_value, :message, 28, "com.rookout.Variant.Complex"
|
36
37
|
optional :enum_value, :message, 31, "com.rookout.Variant.Enumeration"
|
37
38
|
optional :traceback, :message, 32, "com.rookout.Variant.Traceback"
|
39
|
+
optional :livetail, :message, 33, "com.rookout.Variant.LiveTailMessage"
|
38
40
|
end
|
39
41
|
end
|
40
42
|
add_message "com.rookout.Variant.NamedValue" do
|
@@ -48,6 +50,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
48
50
|
add_message "com.rookout.Variant.String" do
|
49
51
|
optional :original_size, :int32, 1
|
50
52
|
optional :value, :string, 2
|
53
|
+
optional :value_index_in_cache, :uint32, 3
|
51
54
|
end
|
52
55
|
add_message "com.rookout.Variant.List" do
|
53
56
|
optional :type, :string, 1
|
@@ -73,6 +76,9 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
73
76
|
optional :module, :string, 2
|
74
77
|
optional :filename, :string, 3
|
75
78
|
optional :lineno, :uint32, 4
|
79
|
+
optional :name_index_in_cache, :uint32, 5
|
80
|
+
optional :module_index_in_cache, :uint32, 6
|
81
|
+
optional :filename_index_in_cache, :uint32, 7
|
76
82
|
end
|
77
83
|
add_message "com.rookout.Variant.LargeInt" do
|
78
84
|
optional :value, :string, 1
|
@@ -89,6 +95,19 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
89
95
|
add_message "com.rookout.Variant.Traceback" do
|
90
96
|
repeated :locations, :message, 1, "com.rookout.Variant.CodeObject"
|
91
97
|
end
|
98
|
+
add_message "com.rookout.Variant.LiveTailMessage" do
|
99
|
+
optional :level_name, :string, 1
|
100
|
+
optional :msg, :string, 2
|
101
|
+
optional :formatted_message, :string, 3
|
102
|
+
optional :time, :double, 4
|
103
|
+
optional :filename, :string, 5
|
104
|
+
optional :lineno, :int32, 6
|
105
|
+
optional :function, :string, 7
|
106
|
+
optional :module, :string, 8
|
107
|
+
optional :thread_id, :int64, 9
|
108
|
+
optional :thread_name, :string, 10
|
109
|
+
map :log_context, :string, :string, 11
|
110
|
+
end
|
92
111
|
add_enum "com.rookout.Variant.Type" do
|
93
112
|
value :VARIANT_NONE, 0
|
94
113
|
value :VARIANT_INT, 1
|
@@ -113,6 +132,8 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
113
132
|
value :VARIANT_DYNAMIC, 20
|
114
133
|
value :VARIANT_ENUM, 21
|
115
134
|
value :VARIANT_TRACEBACK, 22
|
135
|
+
value :VARIANT_LIVETAIL, 23
|
136
|
+
value :VARIANT_SET, 24
|
116
137
|
end
|
117
138
|
end
|
118
139
|
end
|
@@ -134,6 +155,7 @@ module Com
|
|
134
155
|
Variant::Complex = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.Variant.Complex").msgclass
|
135
156
|
Variant::Enumeration = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.Variant.Enumeration").msgclass
|
136
157
|
Variant::Traceback = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.Variant.Traceback").msgclass
|
158
|
+
Variant::LiveTailMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.Variant.LiveTailMessage").msgclass
|
137
159
|
Variant::Type = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("com.rookout.Variant.Type").enummodule
|
138
160
|
end
|
139
161
|
end
|
@@ -40,14 +40,21 @@ module Rookout
|
|
40
40
|
@services_started = false
|
41
41
|
end
|
42
42
|
|
43
|
-
def connect token, host, port, proxy, labels, async_start,
|
43
|
+
def connect token: nil, host: nil, port: nil, proxy: nil, labels: {}, async_start: false, fork: false,
|
44
|
+
throw_errors: false
|
44
45
|
raise Exceptions::RookInterfaceException, "Multiple connection attempts not supported!" unless @agent_com.nil?
|
45
46
|
|
47
|
+
if fork
|
48
|
+
require_relative "atfork"
|
49
|
+
Rookout::ForkManager.instance.activate!
|
50
|
+
end
|
51
|
+
|
46
52
|
start_trigger_services
|
47
53
|
|
48
54
|
Logger.instance.debug "Initiating AgentCom-\t#{host}:#{port}"
|
49
55
|
|
50
|
-
@agent_com = ComWs::AgentComWs.new @output, host, port, proxy, token, labels
|
56
|
+
@agent_com = ComWs::AgentComWs.new @output, host, port, proxy, token, labels, !throw_errors
|
57
|
+
@output.agent_com = @agent_com
|
51
58
|
@command_handler = ComWs::CommandHandler.new @agent_com, @aug_manager
|
52
59
|
|
53
60
|
@agent_com.connect
|
@@ -60,14 +67,25 @@ module Rookout
|
|
60
67
|
@output.flush_messages if !@output.nil && !@agent_com.nil?
|
61
68
|
end
|
62
69
|
|
70
|
+
def post_fork_clean
|
71
|
+
@agent_com.stop
|
72
|
+
@agent_com = nil
|
73
|
+
|
74
|
+
@command_handler = nil
|
75
|
+
|
76
|
+
# We don't disable services because we will lose all loaded scripts
|
77
|
+
@services.clear_augs
|
78
|
+
end
|
79
|
+
|
63
80
|
attr_reader :services
|
64
81
|
|
65
82
|
private
|
66
83
|
|
67
84
|
def check_version_supported
|
68
|
-
raise Exceptions::
|
69
|
-
raise Exceptions::RookVersionNotSupported
|
70
|
-
RUBY_VERSION.start_with?("2.7") || RUBY_VERSION.start_with?("2.6")
|
85
|
+
raise Exceptions::RookVersionNotSupported.new("platform", RUBY_ENGINE) unless RUBY_ENGINE == "ruby"
|
86
|
+
raise Exceptions::RookVersionNotSupported.new("version", RUBY_VERSION) unless
|
87
|
+
RUBY_VERSION.start_with?("2.7") || RUBY_VERSION.start_with?("2.6") ||
|
88
|
+
RUBY_VERSION.start_with?("3.0") || RUBY_VERSION.start_with?("3.1") || RUBY_VERSION.start_with?("3.2")
|
71
89
|
end
|
72
90
|
end
|
73
91
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "set"
|
2
|
+
module Rookout
|
3
|
+
class Sanitizer
|
4
|
+
@@blacklisted_properties = Set["labels", "ROOKOUT_LABELS"]
|
5
|
+
|
6
|
+
def self.sanitize_object! obj
|
7
|
+
obj.each_key do |key|
|
8
|
+
if obj[key].is_a?(String) && !@@blacklisted_properties.include?(key.to_s)
|
9
|
+
obj[key] = obj[key].strip
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.sanitize_properties!
|
15
|
+
ENV.each do |key, val|
|
16
|
+
if key.start_with?("ROOKOUT_") && !@@blacklisted_properties.include?(key.to_s)
|
17
|
+
ENV[key] = val.strip.delete_suffix("/")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module Rookout
|
2
2
|
module Services
|
3
|
+
require "zlib"
|
4
|
+
|
3
5
|
require_relative "../logger"
|
4
6
|
require_relative "../exceptions"
|
5
7
|
|
@@ -9,17 +11,25 @@ module Rookout
|
|
9
11
|
@method = method
|
10
12
|
end
|
11
13
|
|
12
|
-
attr_reader :lineno
|
14
|
+
attr_reader :lineno
|
15
|
+
attr_reader :method
|
13
16
|
end
|
14
17
|
|
15
18
|
class PositionResolver
|
16
19
|
def initialize tracer
|
17
20
|
@tracer = tracer
|
18
21
|
@augs = {}
|
22
|
+
@augs_lock = Mutex.new
|
23
|
+
@iseqs = []
|
19
24
|
@trace_point = TracePoint.new :script_compiled do |tp|
|
20
25
|
begin
|
21
26
|
begin
|
22
|
-
|
27
|
+
iseq = tp.instruction_sequence
|
28
|
+
# Ignore script without sources
|
29
|
+
if iseq.absolute_path
|
30
|
+
@iseqs << iseq
|
31
|
+
evaluate_script iseq
|
32
|
+
end
|
23
33
|
rescue Exception => e
|
24
34
|
Logger.instance.exception "Exception while evaluating script", e
|
25
35
|
end
|
@@ -30,26 +40,22 @@ module Rookout
|
|
30
40
|
@trace_point.enable
|
31
41
|
end
|
32
42
|
|
33
|
-
def add_aug location
|
34
|
-
positions =
|
35
|
-
|
36
|
-
|
37
|
-
else
|
38
|
-
@tracer.add_breakpoint_aug positions, aug
|
39
|
-
end
|
43
|
+
def add_aug location
|
44
|
+
positions = evaluate_all_scripts_to_location location
|
45
|
+
@tracer.add_breakpoint_aug positions, location unless positions.empty?
|
46
|
+
@augs_lock.synchronize { @augs[location.id] = location }
|
40
47
|
end
|
41
48
|
|
42
49
|
def remove_aug aug_id
|
43
|
-
|
44
|
-
return if
|
50
|
+
location = @augs[aug_id]
|
51
|
+
return if location.nil?
|
45
52
|
|
46
53
|
@augs.delete [aug_id]
|
47
|
-
|
48
|
-
aug.notify_removed
|
54
|
+
location.notify_removed
|
49
55
|
end
|
50
56
|
|
51
57
|
def clear_augs
|
52
|
-
@augs.
|
58
|
+
@augs.each_value do |aug_id|
|
53
59
|
remove_aug aug_id
|
54
60
|
end
|
55
61
|
|
@@ -64,88 +70,52 @@ module Rookout
|
|
64
70
|
private
|
65
71
|
|
66
72
|
#########################################################################################
|
67
|
-
#
|
73
|
+
# ISEQ comparison Section
|
68
74
|
def evaluate_script iseq
|
69
75
|
filename = iseq.absolute_path
|
70
76
|
return if filename.nil?
|
71
77
|
|
72
|
-
@
|
73
|
-
|
78
|
+
@augs_lock.synchronize do
|
79
|
+
@augs.each_value do |location|
|
80
|
+
position = evaluate_script_to_location iseq, filename, location
|
81
|
+
next if position.nil?
|
74
82
|
|
75
|
-
|
76
|
-
# TODO: CHECK FILE AND LINE HASH COMPARED TO AUG
|
77
|
-
position = PositionMarker.new iseq.absolute_path, location.lineno, iseq
|
78
|
-
@tracer.add_breakpoint_aug [position], pair[1]
|
79
|
-
elsif suggested_match? location, filename
|
80
|
-
warning = Exceptions::RookSourceFilePathSuggestion.new location.filename, filename
|
81
|
-
pair[1].notify_warning warning
|
83
|
+
@tracer.add_breakpoint_aug [position], location
|
82
84
|
end
|
83
85
|
end
|
84
86
|
end
|
85
87
|
|
86
|
-
|
87
|
-
# Enumerating Section
|
88
|
-
def resolve_positions location, aug
|
89
|
-
# TODO: ADD HASHES AND SUGGESTIONS TO THIS FLOW
|
88
|
+
def evaluate_all_scripts_to_location location
|
90
89
|
positions = []
|
90
|
+
@iseqs.each do |iseq|
|
91
|
+
position = evaluate_script_to_location iseq, iseq.absolute_path, location
|
92
|
+
next if position.nil?
|
91
93
|
|
92
|
-
|
93
|
-
positions += scan_module_or_class mod, location, aug
|
94
|
-
end
|
95
|
-
|
96
|
-
ObjectSpace.each_object Class do |klass|
|
97
|
-
positions += scan_module_or_class klass, location, aug
|
94
|
+
positions << position
|
98
95
|
end
|
99
96
|
|
100
97
|
positions
|
101
98
|
end
|
102
99
|
|
103
|
-
def
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
mod.private_instance_methods(false).each do |method_name|
|
115
|
-
method = mod.instance_method method_name
|
116
|
-
next unless method_match? method, location, aug
|
117
|
-
|
118
|
-
position = PositionMarker.new location.lineno, method
|
119
|
-
positions.push position
|
120
|
-
end
|
121
|
-
|
122
|
-
positions
|
123
|
-
end
|
124
|
-
|
125
|
-
def method_match? method, location, aug
|
126
|
-
return false unless method.source_location
|
127
|
-
filename = method.source_location[0]
|
128
|
-
|
129
|
-
if exact_match? location, filename
|
130
|
-
disasm_header = "== disasm: #<ISeq:#{method.name}@#{location.filename}:"
|
131
|
-
line_in_disasm = "(#{location.lineno.to_s.rjust 4})"
|
132
|
-
text = RubyVM::InstructionSequence.disasm method
|
133
|
-
return false if text.nil?
|
134
|
-
|
135
|
-
text.start_with?(disasm_header) && text.include?(line_in_disasm)
|
136
|
-
else
|
137
|
-
if suggested_match? location, filename
|
138
|
-
warning = Exceptions::RookSourceFilePathSuggestion.new location.filename, filename
|
139
|
-
aug.notify_warning warning
|
140
|
-
end
|
141
|
-
false
|
100
|
+
def evaluate_script_to_location iseq, filename, location
|
101
|
+
if exact_match? location.filename, filename
|
102
|
+
lineno = find_updated_line filename, location
|
103
|
+
return if lineno == -1
|
104
|
+
|
105
|
+
PositionMarker.new lineno, iseq
|
106
|
+
elsif suggested_match? location, filename
|
107
|
+
warning = Exceptions::RookSourceFilePathSuggestion.new location.filename, filename
|
108
|
+
location.notify_warning Processor::RookError.new warning
|
109
|
+
# Must return nil in order to skip this script
|
110
|
+
nil
|
142
111
|
end
|
143
112
|
end
|
144
113
|
|
145
114
|
#########################################################################################
|
146
115
|
# Utils
|
147
|
-
def exact_match?
|
148
|
-
|
116
|
+
def exact_match? location_filename, script_filename
|
117
|
+
return unless script_filename.end_with? location_filename
|
118
|
+
File.basename(script_filename) == File.basename(location_filename)
|
149
119
|
end
|
150
120
|
|
151
121
|
def suggested_match? location, filename
|
@@ -158,6 +128,53 @@ module Rookout
|
|
158
128
|
content.gsub!(/(?:\r\n|\r|\n)/, "\n")
|
159
129
|
Digest::SHA2.new(256).hexdigest content
|
160
130
|
end
|
131
|
+
|
132
|
+
def handle_unique_line lines, location, filename
|
133
|
+
first_line = nil
|
134
|
+
second_found = false
|
135
|
+
|
136
|
+
lines.each_with_index do |line, index|
|
137
|
+
if crc_line(line) == location.line_crc
|
138
|
+
if first_line.nil?
|
139
|
+
first_line = index
|
140
|
+
else
|
141
|
+
second_found = true
|
142
|
+
break
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
if first_line && !second_found
|
148
|
+
updated_line = first_line + 1
|
149
|
+
location.notify_warning Processor::RookError.new Exceptions::RookLineMoved.new(filename,
|
150
|
+
location.lineno,
|
151
|
+
updated_line)
|
152
|
+
return updated_line
|
153
|
+
end
|
154
|
+
nil
|
155
|
+
end
|
156
|
+
|
157
|
+
def find_updated_line filename, location
|
158
|
+
return location.lineno if location.line_crc.nil?
|
159
|
+
|
160
|
+
lines = File.readlines filename, chomp: true
|
161
|
+
line_crc32 = lines.length >= location.lineno ? crc_line(lines[location.lineno - 1]) : nil
|
162
|
+
return location.lineno if location.line_crc == line_crc32
|
163
|
+
|
164
|
+
if location.line_unique
|
165
|
+
updated_line = handle_unique_line lines, location, filename
|
166
|
+
unless updated_line.nil?
|
167
|
+
return updated_line
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
location.notify_error Exceptions::RookCrcMismatchException.new(filename, location.line_crc, line_crc32)
|
172
|
+
-1
|
173
|
+
end
|
174
|
+
|
175
|
+
def crc_line line
|
176
|
+
(Zlib.crc32(line) & 0xffffffff).to_s 16
|
177
|
+
end
|
161
178
|
end
|
162
179
|
end
|
163
180
|
end
|