google-cloud-debugger 0.25.0 → 0.26.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/google/cloud/debugger/debugger_c/evaluator.c +37 -10
- data/ext/google/cloud/debugger/debugger_c/tracer.c +76 -20
- data/lib/google/cloud/debugger/agent.rb +42 -19
- data/lib/google/cloud/debugger/breakpoint.rb +92 -36
- data/lib/google/cloud/debugger/breakpoint/evaluator.rb +27 -0
- data/lib/google/cloud/debugger/breakpoint_manager.rb +59 -1
- data/lib/google/cloud/debugger/middleware.rb +8 -0
- data/lib/google/cloud/debugger/tracer.rb +5 -22
- data/lib/google/cloud/debugger/transmitter.rb +27 -16
- data/lib/google/cloud/debugger/v2.rb +1 -1
- data/lib/google/cloud/debugger/v2/controller2_client.rb +11 -3
- data/lib/google/cloud/debugger/v2/controller2_client_config.json +1 -3
- data/lib/google/cloud/debugger/v2/debugger2_client.rb +13 -5
- data/lib/google/cloud/debugger/v2/debugger2_client_config.json +1 -3
- data/lib/google/cloud/debugger/version.rb +1 -1
- data/lib/google/devtools/clouddebugger/v2/data_pb.rb +1 -0
- metadata +18 -5
- data/lib/google/cloud/debugger/async_actor.rb +0 -290
@@ -878,6 +878,33 @@ module Google
|
|
878
878
|
result
|
879
879
|
end
|
880
880
|
|
881
|
+
##
|
882
|
+
# Format log message by interpolate expressions.
|
883
|
+
#
|
884
|
+
# @example
|
885
|
+
# Evaluator.format_log_message("Hello $0",
|
886
|
+
# ["World"]) #=> "Hello World"
|
887
|
+
#
|
888
|
+
# @param [String] message_format The message with with
|
889
|
+
# expression placeholders such as `$0`, `$1`, etc.
|
890
|
+
# @param [Array<Google::Cloud::Debugger::Breakpoint::Variable>]
|
891
|
+
# expressions An array of evaluated expression variables to be
|
892
|
+
# placed into message_format's placeholders. The variables need
|
893
|
+
# to have type equal String.
|
894
|
+
#
|
895
|
+
# @return [String] The formatted message string
|
896
|
+
#
|
897
|
+
def format_message message_format, expressions
|
898
|
+
# Substitute placeholders with expressions
|
899
|
+
message = message_format.gsub(/(?<!\$)\$\d+/) do |placeholder|
|
900
|
+
index = placeholder.match(/\$(\d+)/)[1].to_i
|
901
|
+
index < expressions.size ? expressions[index].inspect : ""
|
902
|
+
end
|
903
|
+
|
904
|
+
# Unescape "$" charactors
|
905
|
+
message.gsub(/\$\$/, "$")
|
906
|
+
end
|
907
|
+
|
881
908
|
private
|
882
909
|
|
883
910
|
##
|
@@ -32,6 +32,11 @@ module Google
|
|
32
32
|
class BreakpointManager
|
33
33
|
include MonitorMixin
|
34
34
|
|
35
|
+
##
|
36
|
+
# The debugger agent this tracer belongs to
|
37
|
+
# @return [Google::Cloud::Debugger::Agent]
|
38
|
+
attr_reader :agent
|
39
|
+
|
35
40
|
##
|
36
41
|
# @private The gRPC Service object.
|
37
42
|
attr_reader :service
|
@@ -53,9 +58,10 @@ module Google
|
|
53
58
|
|
54
59
|
##
|
55
60
|
# @private Construct new instance of BreakpointManager
|
56
|
-
def initialize service
|
61
|
+
def initialize agent, service
|
57
62
|
super()
|
58
63
|
|
64
|
+
@agent = agent
|
59
65
|
@service = service
|
60
66
|
|
61
67
|
@completed_breakpoints = []
|
@@ -133,6 +139,58 @@ module Google
|
|
133
139
|
end
|
134
140
|
end
|
135
141
|
|
142
|
+
##
|
143
|
+
# Evaluates a hit breakpoint, and submit the breakpoint to
|
144
|
+
# Transmitter if this breakpoint is evaluated successfully.
|
145
|
+
#
|
146
|
+
# See {Breakpoint#evaluate} for evaluation details.
|
147
|
+
#
|
148
|
+
# @param [Google::Cloud::Debugger::Breakpoint] breakpoint The breakpoint
|
149
|
+
# to be evaluated
|
150
|
+
# @param [Array<Binding>] call_stack_bindings An array of Ruby Binding
|
151
|
+
# objects, from the each frame of the call stack that leads to the
|
152
|
+
# triggering of the breakpoints.
|
153
|
+
#
|
154
|
+
def breakpoint_hit breakpoint, call_stack_bindings
|
155
|
+
breakpoint.evaluate call_stack_bindings
|
156
|
+
|
157
|
+
case breakpoint.action
|
158
|
+
when :CAPTURE
|
159
|
+
# Take this completed breakpoint off manager's active breakpoints
|
160
|
+
# list, submit the breakpoint snapshot, and update Tracer's
|
161
|
+
# breakpoints_cache.
|
162
|
+
return unless breakpoint.complete?
|
163
|
+
|
164
|
+
# Remove this breakpoint from active list
|
165
|
+
mark_off breakpoint
|
166
|
+
# Signal transmitter to submit this breakpoint
|
167
|
+
agent.transmitter.submit breakpoint
|
168
|
+
when :LOG
|
169
|
+
log_logpoint breakpoint
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
##
|
174
|
+
# Assume the given logpoint is successfully evaluated, log the
|
175
|
+
# evaluated log message via logger
|
176
|
+
#
|
177
|
+
# @param [Google::Cloud::Debugger::Breakpoint] logpoint The evaluated
|
178
|
+
# logpoint.
|
179
|
+
def log_logpoint logpoint
|
180
|
+
return unless agent.logger && logpoint.evaluated_log_message
|
181
|
+
|
182
|
+
message = "LOGPOINT: #{logpoint.evaluated_log_message}"
|
183
|
+
|
184
|
+
case logpoint.log_level
|
185
|
+
when :INFO
|
186
|
+
agent.logger.info message
|
187
|
+
when :WARNING
|
188
|
+
agent.logger.warn message
|
189
|
+
when :ERROR
|
190
|
+
agent.logger.error message
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
136
194
|
##
|
137
195
|
# Mark a given active breakpoint as completed. Meaning moving it from
|
138
196
|
# list of active breakpoints to completed breakpoints.
|
@@ -13,6 +13,8 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
|
16
|
+
require "google/cloud/logging/logger"
|
17
|
+
|
16
18
|
module Google
|
17
19
|
module Cloud
|
18
20
|
module Debugger
|
@@ -47,6 +49,7 @@ module Google
|
|
47
49
|
keyfile: configuration.keyfile,
|
48
50
|
module_name: configuration.module_name,
|
49
51
|
module_version: configuration.module_version)
|
52
|
+
|
50
53
|
# Immediately start the debugger agent
|
51
54
|
@debugger.start
|
52
55
|
end
|
@@ -65,6 +68,11 @@ module Google
|
|
65
68
|
# Enable/resume breakpoints tracing
|
66
69
|
@debugger.agent.tracer.start
|
67
70
|
|
71
|
+
# Use Stackdriver Logger for debugger if available
|
72
|
+
if env["rack.logger"].is_a? Google::Cloud::Logging::Logger
|
73
|
+
@debugger.agent.logger = env["rack.logger"]
|
74
|
+
end
|
75
|
+
|
68
76
|
@app.call env
|
69
77
|
ensure
|
70
78
|
# Stop breakpoints tracing beyond this point
|
@@ -103,31 +103,14 @@ module Google
|
|
103
103
|
end
|
104
104
|
|
105
105
|
##
|
106
|
-
#
|
107
|
-
#
|
106
|
+
# Callback function when a breakpoint is hit. Handover the hit
|
107
|
+
# breakpoint to breakpoint_manager to be evaluated.
|
108
108
|
#
|
109
|
-
|
110
|
-
#
|
111
|
-
# @param [Google::Cloud::Debugger::Breakpoint] breakpoint The breakpoint
|
112
|
-
# to be evaluated
|
113
|
-
# @param [Array<Binding>] call_stack_bindings An array of Ruby Binding
|
114
|
-
# objects, from the each frame of the call stack that leads to the
|
115
|
-
# triggering of the breakpoints.
|
116
|
-
#
|
117
|
-
def eval_breakpoint breakpoint, call_stack_bindings
|
109
|
+
def breakpoint_hit breakpoint, call_stack_bindings
|
118
110
|
return if breakpoint.nil? || breakpoint.complete?
|
119
111
|
|
120
|
-
|
121
|
-
|
122
|
-
# Take this completed breakpoint off manager's active breakpoints
|
123
|
-
# list, submit the breakpoint snapshot, and update Tracer's
|
124
|
-
# breakpoints_cache.
|
125
|
-
return unless breakpoint.complete?
|
126
|
-
|
127
|
-
# Signal breakpoint_manager that this breakpoint is evaluated
|
128
|
-
agent.breakpoint_manager.mark_off breakpoint
|
129
|
-
# Signal transmitter to submit this breakpoint
|
130
|
-
agent.transmitter.submit breakpoint
|
112
|
+
agent.breakpoint_manager.breakpoint_hit breakpoint,
|
113
|
+
call_stack_bindings
|
131
114
|
|
132
115
|
update_breakpoints_cache
|
133
116
|
|
@@ -13,7 +13,7 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
|
16
|
-
require "
|
16
|
+
require "stackdriver/core/async_actor"
|
17
17
|
|
18
18
|
module Google
|
19
19
|
module Cloud
|
@@ -32,7 +32,7 @@ module Google
|
|
32
32
|
# interaction with the rest debugger agent components
|
33
33
|
#
|
34
34
|
class Transmitter
|
35
|
-
include AsyncActor
|
35
|
+
include Stackdriver::Core::AsyncActor
|
36
36
|
|
37
37
|
##
|
38
38
|
# @private Default maximum backlog size for the job queue
|
@@ -53,12 +53,13 @@ module Google
|
|
53
53
|
|
54
54
|
##
|
55
55
|
# @private Construct a new instance of Tramsnitter
|
56
|
-
def initialize
|
56
|
+
def initialize agent, service, max_queue_size = DEFAULT_MAX_QUEUE_SIZE
|
57
57
|
super()
|
58
58
|
@service = service
|
59
59
|
@agent = agent
|
60
60
|
@max_queue_size = max_queue_size
|
61
|
-
@queue =
|
61
|
+
@queue = []
|
62
|
+
@queue_resource = new_cond
|
62
63
|
end
|
63
64
|
|
64
65
|
##
|
@@ -82,7 +83,7 @@ module Google
|
|
82
83
|
def submit breakpoint
|
83
84
|
synchronize do
|
84
85
|
@queue.push breakpoint
|
85
|
-
@
|
86
|
+
@queue_resource.broadcast
|
86
87
|
# Discard old entries if queue gets too large
|
87
88
|
@queue.pop while @queue.size > @max_queue_size
|
88
89
|
end
|
@@ -101,6 +102,14 @@ module Google
|
|
101
102
|
end
|
102
103
|
end
|
103
104
|
|
105
|
+
##
|
106
|
+
# @private Callback function when the async actor thread state changes
|
107
|
+
def on_async_state_change
|
108
|
+
synchronize do
|
109
|
+
@queue_resource.broadcast
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
104
113
|
private
|
105
114
|
|
106
115
|
##
|
@@ -109,18 +118,20 @@ module Google
|
|
109
118
|
# enqueued
|
110
119
|
def wait_next_item
|
111
120
|
synchronize do
|
112
|
-
@
|
113
|
-
|
114
|
-
(async_state == :running && @queue.empty?)
|
115
|
-
end
|
116
|
-
queue_item = nil
|
117
|
-
if @queue.empty?
|
118
|
-
@async_state = :stopped
|
119
|
-
else
|
120
|
-
queue_item = @queue.pop
|
121
|
+
@queue_resource.wait_while do
|
122
|
+
async_suspended? || (async_running? && @queue.empty?)
|
121
123
|
end
|
122
|
-
@
|
123
|
-
|
124
|
+
@queue.pop
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
##
|
129
|
+
# @private Override the #backgrounder_stoppable? method from AsyncActor
|
130
|
+
# module. The actor can be gracefully stopped when queue is
|
131
|
+
# empty.
|
132
|
+
def backgrounder_stoppable?
|
133
|
+
synchronize do
|
134
|
+
@queue.empty?
|
124
135
|
end
|
125
136
|
end
|
126
137
|
end
|
@@ -11,5 +11,5 @@
|
|
11
11
|
# See the License for the specific language governing permissions and
|
12
12
|
# limitations under the License.
|
13
13
|
|
14
|
-
require "google/cloud/debugger/v2/controller2_client"
|
15
14
|
require "google/cloud/debugger/v2/debugger2_client"
|
15
|
+
require "google/cloud/debugger/v2/controller2_client"
|
@@ -82,6 +82,12 @@ module Google
|
|
82
82
|
# A Channel object through which to make calls.
|
83
83
|
# @param chan_creds [Grpc::ChannelCredentials]
|
84
84
|
# A ChannelCredentials for the setting up the RPC client.
|
85
|
+
# @param updater_proc [Proc]
|
86
|
+
# A function that transforms the metadata for requests, e.g., to give
|
87
|
+
# OAuth credentials.
|
88
|
+
# @param scopes [Array<String>]
|
89
|
+
# The OAuth scopes for this service. This parameter is ignored if
|
90
|
+
# an updater_proc is supplied.
|
85
91
|
# @param client_config[Hash]
|
86
92
|
# A Hash for call options for each method. See
|
87
93
|
# Google::Gax#construct_settings for the structure of
|
@@ -94,6 +100,7 @@ module Google
|
|
94
100
|
port: DEFAULT_SERVICE_PORT,
|
95
101
|
channel: nil,
|
96
102
|
chan_creds: nil,
|
103
|
+
updater_proc: nil,
|
97
104
|
scopes: ALL_SCOPES,
|
98
105
|
client_config: {},
|
99
106
|
timeout: DEFAULT_TIMEOUT,
|
@@ -138,6 +145,7 @@ module Google
|
|
138
145
|
port,
|
139
146
|
chan_creds: chan_creds,
|
140
147
|
channel: channel,
|
148
|
+
updater_proc: updater_proc,
|
141
149
|
scopes: scopes,
|
142
150
|
&Google::Devtools::Clouddebugger::V2::Controller2::Stub.method(:new)
|
143
151
|
)
|
@@ -179,7 +187,7 @@ module Google
|
|
179
187
|
# @return [Google::Devtools::Clouddebugger::V2::RegisterDebuggeeResponse]
|
180
188
|
# @raise [Google::Gax::GaxError] if the RPC is aborted.
|
181
189
|
# @example
|
182
|
-
# require "google/cloud/debugger/v2
|
190
|
+
# require "google/cloud/debugger/v2"
|
183
191
|
#
|
184
192
|
# Controller2Client = Google::Cloud::Debugger::V2::Controller2Client
|
185
193
|
# Debuggee = Google::Devtools::Clouddebugger::V2::Debuggee
|
@@ -230,7 +238,7 @@ module Google
|
|
230
238
|
# @return [Google::Devtools::Clouddebugger::V2::ListActiveBreakpointsResponse]
|
231
239
|
# @raise [Google::Gax::GaxError] if the RPC is aborted.
|
232
240
|
# @example
|
233
|
-
# require "google/cloud/debugger/v2
|
241
|
+
# require "google/cloud/debugger/v2"
|
234
242
|
#
|
235
243
|
# Controller2Client = Google::Cloud::Debugger::V2::Controller2Client
|
236
244
|
#
|
@@ -272,7 +280,7 @@ module Google
|
|
272
280
|
# @return [Google::Devtools::Clouddebugger::V2::UpdateActiveBreakpointResponse]
|
273
281
|
# @raise [Google::Gax::GaxError] if the RPC is aborted.
|
274
282
|
# @example
|
275
|
-
# require "google/cloud/debugger/v2
|
283
|
+
# require "google/cloud/debugger/v2"
|
276
284
|
#
|
277
285
|
# Breakpoint = Google::Devtools::Clouddebugger::V2::Breakpoint
|
278
286
|
# Controller2Client = Google::Cloud::Debugger::V2::Controller2Client
|
@@ -74,6 +74,12 @@ module Google
|
|
74
74
|
# A Channel object through which to make calls.
|
75
75
|
# @param chan_creds [Grpc::ChannelCredentials]
|
76
76
|
# A ChannelCredentials for the setting up the RPC client.
|
77
|
+
# @param updater_proc [Proc]
|
78
|
+
# A function that transforms the metadata for requests, e.g., to give
|
79
|
+
# OAuth credentials.
|
80
|
+
# @param scopes [Array<String>]
|
81
|
+
# The OAuth scopes for this service. This parameter is ignored if
|
82
|
+
# an updater_proc is supplied.
|
77
83
|
# @param client_config[Hash]
|
78
84
|
# A Hash for call options for each method. See
|
79
85
|
# Google::Gax#construct_settings for the structure of
|
@@ -86,6 +92,7 @@ module Google
|
|
86
92
|
port: DEFAULT_SERVICE_PORT,
|
87
93
|
channel: nil,
|
88
94
|
chan_creds: nil,
|
95
|
+
updater_proc: nil,
|
89
96
|
scopes: ALL_SCOPES,
|
90
97
|
client_config: {},
|
91
98
|
timeout: DEFAULT_TIMEOUT,
|
@@ -130,6 +137,7 @@ module Google
|
|
130
137
|
port,
|
131
138
|
chan_creds: chan_creds,
|
132
139
|
channel: channel,
|
140
|
+
updater_proc: updater_proc,
|
133
141
|
scopes: scopes,
|
134
142
|
&Google::Devtools::Clouddebugger::V2::Debugger2::Stub.method(:new)
|
135
143
|
)
|
@@ -174,7 +182,7 @@ module Google
|
|
174
182
|
# @return [Google::Devtools::Clouddebugger::V2::SetBreakpointResponse]
|
175
183
|
# @raise [Google::Gax::GaxError] if the RPC is aborted.
|
176
184
|
# @example
|
177
|
-
# require "google/cloud/debugger/v2
|
185
|
+
# require "google/cloud/debugger/v2"
|
178
186
|
#
|
179
187
|
# Breakpoint = Google::Devtools::Clouddebugger::V2::Breakpoint
|
180
188
|
# Debugger2Client = Google::Cloud::Debugger::V2::Debugger2Client
|
@@ -213,7 +221,7 @@ module Google
|
|
213
221
|
# @return [Google::Devtools::Clouddebugger::V2::GetBreakpointResponse]
|
214
222
|
# @raise [Google::Gax::GaxError] if the RPC is aborted.
|
215
223
|
# @example
|
216
|
-
# require "google/cloud/debugger/v2
|
224
|
+
# require "google/cloud/debugger/v2"
|
217
225
|
#
|
218
226
|
# Debugger2Client = Google::Cloud::Debugger::V2::Debugger2Client
|
219
227
|
#
|
@@ -250,7 +258,7 @@ module Google
|
|
250
258
|
# retries, etc.
|
251
259
|
# @raise [Google::Gax::GaxError] if the RPC is aborted.
|
252
260
|
# @example
|
253
|
-
# require "google/cloud/debugger/v2
|
261
|
+
# require "google/cloud/debugger/v2"
|
254
262
|
#
|
255
263
|
# Debugger2Client = Google::Cloud::Debugger::V2::Debugger2Client
|
256
264
|
#
|
@@ -304,7 +312,7 @@ module Google
|
|
304
312
|
# @return [Google::Devtools::Clouddebugger::V2::ListBreakpointsResponse]
|
305
313
|
# @raise [Google::Gax::GaxError] if the RPC is aborted.
|
306
314
|
# @example
|
307
|
-
# require "google/cloud/debugger/v2
|
315
|
+
# require "google/cloud/debugger/v2"
|
308
316
|
#
|
309
317
|
# Debugger2Client = Google::Cloud::Debugger::V2::Debugger2Client
|
310
318
|
#
|
@@ -350,7 +358,7 @@ module Google
|
|
350
358
|
# @return [Google::Devtools::Clouddebugger::V2::ListDebuggeesResponse]
|
351
359
|
# @raise [Google::Gax::GaxError] if the RPC is aborted.
|
352
360
|
# @example
|
353
|
-
# require "google/cloud/debugger/v2
|
361
|
+
# require "google/cloud/debugger/v2"
|
354
362
|
#
|
355
363
|
# Debugger2Client = Google::Cloud::Debugger::V2::Debugger2Client
|
356
364
|
#
|