fluent-plugin-google-cloud 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,7 +4,7 @@ Gem::Specification.new do |gem|
4
4
  gem.summary = %q{Fluentd plugin to stream logs to the Google Cloud Platform's logging API}
5
5
  gem.homepage = 'https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud'
6
6
  gem.license = 'Apache 2.0'
7
- gem.version = '0.2.0'
7
+ gem.version = '0.2.1'
8
8
  gem.authors = ['Todd Derr', 'Alex Robinson']
9
9
  gem.email = ['salty@google.com']
10
10
 
@@ -192,24 +192,44 @@ module Fluent
192
192
  })
193
193
  client.execute!(request)
194
194
  # Allow most exceptions to propagate, which will cause fluentd to
195
- # retry (with backoff). However, most ClientErrors indicate a problem
196
- # with the request itself and should not be retried - the exception
197
- # is 'Invalid Credentials' which we can retry.
195
+ # retry (with backoff), but in some cases we catch the error and
196
+ # drop the request (we will emit a log message in those cases).
198
197
  rescue Google::APIClient::ClientError => error
199
- if (error.message == 'Invalid Credentials')
198
+ # Most ClientErrors indicate a problem with the request itself and
199
+ # should not be retried, unless it is an authentication issue, in
200
+ # which case we will retry the request via re-raising the exception.
201
+ if (is_retriable_client_error(error))
200
202
  raise error
201
203
  end
202
- # fall through to next rescue clause
204
+ log_write_failure(write_log_entries_request, error)
203
205
  rescue JSON::GeneratorError => error
206
+ # This happens if the request contains illegal characters;
207
+ # do not retry it because it will fail repeatedly.
204
208
  dropped = write_log_entries_request['entries'].length
205
- $log.warn "Dropping #{dropped} log message(s)",
206
- :error_class=>error.class.to_s, :error=>error.to_s
209
+ log_write_failure(write_log_entries_request, error)
207
210
  end
208
211
  end
209
212
  end
210
213
 
211
214
  private
212
215
 
216
+ RETRIABLE_CLIENT_ERRORS = Set.new [
217
+ 'Invalid Credentials',
218
+ 'Request had invalid credentials.',
219
+ 'The caller does not have permission',
220
+ 'Project has not enabled the API. Please use Google Developers Console to activate the API for your project.',
221
+ 'Unable to fetch access token (no scopes configured?)']
222
+
223
+ def is_retriable_client_error(error)
224
+ return RETRIABLE_CLIENT_ERRORS.include?(error.message)
225
+ end
226
+
227
+ def log_write_failure(request, error)
228
+ dropped = request['entries'].length
229
+ $log.warn "Dropping #{dropped} log message(s)",
230
+ :error_class=>error.class.to_s, :error=>error.to_s
231
+ end
232
+
213
233
  def fetch_metadata(metadata_path)
214
234
  open('http://metadata/computeMetadata/v1/' + metadata_path,
215
235
  {'Metadata-Flavor' => 'Google'}) do |f|
@@ -220,7 +240,7 @@ module Fluent
220
240
  def init_api_client
221
241
  @client = Google::APIClient.new(
222
242
  :application_name => 'Fluentd Google Cloud Logging plugin',
223
- :application_version => '0.2.0',
243
+ :application_version => '0.2.1',
224
244
  :retries => 1)
225
245
 
226
246
  if @auth_method == 'private_key'
@@ -238,7 +258,14 @@ module Fluent
238
258
 
239
259
  def api_client
240
260
  if !@client.authorization.expired?
241
- @client.authorization.fetch_access_token!
261
+ begin
262
+ @client.authorization.fetch_access_token!
263
+ rescue MultiJson::ParseError
264
+ # Workaround an issue in the API client; just re-raise a more
265
+ # descriptive error for the user (which will still cause a retry).
266
+ raise Google::APIClient::ClientError,
267
+ 'Unable to fetch access token (no scopes configured?)'
268
+ end
242
269
  end
243
270
  return @client
244
271
  end
@@ -223,23 +223,43 @@ class GoogleCloudOutputTest < Test::Unit::TestCase
223
223
  assert_requested(:post, uri_for_log(COMPUTE_PARAMS), :times => 2)
224
224
  end
225
225
 
226
- def test_client_error_invalid_credentials
227
- # we expect this to retry once, then throw the error.
226
+ # helper for the ClientError retriable special cases below.
227
+ def client_error_helper(message)
228
228
  stub_request(:post, uri_for_log(COMPUTE_PARAMS)).to_return(
229
- :status => 401, :body => "Invalid Credentials")
229
+ :status => 401, :body => message)
230
230
  d = create_driver(PRIVATE_KEY_CONFIG)
231
231
  d.emit({'message' => log_entry(0)})
232
232
  exception_count = 0
233
233
  begin
234
234
  d.run
235
235
  rescue Google::APIClient::ClientError => error
236
- assert_equal 'Invalid Credentials', error.message
236
+ assert_equal message, error.message
237
237
  exception_count += 1
238
238
  end
239
239
  assert_requested(:post, uri_for_log(COMPUTE_PARAMS), :times => 2)
240
240
  assert_equal 1, exception_count
241
241
  end
242
242
 
243
+ def test_client_error_invalid_credentials
244
+ client_error_helper("Invalid Credentials")
245
+ end
246
+
247
+ def test_client_error_caller_does_not_have_permission
248
+ client_error_helper("The caller does not have permission")
249
+ end
250
+
251
+ def test_client_error_request_had_invalid_credentials
252
+ client_error_helper("Request had invalid credentials.")
253
+ end
254
+
255
+ def test_client_error_project_has_not_enabled_the_api
256
+ client_error_helper("Project has not enabled the API. Please use Google Developers Console to activate the API for your project.")
257
+ end
258
+
259
+ def test_client_error_unable_to_fetch_accesss_token
260
+ client_error_helper("Unable to fetch access token (no scopes configured?)")
261
+ end
262
+
243
263
  def test_server_error
244
264
  # The API client should retry this once, then throw an exception which
245
265
  # gets propagated through the plugin.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-google-cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-02-23 00:00:00.000000000 Z
13
+ date: 2015-03-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: fluentd