fluent-plugin-cloudwatch-logs 0.2.3 → 0.2.4

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
  SHA1:
3
- metadata.gz: 5082b725cf548ffea0fb7e779c6c24a4d7bb7909
4
- data.tar.gz: 6a8dbc8986550ec45e9fb3518316f19d7267ac8e
3
+ metadata.gz: 177bb1a6b7af9c6565f1cd5104f422c1fb48add7
4
+ data.tar.gz: 576f39a7a7cec61aa655aefbc60549f1787f9f77
5
5
  SHA512:
6
- metadata.gz: f8321eeaa7a481dae684a5908446782a5ba570b1bcc9bbeec86a63d4a365340923a4478536a471a4480aa32b6017a537c5023ee87dd5d0144d62cab252f0c6fd
7
- data.tar.gz: c57ab7ca6be0756ad4377b3b7cf12cc69b6f4e141b82c5c5cc664fe493fe22f705758c5e3c4be2d00fcec55d98c892c8c325c3f17b453acd899b7ccf266b01cb
6
+ metadata.gz: 998c9861c7db2ed024ef27c2011a70a52a8648797f2b5f5891381f6c5620b2d4074279b0e682b2123f0f6f9a90d197f388943fec9416271c6f045261d39b326e
7
+ data.tar.gz: 900de6d31aeb5e62f6695c9ae016e16470ce0c550cb2e9b0851d03a073095862808dab9093a22586709ff05310445c47c7134c89b8a4485c0032ef69e8998dbe
data/README.md CHANGED
@@ -79,6 +79,9 @@ Fetch sample log from CloudWatch Logs:
79
79
  #log_stream_name_key stream_name_key
80
80
  #remove_log_group_name_key true
81
81
  #remove_log_stream_name_key true
82
+ #put_log_events_retry_wait 1s
83
+ #put_log_events_retry_limit 17
84
+ #put_log_events_disable_retry_limit false
82
85
  </match>
83
86
  ```
84
87
 
@@ -96,6 +99,9 @@ Fetch sample log from CloudWatch Logs:
96
99
  * `log_stream_name_key`: use specified field of records as log stream name
97
100
  * `remove_log_group_name_key`: remove field specified by `log_group_name_key`
98
101
  * `remove_log_stream_name_key`: remove field specified by `log_stream_name_key`
102
+ * `put_log_events_retry_wait`: time before retrying PutLogEvents (retry interval increases exponentially like `put_log_events_retry_wait * (2 ^ retry_count)`)
103
+ * `put_log_events_retry_limit`: maximum count of retry (if exceeding this, the events will be discarded)
104
+ * `put_log_events_disable_retry_limit`: if true, `put_log_events_retry_limit` will be ignored
99
105
 
100
106
  ### in_cloudwatch_logs
101
107
 
@@ -24,4 +24,5 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency "bundler", "~> 1.6"
25
25
  spec.add_development_dependency "rake"
26
26
  spec.add_development_dependency "test-unit"
27
+ spec.add_development_dependency "mocha"
27
28
  end
@@ -2,7 +2,7 @@ module Fluent
2
2
  module Plugin
3
3
  module Cloudwatch
4
4
  module Logs
5
- VERSION = "0.2.3"
5
+ VERSION = "0.2.4"
6
6
  end
7
7
  end
8
8
  end
@@ -23,6 +23,9 @@ module Fluent
23
23
  config_param :remove_log_group_name_key, :bool, :default => false
24
24
  config_param :remove_log_stream_name_key, :bool, :default => false
25
25
  config_param :http_proxy, :string, default: nil
26
+ config_param :put_log_events_retry_wait, :time, default: 1.0
27
+ config_param :put_log_events_retry_limit, :integer, default: 17
28
+ config_param :put_log_events_disable_retry_limit, :bool, default: false
26
29
 
27
30
  MAX_EVENTS_SIZE = 1_048_576
28
31
  EVENT_HEADER_SIZE = 26
@@ -60,7 +63,7 @@ module Fluent
60
63
  options[:credentials] = Aws::Credentials.new(@aws_key_id, @aws_sec_key) if @aws_key_id && @aws_sec_key
61
64
  options[:region] = @region if @region
62
65
  options[:http_proxy] = @http_proxy if @http_proxy
63
- @logs = Aws::CloudWatchLogs::Client.new(options)
66
+ @logs ||= Aws::CloudWatchLogs::Client.new(options)
64
67
  @sequence_tokens = {}
65
68
  end
66
69
 
@@ -191,14 +194,42 @@ module Fluent
191
194
  token = next_sequence_token(group_name, stream_name)
192
195
  args[:sequence_token] = token if token
193
196
 
194
- log.debug "Calling PutLogEvents API", {
195
- "group" => group_name,
196
- "stream" => stream_name,
197
- "events_count" => events.size,
198
- "events_bytesize" => events_bytesize,
199
- }
197
+ response = nil
198
+ retry_count = 0
199
+ until response
200
+ log.debug "Calling PutLogEvents API", {
201
+ "group" => group_name,
202
+ "stream" => stream_name,
203
+ "events_count" => events.size,
204
+ "events_bytesize" => events_bytesize,
205
+ }
206
+ begin
207
+ response = @logs.put_log_events(args)
208
+ rescue Aws::CloudWatchLogs::Errors::ThrottlingException => err
209
+ if !@put_log_events_disable_retry_limit && @put_log_events_retry_limit < retry_count
210
+ log.error "failed to PutLogEvents and discard logs because retry count exceeded put_log_events_retry_limit", {
211
+ "error_class" => err.class.to_s,
212
+ "error" => err.message,
213
+ }
214
+ return
215
+ else
216
+ sleep_sec = @put_log_events_retry_wait * (2 ** retry_count)
217
+ sleep_sec += sleep_sec * (0.25 * (rand - 0.5))
218
+ log.warn "failed to PutLogEvents", {
219
+ "next_retry" => Time.now + sleep_sec,
220
+ "error_class" => err.class.to_s,
221
+ "error" => err.message,
222
+ }
223
+ sleep(sleep_sec)
224
+ retry_count += 1
225
+ end
226
+ end
227
+ end
228
+
229
+ if 0 < retry_count
230
+ log.warn "retry succeeded"
231
+ end
200
232
 
201
- response = @logs.put_log_events(args)
202
233
  store_next_sequence_token(group_name, stream_name, response.next_sequence_token)
203
234
  end
204
235
 
@@ -291,6 +291,49 @@ class CloudwatchLogsOutputTest < Test::Unit::TestCase
291
291
  assert_equal({'cloudwatch' => 'logs1', 'message' => 'message1'}, JSON.parse(events[0].message))
292
292
  end
293
293
 
294
+ def test_retrying_on_throttling_exception
295
+ resp = mock()
296
+ resp.expects(:next_sequence_token)
297
+ client = Aws::CloudWatchLogs::Client.new
298
+ client.stubs(:put_log_events).
299
+ raises(Aws::CloudWatchLogs::Errors::ThrottlingException.new(nil, "error")).then.returns(resp)
300
+
301
+ time = Time.now
302
+ d = create_driver
303
+ d.instance.instance_variable_set(:@logs, client)
304
+ d.emit({'message' => 'message1'}, time.to_i)
305
+ d.run
306
+
307
+ assert_match(/Calling PutLogEvents/, d.instance.log.logs[0])
308
+ assert_match(/failed to PutLogEvents/, d.instance.log.logs[1])
309
+ assert_match(/Calling PutLogEvents/, d.instance.log.logs[2])
310
+ assert_match(/retry succeeded/, d.instance.log.logs[3])
311
+ end
312
+
313
+ def test_retrying_on_throttling_exception_and_throw_away
314
+ client = Aws::CloudWatchLogs::Client.new
315
+ client.stubs(:put_log_events).
316
+ raises(Aws::CloudWatchLogs::Errors::ThrottlingException.new(nil, "error"))
317
+
318
+ time = Time.now
319
+ d = create_driver(<<-EOC)
320
+ #{default_config}
321
+ log_group_name #{log_group_name}
322
+ log_stream_name #{log_stream_name}
323
+ put_log_events_retry_limit 1
324
+ EOC
325
+ d.instance.instance_variable_set(:@logs, client)
326
+ d.emit({'message' => 'message1'}, time.to_i)
327
+ d.run
328
+
329
+ assert_match(/Calling PutLogEvents/, d.instance.log.logs[0])
330
+ assert_match(/failed to PutLogEvents/, d.instance.log.logs[1])
331
+ assert_match(/Calling PutLogEvents/, d.instance.log.logs[2])
332
+ assert_match(/failed to PutLogEvents/, d.instance.log.logs[3])
333
+ assert_match(/Calling PutLogEvents/, d.instance.log.logs[4])
334
+ assert_match(/failed to PutLogEvents and throwing away/, d.instance.log.logs[5])
335
+ end
336
+
294
337
  private
295
338
  def default_config
296
339
  <<-EOC
data/test/test_helper.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'test/unit'
2
+ require 'mocha/test_unit'
2
3
  require 'fluent/test'
3
4
 
4
5
  require 'aws-sdk-core'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-cloudwatch-logs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryota Arai
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-18 00:00:00.000000000 Z
11
+ date: 2016-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: mocha
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  description:
98
112
  email:
99
113
  - ryota.arai@gmail.com