google-cloud-debugger 0.40.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 (45) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +18 -0
  3. data/AUTHENTICATION.md +178 -0
  4. data/CHANGELOG.md +233 -0
  5. data/CODE_OF_CONDUCT.md +40 -0
  6. data/CONTRIBUTING.md +188 -0
  7. data/INSTRUMENTATION.md +115 -0
  8. data/LICENSE +201 -0
  9. data/LOGGING.md +32 -0
  10. data/OVERVIEW.md +266 -0
  11. data/TROUBLESHOOTING.md +31 -0
  12. data/ext/google/cloud/debugger/debugger_c/debugger.c +31 -0
  13. data/ext/google/cloud/debugger/debugger_c/debugger.h +26 -0
  14. data/ext/google/cloud/debugger/debugger_c/evaluator.c +115 -0
  15. data/ext/google/cloud/debugger/debugger_c/evaluator.h +25 -0
  16. data/ext/google/cloud/debugger/debugger_c/extconf.rb +22 -0
  17. data/ext/google/cloud/debugger/debugger_c/tracer.c +542 -0
  18. data/ext/google/cloud/debugger/debugger_c/tracer.h +25 -0
  19. data/lib/google-cloud-debugger.rb +181 -0
  20. data/lib/google/cloud/debugger.rb +259 -0
  21. data/lib/google/cloud/debugger/agent.rb +255 -0
  22. data/lib/google/cloud/debugger/backoff.rb +70 -0
  23. data/lib/google/cloud/debugger/breakpoint.rb +443 -0
  24. data/lib/google/cloud/debugger/breakpoint/evaluator.rb +1099 -0
  25. data/lib/google/cloud/debugger/breakpoint/source_location.rb +74 -0
  26. data/lib/google/cloud/debugger/breakpoint/stack_frame.rb +109 -0
  27. data/lib/google/cloud/debugger/breakpoint/status_message.rb +93 -0
  28. data/lib/google/cloud/debugger/breakpoint/validator.rb +92 -0
  29. data/lib/google/cloud/debugger/breakpoint/variable.rb +595 -0
  30. data/lib/google/cloud/debugger/breakpoint/variable_table.rb +96 -0
  31. data/lib/google/cloud/debugger/breakpoint_manager.rb +311 -0
  32. data/lib/google/cloud/debugger/credentials.rb +50 -0
  33. data/lib/google/cloud/debugger/debuggee.rb +222 -0
  34. data/lib/google/cloud/debugger/debuggee/app_uniquifier_generator.rb +76 -0
  35. data/lib/google/cloud/debugger/logpoint.rb +98 -0
  36. data/lib/google/cloud/debugger/middleware.rb +200 -0
  37. data/lib/google/cloud/debugger/project.rb +110 -0
  38. data/lib/google/cloud/debugger/rails.rb +174 -0
  39. data/lib/google/cloud/debugger/request_quota_manager.rb +95 -0
  40. data/lib/google/cloud/debugger/service.rb +88 -0
  41. data/lib/google/cloud/debugger/snappoint.rb +208 -0
  42. data/lib/google/cloud/debugger/tracer.rb +137 -0
  43. data/lib/google/cloud/debugger/transmitter.rb +199 -0
  44. data/lib/google/cloud/debugger/version.rb +22 -0
  45. metadata +353 -0
@@ -0,0 +1,25 @@
1
+ /*
2
+ Copyright 2017 Google Inc. All rights reserved.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ https://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+ #ifndef GOOGLE_CLOUD_RUBY_DEBUGGER_TRACER_H_
18
+ #define GOOGLE_CLOUD_RUBY_DEBUGGER_TRACER_H_
19
+
20
+ #include "ruby/debug.h"
21
+
22
+ void
23
+ Init_tracer(VALUE mDebugger);
24
+
25
+ #endif // GOOGLE_CLOUD_RUBY_DEBUGGER_TRACER_H_
@@ -0,0 +1,181 @@
1
+ # Copyright 2017 Google LLC
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
+ # https://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
+ ##
17
+ # This file is here to be autorequired by bundler, so that the
18
+ # Google::Cloud.debugger and Google::Cloud#debugger methods can be available,
19
+ # but the library and all dependencies won't be loaded until required and used.
20
+
21
+
22
+ gem "google-cloud-core"
23
+ require "google/cloud" unless defined? Google::Cloud.new
24
+ require "google/cloud/config"
25
+ require "googleauth"
26
+
27
+ module Google
28
+ module Cloud
29
+ ##
30
+ # Creates a new debugger object for instrumenting Stackdriver Debugger for
31
+ # an application. Each call creates a new debugger agent with independent
32
+ # connection service.
33
+ #
34
+ # For more information on connecting to Google Cloud see the
35
+ # {file:AUTHENTICATION.md Authentication Guide}.
36
+ #
37
+ # @param [String] service_name Name for the debuggee application. Optional.
38
+ # @param [String] service_version Version identifier for the debuggee
39
+ # application. Optional.
40
+ # @param [String, Array<String>] scope The OAuth 2.0 scopes controlling the
41
+ # set of resources and operations that the connection can access. See
42
+ # [Using OAuth 2.0 to Access Google
43
+ # APIs](https://developers.google.com/identity/protocols/OAuth2).
44
+ #
45
+ # The default scope is:
46
+ #
47
+ # * `https://www.googleapis.com/auth/cloud_debugger`
48
+ # * `https://www.googleapis.com/auth/logging.admin`
49
+ #
50
+ # @param [Integer] timeout Default timeout to use in requests. Optional.
51
+ #
52
+ # @return [Google::Cloud::Debugger::Project]
53
+ #
54
+ # @example
55
+ # require "google/cloud"
56
+ #
57
+ # gcloud = Google::Cloud.new
58
+ # debugger = gcloud.debugger
59
+ #
60
+ # debugger.start
61
+ #
62
+ # @example The default scope can be overridden with the `scope` option:
63
+ # require "google/cloud"
64
+ #
65
+ # gcloud = Google::Cloud.new
66
+ # platform_scope = "https://www.googleapis.com/auth/cloud-platform"
67
+ # debugger = gcloud.debugger scope: platform_scope
68
+ #
69
+ def debugger service_name: nil, service_version: nil, scope: nil, timeout: nil
70
+ Google::Cloud.debugger @project, @keyfile,
71
+ service_name: service_name,
72
+ service_version: service_version,
73
+ scope: scope,
74
+ timeout: (timeout || @timeout)
75
+ end
76
+
77
+ ##
78
+ # Creates a new debugger object for instrumenting Stackdriver Debugger for
79
+ # an application. Each call creates a new debugger agent with independent
80
+ # connection service.
81
+ #
82
+ # For more information on connecting to Google Cloud see the
83
+ # {file:AUTHENTICATION.md Authentication Guide}.
84
+ #
85
+ # @param [String] project_id Project identifier for the Stackdriver Debugger
86
+ # service you are connecting to. If not present, the default project for
87
+ # the credentials is used.
88
+ # @param [String, Hash, Google::Auth::Credentials] credentials The path to
89
+ # the keyfile as a String, the contents of the keyfile as a Hash, or a
90
+ # Google::Auth::Credentials object. (See {Debugger::Credentials})
91
+ # @param [String] service_name Name for the debuggee application. Optional.
92
+ # @param [String] service_version Version identifier for the debuggee
93
+ # @param [String, Array<String>] scope The OAuth 2.0 scopes controlling the
94
+ # set of resources and operations that the connection can access. See
95
+ # [Using OAuth 2.0 to Access Google
96
+ # APIs](https://developers.google.com/identity/protocols/OAuth2).
97
+ #
98
+ # The default scope is:
99
+ #
100
+ # * `https://www.googleapis.com/auth/cloud_debugger`
101
+ # * `https://www.googleapis.com/auth/logging.admin`
102
+ #
103
+ # @param [Integer] timeout Default timeout to use in requests. Optional.
104
+ #
105
+ # @return [Google::Cloud::Debugger::Project]
106
+ #
107
+ # @example
108
+ # require "google/cloud"
109
+ #
110
+ # debugger = Google::Cloud.debugger
111
+ #
112
+ # debugger.start
113
+ #
114
+ def self.debugger project_id = nil, credentials = nil, service_name: nil,
115
+ service_version: nil, scope: nil, timeout: nil
116
+ require "google/cloud/debugger"
117
+ Google::Cloud::Debugger.new project_id: project_id,
118
+ credentials: credentials,
119
+ service_name: service_name,
120
+ service_version: service_version,
121
+ scope: scope, timeout: timeout
122
+ end
123
+ end
124
+ end
125
+
126
+ # Add debugger to top-level configuration
127
+ Google::Cloud.configure do |config|
128
+ unless config.field? :use_debugger
129
+ config.add_field! :use_debugger, nil, enum: [true, false]
130
+ end
131
+ unless config.field? :service_name
132
+ config.add_field! :service_name, nil, match: String
133
+ end
134
+ unless config.field? :service_version
135
+ config.add_field! :service_version, nil, match: String
136
+ end
137
+ end
138
+
139
+ # Set the default debugger configuration
140
+ Google::Cloud.configure.add_config! :debugger do |config|
141
+ default_project = Google::Cloud::Config.deferred do
142
+ ENV["DEBUGGER_PROJECT"]
143
+ end
144
+ default_creds = Google::Cloud::Config.deferred do
145
+ Google::Cloud::Config.credentials_from_env \
146
+ "DEBUGGER_CREDENTIALS", "DEBUGGER_CREDENTIALS_JSON",
147
+ "DEBUGGER_KEYFILE", "DEBUGGER_KEYFILE_JSON"
148
+ end
149
+ default_service = Google::Cloud::Config.deferred do
150
+ ENV["DEBUGGER_SERVICE_NAME"]
151
+ end
152
+ default_version = Google::Cloud::Config.deferred do
153
+ ENV["DEBUGGER_SERVICE_VERSION"]
154
+ end
155
+ default_scopes = [
156
+ "https://www.googleapis.com/auth/cloud-platform",
157
+ "https://www.googleapis.com/auth/cloud_debugger",
158
+ "https://www.googleapis.com/auth/logging.admin",
159
+ "https://www.googleapis.com/auth/logging.read",
160
+ "https://www.googleapis.com/auth/logging.write"
161
+ ]
162
+
163
+ config.add_field! :project_id, default_project, match: String, allow_nil: true
164
+ config.add_alias! :project, :project_id
165
+ config.add_field! :credentials, default_creds,
166
+ match: [String, Hash, Google::Auth::Credentials],
167
+ allow_nil: true
168
+ config.add_alias! :keyfile, :credentials
169
+ config.add_field! :service_name, default_service,
170
+ match: String, allow_nil: true
171
+ config.add_field! :service_version, default_version,
172
+ match: String, allow_nil: true
173
+ config.add_field! :app_root, nil, match: String
174
+ config.add_field! :root, nil, match: String
175
+ config.add_field! :scope, default_scopes, match: [String, Array]
176
+ config.add_field! :timeout, nil, match: Integer
177
+ config.add_field! :endpoint, "clouddebugger.googleapis.com", match: String
178
+ config.add_field! :allow_mutating_methods, false
179
+ config.add_field! :evaluation_time_limit, 0.05, match: Numeric
180
+ config.add_field! :on_error, nil, match: Proc
181
+ end
@@ -0,0 +1,259 @@
1
+ # Copyright 2017 Google LLC
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
+ # https://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"
17
+ require "google/cloud/debugger/project"
18
+ require "google/cloud/config"
19
+ require "google/cloud/env"
20
+ require "stackdriver/core"
21
+
22
+ module Google
23
+ module Cloud
24
+ ##
25
+ # # Stackdriver Debugger
26
+ #
27
+ # Stackdriver Debugger is a feature of the Google Cloud Platform that lets
28
+ # you inspect the state of an application at any code location without using
29
+ # logging statements and without stopping or slowing down your applications.
30
+ # Your users are not impacted during debugging. Using the production
31
+ # debugger you can capture the local variables and call stack and link it
32
+ # back to a specific line location in your source code. You can use this to
33
+ # analyze the production state of your application and understand the
34
+ # behavior of your code in production.
35
+ #
36
+ # See {file:OVERVIEW.md Debugger Overview}.
37
+ #
38
+ module Debugger
39
+ # rubocop:disable all
40
+
41
+ ##
42
+ # Creates a new debugger object for instrumenting Stackdriver Debugger for
43
+ # an application. Each call creates a new debugger agent with independent
44
+ # connection service.
45
+ #
46
+ # For more information on connecting to Google Cloud see the
47
+ # {file:AUTHENTICATION.md Authentication Guide}.
48
+ #
49
+ # @param [String] project_id Project identifier for the Stackdriver
50
+ # Debugger service you are connecting to. If not present, the default
51
+ # project for the credentials is used.
52
+ # @param [String, Hash, Google::Auth::Credentials] credentials The path to
53
+ # the keyfile as a String, the contents of the keyfile as a Hash, or a
54
+ # Google::Auth::Credentials object. (See {Debugger::Credentials})
55
+ # @param [String] service_name Name for the debuggee application.
56
+ # Optional.
57
+ # @param [String] service_version Version identifier for the debuggee
58
+ # application. Optional.
59
+ # @param [String, Array<String>] scope The OAuth 2.0 scopes controlling
60
+ # the set of resources and operations that the connection can access.
61
+ # See [Using OAuth 2.0 to Access Google
62
+ # APIs](https://developers.google.com/identity/protocols/OAuth2).
63
+ #
64
+ # The default scope is:
65
+ #
66
+ # * `https://www.googleapis.com/auth/cloud_debugger`
67
+ # * `https://www.googleapis.com/auth/logging.admin`
68
+ #
69
+ # @param [Integer] timeout Default timeout to use in requests. Optional.
70
+ # @param [String] endpoint Override of the endpoint host name. Optional.
71
+ # If the param is nil, uses the default endpoint.
72
+ # @param [String] project Project identifier for the Stackdriver Debugger
73
+ # service.
74
+ # @param [String, Hash] keyfile Keyfile downloaded from Google Cloud:
75
+ # either the JSON data or the path to a readable file.
76
+ #
77
+ # @return [Google::Cloud::Debugger::Project]
78
+ #
79
+ # @example
80
+ # require "google/cloud/debugger"
81
+ #
82
+ # debugger = Google::Cloud::Debugger.new
83
+ # debugger.start
84
+ #
85
+ def self.new project_id: nil,
86
+ credentials: nil,
87
+ service_name: nil,
88
+ service_version: nil,
89
+ scope: nil,
90
+ timeout: nil,
91
+ endpoint: nil,
92
+ project: nil,
93
+ keyfile: nil
94
+ project_id ||= (project || default_project_id)
95
+ service_name ||= default_service_name
96
+ service_version ||= default_service_version
97
+ scope ||= configure.scope
98
+ timeout ||= configure.timeout
99
+ endpoint ||= configure.endpoint
100
+
101
+ service_name = service_name.to_s
102
+ raise ArgumentError, "service_name is missing" if service_name.empty?
103
+
104
+ service_version = service_version.to_s
105
+ if service_version.nil?
106
+ raise ArgumentError, "service_version is missing"
107
+ end
108
+
109
+ credentials ||= (keyfile || default_credentials(scope: scope))
110
+ unless credentials.is_a? Google::Auth::Credentials
111
+ credentials = Debugger::Credentials.new credentials, scope: scope
112
+ end
113
+
114
+ if credentials.respond_to? :project_id
115
+ project_id ||= credentials.project_id
116
+ end
117
+ project_id = project_id.to_s # Always cast to a string
118
+ raise ArgumentError, "project_id is missing" if project_id.empty?
119
+
120
+ service = Debugger::Service.new project_id, credentials, host: endpoint, timeout: timeout
121
+ Debugger::Project.new service, service_name: service_name, service_version: service_version
122
+ end
123
+
124
+ # rubocop:enable all
125
+
126
+ ##
127
+ # Configure the Stackdriver Debugger agent.
128
+ #
129
+ # The following Stackdriver Debugger configuration parameters are
130
+ # supported:
131
+ #
132
+ # * `project_id` - (String) Project identifier for the Stackdriver
133
+ # Debugger service you are connecting to. (The parameter `project` is
134
+ # considered deprecated, but may also be used.)
135
+ # * `credentials` - (String, Hash, Google::Auth::Credentials) The path to
136
+ # the keyfile as a String, the contents of the keyfile as a Hash, or a
137
+ # Google::Auth::Credentials object. (See {Debugger::Credentials}) (The
138
+ # parameter `keyfile` is considered deprecated, but may also be used.)
139
+ # * `service_name` - (String) Name for the debuggee application.
140
+ # * `service_version` - (String) Version identifier for the debuggee
141
+ # application.
142
+ # * `root` - (String) The root directory of the debuggee application as an
143
+ # absolute file path.
144
+ # * `scope` - (String, Array<String>) The OAuth 2.0 scopes controlling
145
+ # the set of resources and operations that the connection can access.
146
+ # * `timeout` - (Integer) Default timeout to use in requests.
147
+ # * `endpoint` - (String) Override of the endpoint host name, or `nil`
148
+ # to use the default endpoint.
149
+ # * `allow_mutating_methods` - (boolean) Whether expressions and
150
+ # conditional breakpoints can call methods that could modify program
151
+ # state. Defaults to false.
152
+ # * `evaluation_time_limit` - (Numeric) Time limit in seconds for
153
+ # expression evaluation. Defaults to 0.05.
154
+ # * `on_error` - (Proc) A Proc to be run when an error is encountered
155
+ # on a background thread. The Proc must take the error object as the
156
+ # single argument.
157
+ #
158
+ # See the [Configuration
159
+ # Guide](https://googleapis.dev/ruby/stackdriver/latest/file.INSTRUMENTATION_CONFIGURATION.html)
160
+ # for full configuration parameters.
161
+ #
162
+ # @return [Google::Cloud::Config] The configuration object the
163
+ # Google::Cloud::Debugger module uses.
164
+ #
165
+ def self.configure
166
+ yield Google::Cloud.configure.debugger if block_given?
167
+
168
+ Google::Cloud.configure.debugger
169
+ end
170
+
171
+ ##
172
+ # @private Default project.
173
+ def self.default_project_id
174
+ Google::Cloud.configure.debugger.project_id ||
175
+ Google::Cloud.configure.project_id ||
176
+ Google::Cloud.env.project_id
177
+ end
178
+
179
+ ##
180
+ # @private Default service name identifier.
181
+ def self.default_service_name
182
+ Google::Cloud.configure.debugger.service_name ||
183
+ Google::Cloud.configure.service_name ||
184
+ Google::Cloud.env.app_engine_service_id ||
185
+ "ruby-app"
186
+ end
187
+
188
+ ##
189
+ # @private Default service version identifier.
190
+ def self.default_service_version
191
+ Google::Cloud.configure.debugger.service_version ||
192
+ Google::Cloud.configure.service_version ||
193
+ Google::Cloud.env.app_engine_service_version ||
194
+ ""
195
+ end
196
+
197
+ ##
198
+ # @private Default credentials.
199
+ def self.default_credentials scope: nil
200
+ Google::Cloud.configure.debugger.credentials ||
201
+ Google::Cloud.configure.credentials ||
202
+ Debugger::Credentials.default(scope: scope)
203
+ end
204
+
205
+ ##
206
+ # Allow calling of potentially state-changing methods even if mutation
207
+ # detection is configured to be active.
208
+ #
209
+ # Generally it is unwise to run code that may change the program state
210
+ # (e.g. modifying instance variables or causing other side effects) in a
211
+ # breakpoint expression, because it could change the behavior of your
212
+ # program. However, the checks are currently quite conservative, and may
213
+ # block code that is actually safe to run. If you are certain your
214
+ # expression is safe to evaluate, you may use this method to disable
215
+ # side effect checks.
216
+ #
217
+ # This method may be called with a block, in which case checks are
218
+ # disabled within the block. It may also be called without a block to
219
+ # disable side effect checks for the rest of the current expression; the
220
+ # default setting will be restored for the next expression.
221
+ #
222
+ # This method may be called only from a debugger condition or expression
223
+ # evaluation, and will throw an exception if you call it from normal
224
+ # application code. Set the `allow_mutating_methods` configuration if you
225
+ # want to disable the side effect checker globally for your app.
226
+ #
227
+ # @example Disabling side effect detection in a block
228
+ # # This is an expression evaluated in a debugger snapshot
229
+ # Google::Cloud::Debugger.allow_mutating_methods! do
230
+ # obj1.method_with_potential_side_effects
231
+ # end
232
+ #
233
+ # @example Disabling side effect detection for the rest of the expression
234
+ # # This is an expression evaluated in a debugger snapshot
235
+ # Google::Cloud::Debugger.allow_mutating_methods!
236
+ # obj1.method_with_potential_side_effects
237
+ # obj2.another_method_with_potential_side_effects
238
+ #
239
+ # @example Globally disabling side effect detection at app initialization
240
+ # require "google/cloud/debugger"
241
+ # Google::Cloud::Debugger.configure.allow_mutating_methods = true
242
+ #
243
+ def self.allow_mutating_methods! &block
244
+ evaluator = Breakpoint::Evaluator.current
245
+ if evaluator.nil?
246
+ raise "allow_mutating_methods can be called only during evaluation"
247
+ end
248
+ evaluator.allow_mutating_methods!(&block)
249
+ end
250
+ end
251
+ end
252
+
253
+ # Aliases for compatibility with older spellings.
254
+ # @private
255
+ module Devtools
256
+ # @private
257
+ Clouddebugger = ::Google::Cloud::Debugger unless const_defined? :Clouddebugger
258
+ end
259
+ end