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,110 @@
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/errors"
17
+ require "google/cloud/debugger/agent"
18
+ require "google/cloud/debugger/credentials"
19
+ require "google/cloud/debugger/middleware"
20
+ require "google/cloud/debugger/service"
21
+
22
+ module Google
23
+ module Cloud
24
+ module Debugger
25
+ ##
26
+ # # Project
27
+ #
28
+ # Projects are top-level containers in Google Cloud Platform. They store
29
+ # information about billing and authorized users, and they control access
30
+ # to Stackdriver Debugger resources. Each project has a friendly name and
31
+ # a unique ID. Projects can be created only in the [Google Developers
32
+ # Console](https://console.developers.google.com).
33
+ #
34
+ # @example
35
+ # require "google/cloud/debugger"
36
+ #
37
+ # debugger = Google::Cloud::Debugger.new
38
+ # debugger.start
39
+ #
40
+ # See Google::Cloud#debugger
41
+ class Project
42
+ ##
43
+ # @private The gRPC Service object.
44
+ attr_accessor :service
45
+
46
+ ##
47
+ # The Stackdriver Debugger Agent object.
48
+ attr_reader :agent
49
+
50
+ ##
51
+ # @private Creates a new Project instance.
52
+ def initialize service, service_name:, service_version:
53
+ @service = service
54
+ @agent = Agent.new service, service_name: service_name,
55
+ service_version: service_version
56
+ end
57
+
58
+ ##
59
+ # The ID of the current project.
60
+ #
61
+ # @return [String] the Google Cloud project ID
62
+ #
63
+ # @example
64
+ # require "google/cloud/debugger"
65
+ #
66
+ # debugger = Google::Cloud::Debugger.new(
67
+ # project_id: "my-project",
68
+ # credentials: "/path/to/keyfile.json"
69
+ # )
70
+ #
71
+ # debugger.project_id #=> "my-project"
72
+ #
73
+ def project_id
74
+ service.project
75
+ end
76
+ alias project project_id
77
+
78
+ ##
79
+ # Start the Stackdriver Debugger Agent.
80
+ #
81
+ # @example
82
+ # require "google/cloud/debugger"
83
+ #
84
+ # debugger = Google::Cloud::Debugger.new
85
+ # debugger.start
86
+ #
87
+ # See {Agent#start} for more details.
88
+ def start
89
+ agent.start
90
+ end
91
+ alias attach start
92
+
93
+ ##
94
+ # Stop the Stackdriver Debugger Agent.
95
+ #
96
+ # @example
97
+ # require "google/cloud/debugger"
98
+ #
99
+ # debugger = Google::Cloud::Debugger.new
100
+ # debugger.start
101
+ # debugger.stop
102
+ #
103
+ # See {Agent#stop} for more details.
104
+ def stop
105
+ agent.stop
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,174 @@
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
+
18
+ module Google
19
+ module Cloud
20
+ module Debugger
21
+ ##
22
+ # # Railtie
23
+ #
24
+ # Google::Cloud::Debugger::Railtie automatically adds the
25
+ # Google::Cloud::Debugger::Middleware to Rack in a Rails environment.
26
+ #
27
+ # The Middleware is only added when the
28
+ # `Google::Cloud.configure.use_debugger` setting is true or Rails is
29
+ # in the production environment.
30
+ #
31
+ # When loaded, the Google::Cloud::Debugger::Middleware will be inserted
32
+ # after the Rack::ETag Middleware, which is top of the Rack stack, closest
33
+ # to the application code.
34
+ #
35
+ # The Railtie should also initialize a debugger to be used by the
36
+ # Middleware. See the [Configuration
37
+ # Guide](https://googleapis.dev/ruby/stackdriver/latest/file.INSTRUMENTATION_CONFIGURATION.html)
38
+ # on how to configure the Railtie and Middleware.
39
+ #
40
+ class Railtie < ::Rails::Railtie
41
+ ##
42
+ # Inform the Railtie that it is safe to start debugger agents.
43
+ # This simply calls {Google::Cloud::Debugger::Middleware.start_agents}.
44
+ # See its documentation for more information.
45
+ #
46
+ def self.start_agents
47
+ Google::Cloud::Debugger::Middleware.start_agents
48
+ end
49
+
50
+ config.google_cloud = ::ActiveSupport::OrderedOptions.new unless
51
+ config.respond_to? :google_cloud
52
+ config.google_cloud[:debugger] = ::ActiveSupport::OrderedOptions.new
53
+ config.google_cloud.define_singleton_method :debugger do
54
+ self[:debugger]
55
+ end
56
+
57
+ initializer "Stackdriver.Debugger" do |app|
58
+ self.class.consolidate_rails_config app.config
59
+
60
+ self.class.init_middleware app if Cloud.configure.use_debugger
61
+ end
62
+
63
+ ##
64
+ # @private Init Debugger integration for Rails. Setup configuration and
65
+ # insert the Middleware.
66
+ def self.init_middleware app
67
+ app.middleware.insert_after Rack::ETag,
68
+ Google::Cloud::Debugger::Middleware
69
+ end
70
+
71
+ ##
72
+ # @private Consolidate Rails configuration into Debugger instrumentation
73
+ # configuration. Also consolidate the `use_debugger` setting by
74
+ # verifying credentials and Rails environment. The `use_debugger`
75
+ # setting will be true if credentials are valid, and the setting is
76
+ # manually set to true or Rails is in the production environment.
77
+ #
78
+ # @param [Rails::Railtie::Configuration] config The
79
+ # Rails.application.config
80
+ #
81
+ def self.consolidate_rails_config config
82
+ merge_rails_config config
83
+
84
+ init_default_config
85
+
86
+ # Done if Google::Cloud.configure.use_debugger is explicitly
87
+ # false
88
+ return if Google::Cloud.configure.use_debugger == false
89
+
90
+ # Verify credentials and set use_debugger to false if
91
+ # credentials are invalid
92
+ unless valid_credentials? Debugger.configure.project_id,
93
+ Debugger.configure.credentials
94
+ Cloud.configure.use_debugger = false
95
+ return
96
+ end
97
+
98
+ # Otherwise set use_debugger to true if Rails is running in
99
+ # the production environment
100
+ Google::Cloud.configure.use_debugger ||= ::Rails.env.production?
101
+ end
102
+
103
+ # rubocop:disable all
104
+
105
+ ##
106
+ # @private Merge Rails configuration into Debugger instrumentation
107
+ # configuration.
108
+ def self.merge_rails_config rails_config
109
+ gcp_config = rails_config.google_cloud
110
+ dbg_config = gcp_config.debugger
111
+
112
+ if Cloud.configure.use_debugger.nil?
113
+ Cloud.configure.use_debugger = gcp_config.use_debugger
114
+ end
115
+ Debugger.configure do |config|
116
+ config.project_id ||= begin
117
+ config.project || dbg_config.project_id || dbg_config.project
118
+ gcp_config.project_id || gcp_config.project
119
+ end
120
+ config.credentials ||= begin
121
+ config.keyfile || dbg_config.credentials || dbg_config.keyfile
122
+ gcp_config.credentials || gcp_config.keyfile
123
+ end
124
+ config.service_name ||= \
125
+ (dbg_config.service_name || gcp_config.service_name)
126
+ config.service_version ||= \
127
+ (dbg_config.service_version || gcp_config.service_version)
128
+ end
129
+ end
130
+
131
+ # rubocop:enable all
132
+
133
+ ##
134
+ # Fallback to default config values if config parameters not provided.
135
+ def self.init_default_config
136
+ config = Debugger.configure
137
+ config.project_id ||= Debugger.default_project_id
138
+ config.service_name ||= Debugger.default_service_name
139
+ config.service_version ||= Debugger.default_service_version
140
+ end
141
+
142
+ ##
143
+ # @private Verify credentials
144
+ def self.valid_credentials? project_id, credentials
145
+ begin
146
+ # if credentials is nil, get default
147
+ credentials ||= Debugger::Credentials.default
148
+ # only create a new Credentials object if the val isn't one already
149
+ unless credentials.is_a? Google::Auth::Credentials
150
+ # if credentials is not a Credentials object, create one
151
+ Debugger::Credentials.new credentials
152
+ end
153
+ rescue StandardError => e
154
+ STDOUT.puts "Note: Google::Cloud::Debugger is disabled because " \
155
+ "it failed to authorize with the service. (#{e.message})"
156
+ return false
157
+ end
158
+
159
+ if project_id.to_s.empty?
160
+ STDOUT.puts "Note: Google::Cloud::Debugger is disabled because " \
161
+ "the project ID could not be determined."
162
+ return false
163
+ end
164
+
165
+ true
166
+ end
167
+
168
+ private_class_method :merge_rails_config,
169
+ :init_default_config,
170
+ :valid_credentials?
171
+ end
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,95 @@
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
+ module Google
17
+ module Cloud
18
+ module Debugger
19
+ ##
20
+ # # RequestQuotaManager
21
+ #
22
+ # Tracking object used by debugger agent to manage quota in
23
+ # request-based applications. This class tracks the amount of time
24
+ # and number of breakpoints to evaluation in a single session.
25
+ #
26
+ # The debugger agent doesn't have use a quota manager by default, which
27
+ # means it will evaluate all breakpoints encountered and takes as much
28
+ # time as needed. This class is utilized by
29
+ # {Google::Cloud::Debugger::Middleware} class to limit latency overhead
30
+ # when used in Rack-based applications.
31
+ #
32
+ class RequestQuotaManager
33
+ # Default Total time allowed to consume, in seconds
34
+ DEFAULT_TIME_QUOTA = 0.05
35
+
36
+ # Default max number of breakpoints to evaluate
37
+ DEFAULT_COUNT_QUOTA = 10
38
+
39
+ ##
40
+ # The time quota for this manager
41
+ attr_accessor :time_quota
42
+
43
+ ##
44
+ # The count quota for this manager
45
+ attr_accessor :count_quota
46
+
47
+ ##
48
+ # The time quota used
49
+ attr_accessor :time_used
50
+
51
+ ##
52
+ # The count quota used
53
+ attr_accessor :count_used
54
+
55
+ ##
56
+ # Construct a new RequestQuotaManager instance
57
+ #
58
+ # @param [Float] time_quota The max quota for time consumed.
59
+ # @param [Integer] count_quota The max quota for count usage.
60
+ def initialize time_quota: DEFAULT_TIME_QUOTA,
61
+ count_quota: DEFAULT_COUNT_QUOTA
62
+ @time_quota = time_quota
63
+ @time_used = 0
64
+ @count_quota = count_quota
65
+ @count_used = 0
66
+ end
67
+
68
+ ##
69
+ # Check if there's more quota left.
70
+ #
71
+ # @return [Boolean] True if there's more quota; false otherwise.
72
+ def more?
73
+ (time_used < time_quota) && (count_used < count_quota)
74
+ end
75
+
76
+ ##
77
+ # Reset all the quota usage.
78
+ def reset
79
+ @time_used = 0
80
+ @count_used = 0
81
+ end
82
+
83
+ ##
84
+ # Notify the quota manager some resource has been consumed. Each time
85
+ # called increases the count quota usage.
86
+ #
87
+ # @param [Float] time Amount of time to deduct from the time quota.
88
+ def consume time: 0
89
+ @time_used += time
90
+ @count_used += 1
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,88 @@
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/errors"
17
+ require "google/cloud/debugger/version"
18
+ require "google/cloud/debugger/v2"
19
+ require "uri"
20
+
21
+ module Google
22
+ module Cloud
23
+ module Debugger
24
+ ##
25
+ # @private Represents the gRPC Debugger service, including all the API
26
+ # methods.
27
+ class Service
28
+ attr_accessor :project, :credentials, :timeout, :host
29
+
30
+ ##
31
+ # Creates a new Service instance.
32
+ def initialize project, credentials, timeout: nil, host: nil
33
+ @project = project
34
+ @credentials = credentials
35
+ @timeout = timeout
36
+ @host = host
37
+ end
38
+
39
+ def cloud_debugger
40
+ return mocked_debugger if mocked_debugger
41
+ @cloud_debugger ||=
42
+ V2::Controller::Client.new do |config|
43
+ config.credentials = credentials if credentials
44
+ config.timeout = timeout if timeout
45
+ config.endpoint = host if host
46
+ config.lib_name = "gccl"
47
+ config.lib_version = Google::Cloud::Debugger::VERSION
48
+ config.metadata = { "google-cloud-resource-prefix" => "projects/#{@project}" }
49
+ end
50
+ end
51
+ attr_accessor :mocked_debugger
52
+
53
+ def transmitter
54
+ return mocked_transmitter if mocked_transmitter
55
+ @transmitter ||=
56
+ V2::Controller::Client.new do |config|
57
+ config.credentials = credentials if credentials
58
+ config.timeout = timeout if timeout
59
+ config.endpoint = host if host
60
+ config.lib_name = "gccl"
61
+ config.lib_version = Google::Cloud::Debugger::VERSION
62
+ config.metadata = { "google-cloud-resource-prefix" => "projects/#{@project}" }
63
+ end
64
+ end
65
+ attr_accessor :mocked_transmitter
66
+
67
+ def register_debuggee debuggee_grpc
68
+ cloud_debugger.register_debuggee debuggee: debuggee_grpc
69
+ end
70
+
71
+ def list_active_breakpoints debuggee_id, wait_token
72
+ cloud_debugger.list_active_breakpoints debuggee_id: debuggee_id.to_s,
73
+ wait_token: wait_token.to_s,
74
+ success_on_timeout: true
75
+ end
76
+
77
+ def update_active_breakpoint debuggee_id, breakpoint
78
+ transmitter.update_active_breakpoint debuggee_id: debuggee_id.to_s,
79
+ breakpoint: breakpoint.to_grpc
80
+ end
81
+
82
+ def inspect
83
+ "#{self.class}(#{@project})"
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end