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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +8 -0
  3. data/LICENSE +201 -0
  4. data/README.md +56 -0
  5. data/ext/google/cloud/debugger/debugger_c/debugger.c +31 -0
  6. data/ext/google/cloud/debugger/debugger_c/debugger.h +26 -0
  7. data/ext/google/cloud/debugger/debugger_c/evaluator.c +78 -0
  8. data/ext/google/cloud/debugger/debugger_c/evaluator.h +25 -0
  9. data/ext/google/cloud/debugger/debugger_c/extconf.rb +22 -0
  10. data/ext/google/cloud/debugger/debugger_c/tracer.c +478 -0
  11. data/ext/google/cloud/debugger/debugger_c/tracer.h +31 -0
  12. data/lib/google-cloud-debugger.rb +121 -0
  13. data/lib/google/cloud/debugger.rb +379 -0
  14. data/lib/google/cloud/debugger/agent.rb +204 -0
  15. data/lib/google/cloud/debugger/async_actor.rb +290 -0
  16. data/lib/google/cloud/debugger/breakpoint.rb +382 -0
  17. data/lib/google/cloud/debugger/breakpoint/evaluator.rb +1113 -0
  18. data/lib/google/cloud/debugger/breakpoint/source_location.rb +75 -0
  19. data/lib/google/cloud/debugger/breakpoint/stack_frame.rb +109 -0
  20. data/lib/google/cloud/debugger/breakpoint/variable.rb +304 -0
  21. data/lib/google/cloud/debugger/breakpoint_manager.rb +217 -0
  22. data/lib/google/cloud/debugger/credentials.rb +41 -0
  23. data/lib/google/cloud/debugger/debuggee.rb +204 -0
  24. data/lib/google/cloud/debugger/debuggee/app_uniquifier_generator.rb +78 -0
  25. data/lib/google/cloud/debugger/middleware.rb +77 -0
  26. data/lib/google/cloud/debugger/project.rb +135 -0
  27. data/lib/google/cloud/debugger/rails.rb +141 -0
  28. data/lib/google/cloud/debugger/service.rb +130 -0
  29. data/lib/google/cloud/debugger/tracer.rb +165 -0
  30. data/lib/google/cloud/debugger/transmitter.rb +129 -0
  31. data/lib/google/cloud/debugger/v2.rb +15 -0
  32. data/lib/google/cloud/debugger/v2/controller2_client.rb +299 -0
  33. data/lib/google/cloud/debugger/v2/controller2_client_config.json +43 -0
  34. data/lib/google/cloud/debugger/v2/debugger2_client.rb +378 -0
  35. data/lib/google/cloud/debugger/v2/debugger2_client_config.json +53 -0
  36. data/lib/google/cloud/debugger/v2/doc/google/devtools/clouddebugger/v2/data.rb +441 -0
  37. data/lib/google/cloud/debugger/v2/doc/google/devtools/clouddebugger/v2/debugger.rb +151 -0
  38. data/lib/google/cloud/debugger/v2/doc/google/devtools/source/v1/source_context.rb +161 -0
  39. data/lib/google/cloud/debugger/v2/doc/google/protobuf/timestamp.rb +81 -0
  40. data/lib/google/cloud/debugger/version.rb +22 -0
  41. data/lib/google/devtools/clouddebugger/v2/controller_pb.rb +47 -0
  42. data/lib/google/devtools/clouddebugger/v2/controller_services_pb.rb +97 -0
  43. data/lib/google/devtools/clouddebugger/v2/data_pb.rb +105 -0
  44. data/lib/google/devtools/clouddebugger/v2/debugger_pb.rb +74 -0
  45. data/lib/google/devtools/clouddebugger/v2/debugger_services_pb.rb +64 -0
  46. data/lib/google/devtools/source/v1/source_context_pb.rb +89 -0
  47. 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