google-cloud-debugger 0.40.0

Sign up to get free protection for your applications and to get access to all the features.
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