google-cloud-debugger 0.24.0
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 +7 -0
- data/.yardopts +8 -0
- data/LICENSE +201 -0
- data/README.md +56 -0
- data/ext/google/cloud/debugger/debugger_c/debugger.c +31 -0
- data/ext/google/cloud/debugger/debugger_c/debugger.h +26 -0
- data/ext/google/cloud/debugger/debugger_c/evaluator.c +78 -0
- data/ext/google/cloud/debugger/debugger_c/evaluator.h +25 -0
- data/ext/google/cloud/debugger/debugger_c/extconf.rb +22 -0
- data/ext/google/cloud/debugger/debugger_c/tracer.c +478 -0
- data/ext/google/cloud/debugger/debugger_c/tracer.h +31 -0
- data/lib/google-cloud-debugger.rb +121 -0
- data/lib/google/cloud/debugger.rb +379 -0
- data/lib/google/cloud/debugger/agent.rb +204 -0
- data/lib/google/cloud/debugger/async_actor.rb +290 -0
- data/lib/google/cloud/debugger/breakpoint.rb +382 -0
- data/lib/google/cloud/debugger/breakpoint/evaluator.rb +1113 -0
- data/lib/google/cloud/debugger/breakpoint/source_location.rb +75 -0
- data/lib/google/cloud/debugger/breakpoint/stack_frame.rb +109 -0
- data/lib/google/cloud/debugger/breakpoint/variable.rb +304 -0
- data/lib/google/cloud/debugger/breakpoint_manager.rb +217 -0
- data/lib/google/cloud/debugger/credentials.rb +41 -0
- data/lib/google/cloud/debugger/debuggee.rb +204 -0
- data/lib/google/cloud/debugger/debuggee/app_uniquifier_generator.rb +78 -0
- data/lib/google/cloud/debugger/middleware.rb +77 -0
- data/lib/google/cloud/debugger/project.rb +135 -0
- data/lib/google/cloud/debugger/rails.rb +141 -0
- data/lib/google/cloud/debugger/service.rb +130 -0
- data/lib/google/cloud/debugger/tracer.rb +165 -0
- data/lib/google/cloud/debugger/transmitter.rb +129 -0
- data/lib/google/cloud/debugger/v2.rb +15 -0
- data/lib/google/cloud/debugger/v2/controller2_client.rb +299 -0
- data/lib/google/cloud/debugger/v2/controller2_client_config.json +43 -0
- data/lib/google/cloud/debugger/v2/debugger2_client.rb +378 -0
- data/lib/google/cloud/debugger/v2/debugger2_client_config.json +53 -0
- data/lib/google/cloud/debugger/v2/doc/google/devtools/clouddebugger/v2/data.rb +441 -0
- data/lib/google/cloud/debugger/v2/doc/google/devtools/clouddebugger/v2/debugger.rb +151 -0
- data/lib/google/cloud/debugger/v2/doc/google/devtools/source/v1/source_context.rb +161 -0
- data/lib/google/cloud/debugger/v2/doc/google/protobuf/timestamp.rb +81 -0
- data/lib/google/cloud/debugger/version.rb +22 -0
- data/lib/google/devtools/clouddebugger/v2/controller_pb.rb +47 -0
- data/lib/google/devtools/clouddebugger/v2/controller_services_pb.rb +97 -0
- data/lib/google/devtools/clouddebugger/v2/data_pb.rb +105 -0
- data/lib/google/devtools/clouddebugger/v2/debugger_pb.rb +74 -0
- data/lib/google/devtools/clouddebugger/v2/debugger_services_pb.rb +64 -0
- data/lib/google/devtools/source/v1/source_context_pb.rb +89 -0
- metadata +300 -0
@@ -0,0 +1,217 @@
|
|
1
|
+
# Copyright 2017 Google Inc. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
|
16
|
+
require "google/cloud/debugger/breakpoint"
|
17
|
+
|
18
|
+
module Google
|
19
|
+
module Cloud
|
20
|
+
module Debugger
|
21
|
+
##
|
22
|
+
# # BreakpointManager
|
23
|
+
#
|
24
|
+
# Responsible for querying Stackdriver Debugger service for any active
|
25
|
+
# breakpoints and keep an accurate local copies of the breakpoints.
|
26
|
+
#
|
27
|
+
# It correctly remembers which breakpoints are currently active and
|
28
|
+
# watched by the debugger agent, and which breakpoints are already
|
29
|
+
# completed. The BreakpointManager holds the record of truth for debugger
|
30
|
+
# breakpoints
|
31
|
+
#
|
32
|
+
class BreakpointManager
|
33
|
+
include MonitorMixin
|
34
|
+
|
35
|
+
##
|
36
|
+
# @private The gRPC Service object.
|
37
|
+
attr_reader :service
|
38
|
+
|
39
|
+
##
|
40
|
+
# Application root directory, in absolute file path form.
|
41
|
+
# @return [String]
|
42
|
+
attr_reader :app_root
|
43
|
+
|
44
|
+
##
|
45
|
+
# Callback function invoked when new breakpoints are added or removed
|
46
|
+
# @return [Method]
|
47
|
+
attr_accessor :on_breakpoints_change
|
48
|
+
|
49
|
+
##
|
50
|
+
# @private The wait token from Stackdriver Debugger service used
|
51
|
+
# for breakpoints long polling
|
52
|
+
attr_reader :wait_token
|
53
|
+
|
54
|
+
##
|
55
|
+
# @private Construct new instance of BreakpointManager
|
56
|
+
def initialize service
|
57
|
+
super()
|
58
|
+
|
59
|
+
@service = service
|
60
|
+
|
61
|
+
@completed_breakpoints = []
|
62
|
+
@active_breakpoints = []
|
63
|
+
|
64
|
+
@wait_token = :init
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Sync active breakpoints with Stackdriver Debugger service for a given
|
69
|
+
# debuggee application. Each request to the debugger service returns
|
70
|
+
# the full list of all active breakpoints. This method makes sure the
|
71
|
+
# local cache of active breakpoints is consistent with server
|
72
|
+
# breakpoints set.
|
73
|
+
#
|
74
|
+
# @param [String] debuggee_id Debuggee application ID
|
75
|
+
#
|
76
|
+
# @return [Boolean] True if synced successfully; otherwise false.
|
77
|
+
#
|
78
|
+
def sync_active_breakpoints debuggee_id
|
79
|
+
begin
|
80
|
+
response = service.list_active_breakpoints debuggee_id, @wait_token
|
81
|
+
rescue
|
82
|
+
return false
|
83
|
+
end
|
84
|
+
|
85
|
+
return true if response.wait_expired
|
86
|
+
|
87
|
+
@wait_token = response.next_wait_token
|
88
|
+
|
89
|
+
server_breakpoints = response.breakpoints || []
|
90
|
+
server_breakpoints = server_breakpoints.map do |grpc_b|
|
91
|
+
Breakpoint.from_grpc grpc_b
|
92
|
+
end
|
93
|
+
|
94
|
+
update_breakpoints server_breakpoints
|
95
|
+
|
96
|
+
true
|
97
|
+
end
|
98
|
+
|
99
|
+
##
|
100
|
+
# Update the local breakpoints cache with a list of server active
|
101
|
+
# breakpoints. New breakpoints will be added to local cache, and deleted
|
102
|
+
# breakpoints will be removed from local cache.
|
103
|
+
#
|
104
|
+
# It also correctly identifies evaluated active breakpoints from the
|
105
|
+
# server set of breakpoints, and does not re-add such evaluated
|
106
|
+
# breakpoints to the active list again.
|
107
|
+
#
|
108
|
+
# @param [Array<Google::Cloud::Debugger::Breakpoint>] server_breakpoints
|
109
|
+
# List of active breakpoints from Stackdriver Debugger service
|
110
|
+
#
|
111
|
+
def update_breakpoints server_breakpoints
|
112
|
+
synchronize do
|
113
|
+
new_breakpoints =
|
114
|
+
server_breakpoints - @active_breakpoints - @completed_breakpoints
|
115
|
+
before_breakpoints_count =
|
116
|
+
@active_breakpoints.size + @completed_breakpoints.size
|
117
|
+
|
118
|
+
# Remember new active breakpoints from server
|
119
|
+
@active_breakpoints += new_breakpoints unless new_breakpoints.empty?
|
120
|
+
|
121
|
+
# Forget old breakpoints
|
122
|
+
@completed_breakpoints &= server_breakpoints
|
123
|
+
@active_breakpoints &= server_breakpoints
|
124
|
+
after_breakpoints_acount =
|
125
|
+
@active_breakpoints.size + @completed_breakpoints.size
|
126
|
+
|
127
|
+
breakpoints_updated =
|
128
|
+
!new_breakpoints.empty? ||
|
129
|
+
(before_breakpoints_count != after_breakpoints_acount)
|
130
|
+
|
131
|
+
on_breakpoints_change.call(@active_breakpoints) if
|
132
|
+
on_breakpoints_change.respond_to?(:call) && breakpoints_updated
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# Mark a given active breakpoint as completed. Meaning moving it from
|
138
|
+
# list of active breakpoints to completed breakpoints.
|
139
|
+
#
|
140
|
+
# @param [Google::Cloud::Debugger::Breakpoint] breakpoint The breakpoint
|
141
|
+
# to remove from local cache
|
142
|
+
#
|
143
|
+
# @return [Google::Cloud::Debugger::Breakpoint, NilClass] The same
|
144
|
+
# breakpoint if successfully marked off as completed. Nil if
|
145
|
+
# this breakpoint isn't found in the list of active breakpoints or
|
146
|
+
# failed to mark off as completed.
|
147
|
+
#
|
148
|
+
def mark_off breakpoint
|
149
|
+
synchronize do
|
150
|
+
breakpoint = @active_breakpoints.delete breakpoint
|
151
|
+
|
152
|
+
if breakpoint.nil?
|
153
|
+
nil
|
154
|
+
else
|
155
|
+
@completed_breakpoints << breakpoint
|
156
|
+
breakpoint
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
##
|
162
|
+
# Get a list of all breakpoints, both active and completed.
|
163
|
+
#
|
164
|
+
# @return [Array<Google::Cloud::Debugger::Breakpoint>] A list of all
|
165
|
+
# breakpoints.
|
166
|
+
def breakpoints
|
167
|
+
synchronize do
|
168
|
+
@active_breakpoints | @completed_breakpoints
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
##
|
173
|
+
# Get a list of all completed breakpoints.
|
174
|
+
#
|
175
|
+
# @return [Array<Google::Cloud::Debugger::Breakpoint>] A list of all
|
176
|
+
# completed breakpoints.
|
177
|
+
def completed_breakpoints
|
178
|
+
synchronize do
|
179
|
+
@completed_breakpoints
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
##
|
184
|
+
# Get a list of all active breakpoints.
|
185
|
+
#
|
186
|
+
# @return [Array<Google::Cloud::Debugger::Breakpoint>] A list of all
|
187
|
+
# active breakpoints.
|
188
|
+
def active_breakpoints
|
189
|
+
synchronize do
|
190
|
+
@active_breakpoints
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
##
|
195
|
+
# Check whether any active breakpoints haven't been completed yet.
|
196
|
+
#
|
197
|
+
# @return [Boolean] True if no more active breakpoints are left. False
|
198
|
+
# otherwise.
|
199
|
+
def all_complete?
|
200
|
+
synchronize do
|
201
|
+
@active_breakpoints.empty?
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
##
|
206
|
+
# Clear local breakpoints cache. Remove all active and completed
|
207
|
+
# breakpoints
|
208
|
+
def clear_breakpoints
|
209
|
+
synchronize do
|
210
|
+
@active_breakpoints.clear
|
211
|
+
@completed_breakpoints.clear
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Copyright 2017 Google Inc. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
|
16
|
+
require "google/cloud/credentials"
|
17
|
+
|
18
|
+
module Google
|
19
|
+
module Cloud
|
20
|
+
module Debugger
|
21
|
+
##
|
22
|
+
# @private Represents the OAuth 2.0 signing logic for Debugger.
|
23
|
+
class Credentials < Google::Cloud::Credentials
|
24
|
+
SCOPE = ["https://www.googleapis.com/auth/cloud_debugger"]
|
25
|
+
PATH_ENV_VARS = %w(DEBUGGER_KEYFILE GOOGLE_CLOUD_KEYFILE GCLOUD_KEYFILE)
|
26
|
+
JSON_ENV_VARS = %w(DEBUGGER_KEYFILE_JSON GOOGLE_CLOUD_KEYFILE_JSON
|
27
|
+
GCLOUD_KEYFILE_JSON)
|
28
|
+
|
29
|
+
##
|
30
|
+
# @private Create credentials with given scope and/or keyfile
|
31
|
+
def self.credentials_with_scope keyfile, scope = nil
|
32
|
+
if keyfile.nil?
|
33
|
+
default(scope: scope)
|
34
|
+
else
|
35
|
+
new(keyfile, scope: scope)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
# Copyright 2017 Google Inc. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
|
16
|
+
require "digest/sha1"
|
17
|
+
require "google/cloud/debugger/debuggee/app_uniquifier_generator"
|
18
|
+
require "google/cloud/debugger/version"
|
19
|
+
require "json"
|
20
|
+
|
21
|
+
module Google
|
22
|
+
module Cloud
|
23
|
+
module Debugger
|
24
|
+
##
|
25
|
+
# # Debuggee
|
26
|
+
#
|
27
|
+
# Represent a debuggee application. Contains information that identifies
|
28
|
+
# debuggee applications from each other. Maps to gRPC struct
|
29
|
+
# {Google::Devtools::Clouddebugger::V2::Debuggee}.
|
30
|
+
#
|
31
|
+
# It also automatically loads source context information generated from
|
32
|
+
# Cloud SDK. See [Stackdriver Debugger
|
33
|
+
# doc](https://cloud.google.com/debugger/docs/source-context#app_engine_standard_python)
|
34
|
+
# for more information on how to generate this source context information
|
35
|
+
# when used on Google Container Engine and Google Compute engine. This
|
36
|
+
# step is taken care of if debuggee application is hosted on Google App
|
37
|
+
# Engine Flexibile.
|
38
|
+
#
|
39
|
+
# To ensure the multiple instances of the application are indeed the same
|
40
|
+
# application, the debuggee also compute a "uniquifier" generated from
|
41
|
+
# source context or application source code.
|
42
|
+
#
|
43
|
+
class Debuggee
|
44
|
+
##
|
45
|
+
# @private The gRPC Service object.
|
46
|
+
attr_reader :service
|
47
|
+
|
48
|
+
##
|
49
|
+
# Name for the debuggee application
|
50
|
+
# @return [String]
|
51
|
+
attr_reader :module_name
|
52
|
+
|
53
|
+
##
|
54
|
+
# Version identifier for the debuggee application
|
55
|
+
# @return [String]
|
56
|
+
attr_reader :module_version
|
57
|
+
|
58
|
+
##
|
59
|
+
# Registered Debuggee ID. Set by Stackdriver Debugger service when
|
60
|
+
# a debuggee application is sucessfully registered.
|
61
|
+
# @return [String]
|
62
|
+
attr_reader :id
|
63
|
+
|
64
|
+
##
|
65
|
+
# @private Construct a new instance of Debuggee
|
66
|
+
def initialize service, module_name:, module_version:
|
67
|
+
@service = service
|
68
|
+
@module_name = module_name
|
69
|
+
@module_version = module_version
|
70
|
+
@computed_uniquifier = nil
|
71
|
+
@id = nil
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# Register the current application as a debuggee with Stackdriver
|
76
|
+
# Debuggee service.
|
77
|
+
# @return [Boolean] True if registered sucessfully; otherwise false.
|
78
|
+
def register
|
79
|
+
begin
|
80
|
+
response = service.register_debuggee to_grpc
|
81
|
+
@id = response.debuggee.id
|
82
|
+
rescue
|
83
|
+
revoke_registration
|
84
|
+
end
|
85
|
+
registered?
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# Check whether this debuggee is currently registered or not
|
90
|
+
# @return [Boolean] True if debuggee is registered; otherwise false.
|
91
|
+
def registered?
|
92
|
+
!id.nil?
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Revoke the registration of this debuggee
|
97
|
+
def revoke_registration
|
98
|
+
@id = nil
|
99
|
+
end
|
100
|
+
|
101
|
+
##
|
102
|
+
# Convert this debuggee into a gRPC
|
103
|
+
# Google::Devtools::Clouddebugger::V2::Debuggee struct.
|
104
|
+
def to_grpc
|
105
|
+
debuggee_args = build_request_arg
|
106
|
+
|
107
|
+
Google::Devtools::Clouddebugger::V2::Debuggee.decode_json \
|
108
|
+
debuggee_args.to_json
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
##
|
114
|
+
# @private Build the parameters for this debuggee
|
115
|
+
def build_request_arg
|
116
|
+
debuggee_args = {
|
117
|
+
project: project_id,
|
118
|
+
description: description,
|
119
|
+
labels: labels,
|
120
|
+
agent_version: agent_version
|
121
|
+
}
|
122
|
+
|
123
|
+
debuggee_args[:id] = id if id
|
124
|
+
|
125
|
+
source_context = read_app_json_file "source-context.json"
|
126
|
+
debuggee_args[:source_contexts] = [source_context] if source_context
|
127
|
+
|
128
|
+
source_contexts = read_app_json_file "source-contexts.json"
|
129
|
+
if source_contexts
|
130
|
+
debuggee_args[:ext_source_contexts] = source_contexts
|
131
|
+
elsif source_context
|
132
|
+
debuggee_args[:ext_source_contexts] = [{ context: source_context }]
|
133
|
+
end
|
134
|
+
|
135
|
+
debuggee_args[:uniquifier] = compute_uniquifier debuggee_args
|
136
|
+
|
137
|
+
debuggee_args
|
138
|
+
end
|
139
|
+
|
140
|
+
##
|
141
|
+
# @private Build labels hash for this debuggee
|
142
|
+
def labels
|
143
|
+
{
|
144
|
+
"projectid" => String(project_id),
|
145
|
+
"module" => String(module_name),
|
146
|
+
"version" => String(module_version)
|
147
|
+
}
|
148
|
+
end
|
149
|
+
|
150
|
+
##
|
151
|
+
# @private Build description string for this debuggee. In
|
152
|
+
# "<module name> - <module version>" format. Or just the module
|
153
|
+
# version if module name is missing.
|
154
|
+
#
|
155
|
+
# @return [String] A compact debuggee description.
|
156
|
+
#
|
157
|
+
def description
|
158
|
+
if module_version.nil? || module_version.empty?
|
159
|
+
module_name
|
160
|
+
else
|
161
|
+
"#{module_name} - #{module_version}"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
##
|
166
|
+
# @private Get debuggee project id
|
167
|
+
def project_id
|
168
|
+
service.project
|
169
|
+
end
|
170
|
+
|
171
|
+
##
|
172
|
+
# @private Build debuggee agent version identifier
|
173
|
+
def agent_version
|
174
|
+
"google.com/ruby#{RUBY_VERSION}-#{Google::Cloud::Debugger::VERSION}"
|
175
|
+
end
|
176
|
+
|
177
|
+
##
|
178
|
+
# @private Generate a debuggee uniquifier from source context
|
179
|
+
# information or application source code
|
180
|
+
def compute_uniquifier debuggee_args
|
181
|
+
return @computed_uniquifier if @computed_uniquifier
|
182
|
+
|
183
|
+
sha = Digest::SHA1.new
|
184
|
+
sha << debuggee_args.to_s
|
185
|
+
|
186
|
+
unless debuggee_args.key?(:source_contexts) ||
|
187
|
+
debuggee_args.key?(:ext_source_contexts)
|
188
|
+
AppUniquifierGenerator.generate_app_uniquifier sha
|
189
|
+
end
|
190
|
+
|
191
|
+
@computed_uniquifier = sha.hexdigest
|
192
|
+
end
|
193
|
+
|
194
|
+
##
|
195
|
+
# @private Helper method to parse json file
|
196
|
+
def read_app_json_file file_path
|
197
|
+
JSON.parse File.read(file_path), symbolize_names: true
|
198
|
+
rescue
|
199
|
+
nil
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|