google-cloud-error_reporting 0.30.5 → 0.31.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df53fba39b31fef5256a2fb3e35160f868eaaea7e6332b71ea779c9edb55c11c
4
- data.tar.gz: 28bea2c9d8caa7eb94f69ad8ea64fb243c9920449cff4396bc5220726d834f07
3
+ metadata.gz: 2ca4dece3ad67bcf61fa206c1561305f21d2dea95e2505099818cdf5f99368e3
4
+ data.tar.gz: c91e752ce4555b646bcaa313177373b8310a6d944997560f9dc98ea7f87eb6a9
5
5
  SHA512:
6
- metadata.gz: ec08c92db16cdaf1a8fe8d6d0d4f00255d2c78c550f07ccb1dc024d9318704b5c1e57a6ded1c37228fa094fd87fc41869c98f4b9c3d7a1a773c611b74e9237d8
7
- data.tar.gz: 4099c791a52bab837c673cc8a88f02542a1f64fe9926e143af97758e72df970066898db77e8fcbb0d7a07a58fca0c5a115d132fc162670ed1b0ec8f3cda5997d
6
+ metadata.gz: 52bb1f172ce54cd572f7ff60d60c675b440f7196358d54ff9ce3f31ceb87a80c07245d1dd9f7fa4f8c9da38aa740cf8d40215a4d4fb229f2ae42ae78f8482fbe
7
+ data.tar.gz: b3d6ebf49e7e596045b86104d4cd0eb4702a493cd93581487c7456f1da0209523d0d80fa6fc0faf06e92f591d027a8b90e096b6ae3b1bb484a7f36551f9c53b0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Release History
2
2
 
3
+ ### 0.31.0 / 2019-02-01
4
+
5
+ * Add ErrorReporting on_error configuration.
6
+ * Update asynchronous error reporting implementation:
7
+ * Add dependency on concurrent-ruby.
8
+ * Fix for submitting error objects without backtrace.
9
+ * Make use of Credentials#project_id
10
+ * Use Credentials#project_id
11
+ If a project_id is not provided, use the value on the Credentials object.
12
+ This value was added in googleauth 0.7.0.
13
+ * Loosen googleauth dependency
14
+ Allow for new releases up to 0.10.
15
+ The googleauth devs have committed to maintanining the current API
16
+ and will not make backwards compatible changes before 0.10.
17
+
3
18
  ### 0.30.5 / 2018-09-20
4
19
 
5
20
  * Update documentation.
@@ -163,4 +163,5 @@ Google::Cloud.configure.add_config! :error_reporting do |config|
163
163
  config.add_field! :service_version, default_version,
164
164
  match: String, allow_nil: true
165
165
  config.add_field! :ignore_classes, nil, match: Array
166
+ config.add_field! :on_error, nil, match: Proc
166
167
  end
@@ -76,20 +76,24 @@ module Google
76
76
  #
77
77
  def self.new project_id: nil, credentials: nil, scope: nil, timeout: nil,
78
78
  client_config: nil, project: nil, keyfile: nil
79
- project_id ||= (project || ErrorReporting::Project.default_project_id)
80
- project_id = project_id.to_s
81
- raise ArgumentError, "project_id is missing" if project_id.empty?
82
-
83
- scope ||= configure.scope
84
- timeout ||= configure.timeout
79
+ project_id ||= project
80
+ project_id ||= ErrorReporting::Project.default_project_id
81
+ scope ||= configure.scope
82
+ timeout ||= configure.timeout
85
83
  client_config ||= configure.client_config
84
+ credentials ||= (keyfile || default_credentials(scope: scope))
86
85
 
87
- credentials ||= (keyfile || default_credentials(scope: scope))
88
86
  unless credentials.is_a? Google::Auth::Credentials
89
87
  credentials = ErrorReporting::Credentials.new credentials,
90
88
  scope: scope
91
89
  end
92
90
 
91
+ if credentials.respond_to? :project_id
92
+ project_id ||= credentials.project_id
93
+ end
94
+ project_id = project_id.to_s
95
+ raise ArgumentError, "project_id is missing" if project_id.empty?
96
+
93
97
  ErrorReporting::Project.new(
94
98
  ErrorReporting::Service.new(
95
99
  project_id, credentials, timeout: timeout,
@@ -123,6 +127,13 @@ module Google
123
127
  # * `service_version` - (String) Version identifier for the application.
124
128
  # * `ignore_classes` - (Array<Exception>) Array of exception types that
125
129
  # should not be reported.
130
+ # * `on_error` - (Proc) A Proc to be run when an error is encountered
131
+ # on a background thread, such as {ErrorReporting.report} or
132
+ # {Middleware}. The Proc must take the error object as the single
133
+ # argument. If ErrorReporting is being used to report errors using
134
+ # `Google::Cloud::cofigure.on_error`, then this `on_error` should be
135
+ # configured to report errors raised when reporting through
136
+ # ErrorReporting.
126
137
  #
127
138
  # See the [Configuration
128
139
  # Guide](https://googleapis.github.io/google-cloud-ruby/docs/stackdriver/latest/file.INSTRUMENTATION_CONFIGURATION)
@@ -206,6 +217,9 @@ module Google
206
217
  service_name ||= Project.default_service_name
207
218
  service_version ||= Project.default_service_version
208
219
 
220
+ # Ensure the reported exception has a backtrace
221
+ exception.set_backtrace caller if exception.backtrace.nil?
222
+
209
223
  error_event = ErrorEvent.from_exception(exception).tap do |event|
210
224
  event.service_name = service_name
211
225
  event.service_version = service_version
@@ -13,12 +13,51 @@
13
13
  # limitations under the License.
14
14
 
15
15
 
16
- require "stackdriver/core/async_actor"
17
-
16
+ require "concurrent"
17
+ require "google/cloud/errors"
18
18
 
19
19
  module Google
20
20
  module Cloud
21
21
  module ErrorReporting
22
+ ##
23
+ # # AsyncErrorReporterError
24
+ #
25
+ # @private Used to indicate a problem reporting errors asynchronously.
26
+ # This can occur when there are not enough resources allocated for the
27
+ # amount of usage.
28
+ #
29
+ class AsyncErrorReporterError < Google::Cloud::Error
30
+ # @!attribute [r] error_event
31
+ # @return [Array<Google::Cloud::ErrorReporting::ErrorEvent>] The
32
+ # individual error event that was not reported to Stackdriver Error
33
+ # Reporting service.
34
+ attr_reader :error_event
35
+
36
+ def initialize message, error_event = nil
37
+ super(message)
38
+ @error_event = error_event
39
+ end
40
+ end
41
+
42
+ ##
43
+ # # ErrorReporterError
44
+ #
45
+ # @private Used to indicate a problem reporting errors. This can occur
46
+ # when the calling the API returns an error.
47
+ #
48
+ class ErrorReporterError < Google::Cloud::Error
49
+ # @!attribute [r] error_event
50
+ # @return [Array<Google::Cloud::ErrorReporting::ErrorEvent>] The
51
+ # individual error event that was not reported to Stackdriver Error
52
+ # Reporting service.
53
+ attr_reader :error_event
54
+
55
+ def initialize message, error_event = nil
56
+ super(message)
57
+ @error_event = error_event
58
+ end
59
+ end
60
+
22
61
  ##
23
62
  # # AsyncErrorReporter
24
63
  #
@@ -27,98 +66,144 @@ module Google
27
66
  # error events to Stackdriver Error Reporting service when used in
28
67
  # Ruby applications.
29
68
  class AsyncErrorReporter
30
- include Stackdriver::Core::AsyncActor
31
-
32
69
  ##
33
- # @private Default maximum backlog size for the job queue
34
- DEFAULT_MAX_QUEUE_SIZE = 1000
70
+ # @private Implementation accessors
71
+ attr_reader :error_reporting, :max_queue, :threads, :thread_pool
35
72
 
36
73
  ##
37
- # The {Google::Cloud::ErrorReporting::Project} object to submit events
38
- # with.
39
- attr_accessor :error_reporting
74
+ # @private Creates a new AsyncErrorReporter instance.
75
+ def initialize error_reporting, max_queue: 1000, threads: 10
76
+ @error_reporting = error_reporting
40
77
 
41
- ##
42
- # The max number of items the queue holds
43
- attr_accessor :max_queue_size
78
+ @max_queue = max_queue
79
+ @threads = threads
44
80
 
45
- ##
46
- # @private Construct a new instance of AsyncErrorReporter
47
- def initialize error_reporting, max_queue_size = DEFAULT_MAX_QUEUE_SIZE
48
- super()
49
- @error_reporting = error_reporting
50
- @max_queue_size = max_queue_size
51
- @queue = []
52
- @queue_resource = new_cond
81
+ @thread_pool = Concurrent::CachedThreadPool.new max_threads: @threads,
82
+ max_queue: @max_queue
83
+
84
+ @error_callbacks = []
85
+
86
+ # Make sure all queued calls are completed when process exits.
87
+ at_exit { stop! }
53
88
  end
54
89
 
55
90
  ##
56
- # Add the error event to the queue. Signal the child thread an item
57
- # has been added.
91
+ # Add the error event to the queue. This will raise if there are no
92
+ # resources available to make the API call.
58
93
  def report error_event
59
- async_start
60
-
61
- synchronize do
62
- @queue.push error_event
63
- @queue_resource.broadcast
94
+ Concurrent::Promises.future_on(@thread_pool, error_event) do |error|
95
+ report_sync error
96
+ end
97
+ rescue Concurrent::RejectedExecutionError => e
98
+ raise AsyncErrorReporterError,
99
+ "Error reporting error_event asynchronously: #{e.message}",
100
+ error_event
101
+ end
64
102
 
65
- retries = 0
66
- while @max_queue_size && @queue.size > @max_queue_size
67
- retries += 1
68
- @queue_resource.wait 1
103
+ ##
104
+ # Begins the process of stopping the reporter. ErrorEvents already
105
+ # in the queue will be published, but no new ErrorEvent can be added.
106
+ # Use {#wait!} to block until the reporter is fully stopped and all
107
+ # pending error_events have been pushed to the API.
108
+ #
109
+ # @return [AsyncErrorReporter] returns self so calls can be chained.
110
+ def stop
111
+ @thread_pool.shutdown if @thread_pool
112
+
113
+ self
114
+ end
69
115
 
70
- # Drop early queue entries when have waited long enough.
71
- @queue.pop while @queue.size > @max_queue_size && retries > 3
72
- end
73
- end
116
+ ##
117
+ # Stop this asynchronous reporter and block until it has been stopped.
118
+ #
119
+ # @param [Number] timeout Timeout in seconds.
120
+ #
121
+ def stop! timeout = nil
122
+ stop
123
+ wait! timeout
74
124
  end
75
125
 
76
126
  ##
77
- # @private Callback fucntion for AsyncActor module to run the async
78
- # job in a loop
79
- def run_backgrounder
80
- error_event = wait_next_item
81
- return if error_event.nil?
82
- begin
83
- error_reporting.report error_event
84
- rescue StandardError => e
85
- warn error_event.message if error_event.message
86
- warn ["#{e.class}: #{e.message}", e.backtrace].join("\n\t")
87
- @last_exception = e
127
+ # Blocks until the reporter is fully stopped, all pending error_events
128
+ # have been published, and all callbacks have completed. Does not stop
129
+ # the reporter. To stop the reporter, first call {#stop} and then call
130
+ # {#wait!} to block until the reporter is stopped.
131
+ #
132
+ # @return [AsyncErrorReporter] returns self so calls can be chained.
133
+ def wait! timeout = nil
134
+ if @thread_pool
135
+ @thread_pool.shutdown
136
+ @thread_pool.wait_for_termination timeout
88
137
  end
138
+
139
+ self
89
140
  end
90
141
 
91
142
  ##
92
- # @private Callback function when the async actor thread state changes
93
- def on_async_state_change
94
- synchronize do
95
- @queue_resource.broadcast
96
- end
143
+ # Whether the reporter has been started.
144
+ #
145
+ # @return [boolean] `true` when started, `false` otherwise.
146
+ #
147
+ def started?
148
+ @thread_pool.running? if @thread_pool
97
149
  end
98
150
 
99
- private
151
+ ##
152
+ # Whether the reporter has been stopped.
153
+ #
154
+ # @return [boolean] `true` when stopped, `false` otherwise.
155
+ #
156
+ def stopped?
157
+ !started?
158
+ end
100
159
 
101
160
  ##
102
- # @private The the next item from the reporter queue. If there are
103
- # no more item, it blocks the reporter thread until an item is
104
- # enqueued
105
- def wait_next_item
106
- synchronize do
107
- @queue_resource.wait_while do
108
- async_suspended? || (async_running? && @queue.empty?)
161
+ # Register to be notified of errors when raised.
162
+ #
163
+ # If an unhandled error has occurred the reporter will attempt to
164
+ # recover from the error and resume reporting error_events.
165
+ #
166
+ # Multiple error handlers can be added.
167
+ #
168
+ # @yield [callback] The block to be called when an error is raised.
169
+ # @yieldparam [Exception] error The error raised.
170
+ #
171
+ def on_error &block
172
+ @error_callbacks << block
173
+ end
174
+
175
+ protected
176
+
177
+ # Calls all error callbacks.
178
+ def error! error
179
+ error_callbacks = @error_callbacks
180
+ error_callbacks = default_error_callbacks if error_callbacks.empty?
181
+ error_callbacks.each { |error_callback| error_callback.call error }
182
+ end
183
+
184
+ def default_error_callbacks
185
+ # This is memoized to reduce calls to the configuration.
186
+ @default_error_callbacks ||= begin
187
+ error_cb = Google::Cloud::ErrorReporting.configuration.on_error
188
+ error_cb ||= Google::Cloud.configure.on_error
189
+ if error_cb
190
+ [error_cb]
191
+ else
192
+ []
109
193
  end
110
- @queue.pop
111
194
  end
112
195
  end
113
196
 
114
- ##
115
- # @private Override the #backgrounder_stoppable? method from AsyncActor
116
- # module. The actor can be gracefully stopped when queue is
117
- # empty.
118
- def backgrounder_stoppable?
119
- synchronize do
120
- @queue.empty?
121
- end
197
+ def report_sync error_event
198
+ error_reporting.report error_event
199
+ rescue StandardError => e
200
+ sync_error = ErrorReporterError.new(
201
+ "Error reporting error_event: #{e.message}",
202
+ error_event
203
+ )
204
+ # Manually set backtrace so we don't have to raise
205
+ sync_error.set_backtrace caller
206
+ error! sync_error
122
207
  end
123
208
  end
124
209
  end
@@ -27,7 +27,7 @@ module Google
27
27
  # and report them to the Stackdriver Error Reporting service.
28
28
  #
29
29
  # The Middleware is only added when certain conditions are met. See
30
- # {Railtie.use_error_reporting?} for detail.
30
+ # `Google::Cloud.configure.use_error_reporting` for detail.
31
31
  #
32
32
  # When loaded, the {Google::Cloud::ErrorReporting::Middleware} will be
33
33
  # inserted after ActionDispatch::DebugExceptions or
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Google LLC
1
+ # Copyright 2019 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Google LLC
1
+ # Copyright 2019 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Google LLC
1
+ # Copyright 2019 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Google LLC
1
+ # Copyright 2019 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -267,6 +267,25 @@ module Google
267
267
  # Response message for deleting error events.
268
268
  class DeleteEventsResponse; end
269
269
 
270
+ # A sorting order of error groups.
271
+ module ErrorGroupOrder
272
+ # No group order specified.
273
+ GROUP_ORDER_UNSPECIFIED = 0
274
+
275
+ # Total count of errors in the given time window in descending order.
276
+ COUNT_DESC = 1
277
+
278
+ # Timestamp when the group was last seen in the given time window
279
+ # in descending order.
280
+ LAST_SEEN_DESC = 2
281
+
282
+ # Timestamp when the group was created in descending order.
283
+ CREATED_DESC = 3
284
+
285
+ # Number of affected users in the given time window in descending order.
286
+ AFFECTED_USERS_DESC = 4
287
+ end
288
+
270
289
  # Specifies how the time periods of error group counts are aligned.
271
290
  module TimedCountAlignment
272
291
  # No alignment specified.
@@ -288,25 +307,6 @@ module Google
288
307
  # first time period.
289
308
  ALIGNMENT_EQUAL_AT_END = 2
290
309
  end
291
-
292
- # A sorting order of error groups.
293
- module ErrorGroupOrder
294
- # No group order specified.
295
- GROUP_ORDER_UNSPECIFIED = 0
296
-
297
- # Total count of errors in the given time window in descending order.
298
- COUNT_DESC = 1
299
-
300
- # Timestamp when the group was last seen in the given time window
301
- # in descending order.
302
- LAST_SEEN_DESC = 2
303
-
304
- # Timestamp when the group was created in descending order.
305
- CREATED_DESC = 3
306
-
307
- # Number of affected users in the given time window in descending order.
308
- AFFECTED_USERS_DESC = 4
309
- end
310
310
  end
311
311
  end
312
312
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Google LLC
1
+ # Copyright 2019 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Google LLC
1
+ # Copyright 2019 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Google LLC
1
+ # Copyright 2019 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Google LLC
1
+ # Copyright 2019 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Google LLC
1
+ # Copyright 2019 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2018 Google LLC
1
+ # Copyright 2019 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module ErrorReporting
19
- VERSION = "0.30.5".freeze
19
+ VERSION = "0.31.0".freeze
20
20
  end
21
21
  end
22
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-cloud-error_reporting
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.30.5
4
+ version: 0.31.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Google Inc
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-21 00:00:00.000000000 Z
11
+ date: 2019-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-cloud-core
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: concurrent-ruby
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: minitest
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -128,14 +142,14 @@ dependencies:
128
142
  requirements:
129
143
  - - "~>"
130
144
  - !ruby/object:Gem::Version
131
- version: 0.50.0
145
+ version: 0.61.0
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
150
  - - "~>"
137
151
  - !ruby/object:Gem::Version
138
- version: 0.50.0
152
+ version: 0.61.0
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: railties
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -275,7 +289,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
275
289
  version: '0'
276
290
  requirements: []
277
291
  rubyforge_project:
278
- rubygems_version: 2.7.7
292
+ rubygems_version: 2.7.6
279
293
  signing_key:
280
294
  specification_version: 4
281
295
  summary: API Client library for Stackdriver Error Reporting