fluent-plugin-s3 0.6.6 → 0.6.7

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: 563ab768bef3f13148f841becf15b1d7e8e88ed2
4
- data.tar.gz: b3b54160a015d14b801914e522fef06ad5d7bb1a
3
+ metadata.gz: cc5bd6dc0616525d3beb069168b7f59bc985b188
4
+ data.tar.gz: 5021dbf9b12861ee087ad2b5a1800d9430e79874
5
5
  SHA512:
6
- metadata.gz: 27b44ab95d94a7cf93cd1337aea917326bf596693b7af529a75cfb343c7a65e97311c9345d21ee8bf3983c69b84a2773f26081c4cc6f928fb6f25ba9a621b285
7
- data.tar.gz: 205930d50c3e1d1d42383e149b870aa4e8b8232780288026fcdeb214624626927b3e68601a1f361aaa1dd3632e3a81119d9e964615e890bbf19ebe94733ecd06
6
+ metadata.gz: f0c104943d41ecaacefcf35565d3bf3de8ff8c0301d3edb02994f8425cfcc81f43833c1eed478dfc8fd2965017068da32d43a590644e82bbd1cd98277f3888bd
7
+ data.tar.gz: 4580b5c87c33db7fc7ba65c250c3c2e1330c10be6e75bde2144175df41276cfe929031379df785dba68b5d8196890e6ba51b8fbd5081e8e769ea96b24718c6ae
data/ChangeLog CHANGED
@@ -1,3 +1,9 @@
1
+ Release 0.6.7 - 2016/03/31
2
+
3
+ * Add signature_version parameter
4
+ * Add warn_for_delay parameter
5
+
6
+
1
7
  Release 0.6.6 - 2016/03/16
2
8
 
3
9
  * Fix ACL handling in PUT operation
data/README.md CHANGED
@@ -293,6 +293,16 @@ AWS SDK uses MD5 for API request/response by default. On FIPS enabled environmen
293
293
  OpenSSL returns an error because MD5 is disabled. If you want to use
294
294
  this plugin on FIPS enabled environment, set `compute_checksums false`.
295
295
 
296
+ **signature_version**
297
+
298
+ Signature version for API request. `s3` means signature version 2 and
299
+ `v4` means signature version 4. Default is `nil` (Following SDK's default).
300
+ It would be useful when you use S3 compatible storage that accepts only signature version 2.
301
+
302
+ **warn_for_delay**
303
+
304
+ Given a threshold to treat events as delay, output warning logs if delayed events were put into s3.
305
+
296
306
  ### assume_role_credentials
297
307
 
298
308
  Typically, you use AssumeRole for cross-account access or federation.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.6
1
+ 0.6.7
@@ -24,4 +24,5 @@ Gem::Specification.new do |gem|
24
24
  gem.add_development_dependency "rake", ">= 0.9.2"
25
25
  gem.add_development_dependency "test-unit", ">= 3.0.8"
26
26
  gem.add_development_dependency "test-unit-rr", ">= 1.0.3"
27
+ gem.add_development_dependency "timecop"
27
28
  end
@@ -105,6 +105,10 @@ module Fluent
105
105
  config_param :ssekms_key_id, :string, :default => nil, :secret => true
106
106
  desc "AWS SDK uses MD5 for API request/response by default"
107
107
  config_param :compute_checksums, :bool, :default => nil # use nil to follow SDK default configuration
108
+ desc "Signature version for API Request (s3,v4)"
109
+ config_param :signature_version, :string, :default => nil # use nil to follow SDK default configuration
110
+ desc "Given a threshold to treat events as delay, output warning logs if delayed events were put into s3"
111
+ config_param :warn_for_delay, :time, :default => nil
108
112
 
109
113
  attr_reader :bucket
110
114
 
@@ -159,6 +163,7 @@ module Fluent
159
163
  options[:http_proxy] = @proxy_uri if @proxy_uri
160
164
  options[:force_path_style] = @force_path_style
161
165
  options[:compute_checksums] = @compute_checksums unless @compute_checksums.nil?
166
+ options[:signature_version] = @signature_version unless @signature_version.nil?
162
167
 
163
168
  s3_client = Aws::S3::Client.new(options)
164
169
  @s3 = Aws::S3::Resource.new(:client => s3_client)
@@ -227,6 +232,12 @@ module Fluent
227
232
  @bucket.object(s3path).put(put_options)
228
233
 
229
234
  @values_for_s3_object_chunk.delete(chunk.unique_id)
235
+
236
+ if @warn_for_delay
237
+ if Time.strptime(chunk.key, @time_slice_format) < Time.now - @warn_for_delay
238
+ log.warn { "out_s3: delayed events were put to s3://#{@s3_bucket}/#{s3path}" }
239
+ end
240
+ end
230
241
  ensure
231
242
  tmp.close(true) rescue nil
232
243
  end
@@ -4,6 +4,7 @@ require 'fluent/plugin/out_s3'
4
4
  require 'test/unit/rr'
5
5
  require 'zlib'
6
6
  require 'fileutils'
7
+ require 'timecop'
7
8
 
8
9
  class S3OutputTest < Test::Unit::TestCase
9
10
  def setup
@@ -50,6 +51,7 @@ class S3OutputTest < Test::Unit::TestCase
50
51
  assert_equal 'application/x-gzip', d.instance.instance_variable_get(:@compressor).content_type
51
52
  assert_equal false, d.instance.force_path_style
52
53
  assert_equal nil, d.instance.compute_checksums
54
+ assert_equal nil, d.instance.signature_version
53
55
  end
54
56
 
55
57
  def test_s3_endpoint_with_valid_endpoint
@@ -274,19 +276,8 @@ class S3OutputTest < Test::Unit::TestCase
274
276
  def test_write_with_custom_s3_object_key_format
275
277
  # Partial mock the S3Bucket, not to make an actual connection to Amazon S3
276
278
  setup_mocks(true)
277
-
278
- # Assert content of event logs which are being sent to S3
279
- s3obj = stub(Aws::S3::Object.new(:bucket_name => "test_bucket",
280
- :key => "test",
281
- :client => @s3_client))
282
- s3obj.exists? { false }
283
- s3_test_file_path = "/tmp/s3-test.txt"
284
- tempfile = File.new(s3_test_file_path, "w")
285
- mock(Tempfile).new("s3-") { tempfile }
286
- s3obj.put(:body => tempfile,
287
- :content_type => "application/x-gzip",
288
- :storage_class => "STANDARD")
289
- @s3_bucket.object("log/events/ts=20110102-13/events_0-testing.node.local.gz") { s3obj }
279
+ s3_local_file_path = "/tmp/s3-test.txt"
280
+ setup_s3_object_mocks(s3_local_file_path: s3_local_file_path)
290
281
 
291
282
  # We must use TimeSlicedOutputTestDriver instead of BufferedOutputTestDriver,
292
283
  # to make assertions on chunks' keys
@@ -298,13 +289,13 @@ class S3OutputTest < Test::Unit::TestCase
298
289
 
299
290
  # Finally, the instance of S3Output is initialized and then invoked
300
291
  d.run
301
- Zlib::GzipReader.open(s3_test_file_path) do |gz|
292
+ Zlib::GzipReader.open(s3_local_file_path) do |gz|
302
293
  data = gz.read
303
294
  assert_equal %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] +
304
295
  %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n],
305
296
  data
306
297
  end
307
- FileUtils.rm_f(s3_test_file_path)
298
+ FileUtils.rm_f(s3_local_file_path)
308
299
  end
309
300
 
310
301
  def test_write_with_custom_s3_object_key_format_containing_uuid_flush_placeholder
@@ -314,18 +305,9 @@ class S3OutputTest < Test::Unit::TestCase
314
305
  uuid = "5755e23f-9b54-42d8-8818-2ea38c6f279e"
315
306
  stub(UUIDTools::UUID).random_create{ uuid }
316
307
 
317
- # Assert content of event logs which are being sent to S3
318
- s3obj = stub(Aws::S3::Object.new(:bucket_name => "test_bucket",
319
- :key => "test",
320
- :client => @s3_client))
321
- s3obj.exists? { false }
322
- s3_test_file_path = "/tmp/s3-test.txt"
323
- tempfile = File.new(s3_test_file_path, "w")
324
- mock(Tempfile).new("s3-") { tempfile }
325
- s3obj.put(:body => tempfile,
326
- :content_type => "application/x-gzip",
327
- :storage_class => "STANDARD")
328
- @s3_bucket.object("log/events/ts=20110102-13/events_0-#{uuid}.gz") { s3obj }
308
+ s3_local_file_path = "/tmp/s3-test.txt"
309
+ s3path = "log/events/ts=20110102-13/events_0-#{uuid}.gz"
310
+ setup_s3_object_mocks(s3_local_file_path: s3_local_file_path, s3path: s3path)
329
311
 
330
312
  # We must use TimeSlicedOutputTestDriver instead of BufferedOutputTestDriver,
331
313
  # to make assertions on chunks' keys
@@ -338,13 +320,13 @@ class S3OutputTest < Test::Unit::TestCase
338
320
 
339
321
  # Finally, the instance of S3Output is initialized and then invoked
340
322
  d.run
341
- Zlib::GzipReader.open(s3_test_file_path) do |gz|
323
+ Zlib::GzipReader.open(s3_local_file_path) do |gz|
342
324
  data = gz.read
343
325
  assert_equal %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] +
344
326
  %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n],
345
327
  data
346
328
  end
347
- FileUtils.rm_f(s3_test_file_path)
329
+ FileUtils.rm_f(s3_local_file_path)
348
330
  Dir.glob('tmp/*').each {|file| FileUtils.rm_f(file) }
349
331
  end
350
332
 
@@ -375,18 +357,9 @@ class S3OutputTest < Test::Unit::TestCase
375
357
  # Partial mock the S3Bucket, not to make an actual connection to Amazon S3
376
358
  setup_mocks(true)
377
359
 
378
- # Assert content of event logs which are being sent to S3
379
- s3obj = stub(Aws::S3::Object.new(:bucket_name => "test_bucket",
380
- :key => "test",
381
- :client => @s3_client))
382
- s3obj.exists? { false }
383
- s3_test_file_path = "/tmp/s3-test.txt"
384
- tempfile = File.new(s3_test_file_path, "w")
385
- mock(Tempfile).new("s3-") { tempfile }
386
- s3obj.put(:body => tempfile,
387
- :content_type => "application/x-gzip",
388
- :storage_class => "STANDARD")
389
- @s3_bucket.object("log/events/ts=20110102-13/events_0-#{hex}.gz") { s3obj }
360
+ s3path = "log/events/ts=20110102-13/events_0-#{hex}.gz"
361
+ s3_local_file_path = "/tmp/s3-test.txt"
362
+ setup_s3_object_mocks(s3_local_file_path: s3_local_file_path, s3path: s3path)
390
363
 
391
364
  d = create_time_sliced_driver(config)
392
365
 
@@ -396,13 +369,13 @@ class S3OutputTest < Test::Unit::TestCase
396
369
 
397
370
  # Finally, the instance of S3Output is initialized and then invoked
398
371
  d.run
399
- Zlib::GzipReader.open(s3_test_file_path) do |gz|
372
+ Zlib::GzipReader.open(s3_local_file_path) do |gz|
400
373
  data = gz.read
401
374
  assert_equal %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] +
402
375
  %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n],
403
376
  data
404
377
  end
405
- FileUtils.rm_f(s3_test_file_path)
378
+ FileUtils.rm_f(s3_local_file_path)
406
379
  end
407
380
 
408
381
  def setup_mocks(exists_return = false)
@@ -420,6 +393,25 @@ class S3OutputTest < Test::Unit::TestCase
420
393
  @s3_resource.bucket(anything) { @s3_bucket }
421
394
  end
422
395
 
396
+ def setup_s3_object_mocks(params = {})
397
+ s3path = params[:s3path] || "log/events/ts=20110102-13/events_0-testing.node.local.gz"
398
+ s3_local_file_path = params[:s3_local_file_path] || "/tmp/s3-test.txt"
399
+
400
+ # Assert content of event logs which are being sent to S3
401
+ s3obj = stub(Aws::S3::Object.new(:bucket_name => "test_bucket",
402
+ :key => "test",
403
+ :client => @s3_client))
404
+ s3obj.exists? { false }
405
+
406
+ tempfile = File.new(s3_local_file_path, "w")
407
+ stub(Tempfile).new("s3-") { tempfile }
408
+ s3obj.put(:body => tempfile,
409
+ :content_type => "application/x-gzip",
410
+ :storage_class => "STANDARD")
411
+
412
+ @s3_bucket.object(s3path) { s3obj }
413
+ end
414
+
423
415
  def test_auto_create_bucket_false_with_non_existence_bucket
424
416
  setup_mocks
425
417
 
@@ -534,4 +526,36 @@ class S3OutputTest < Test::Unit::TestCase
534
526
  credentials = client.config.credentials
535
527
  assert_equal(expected_credentials, credentials)
536
528
  end
529
+
530
+ def test_signature_version
531
+ config = [CONFIG, 'signature_version s3'].join("\n")
532
+ d = create_driver(config)
533
+
534
+ signature_version = d.instance.instance_variable_get(:@signature_version)
535
+ assert_equal("s3", signature_version)
536
+ end
537
+
538
+ def test_warn_for_delay
539
+ setup_mocks(true)
540
+ s3_local_file_path = "/tmp/s3-test.txt"
541
+ setup_s3_object_mocks(s3_local_file_path: s3_local_file_path)
542
+
543
+ config = CONFIG_TIME_SLICE + 'warn_for_delay 1d'
544
+ d = create_time_sliced_driver(config)
545
+
546
+ delayed_time = Time.parse("2011-01-02 13:14:15 UTC")
547
+ now = delayed_time + 86000 + 1
548
+ Timecop.freeze(now)
549
+
550
+ d.emit({"a"=>1}, delayed_time.to_i)
551
+ d.emit({"a"=>2}, delayed_time.to_i)
552
+
553
+ d.run
554
+
555
+ logs = d.instance.log.logs
556
+ assert_true logs.any? {|log| log.include?('[warn]: out_s3: delayed events were put') }
557
+
558
+ Timecop.return
559
+ FileUtils.rm_f(s3_local_file_path)
560
+ end
537
561
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-s3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.6
4
+ version: 0.6.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-03-17 00:00:00.000000000 Z
12
+ date: 2016-03-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fluentd
@@ -115,6 +115,20 @@ dependencies:
115
115
  - - ">="
116
116
  - !ruby/object:Gem::Version
117
117
  version: 1.0.3
118
+ - !ruby/object:Gem::Dependency
119
+ name: timecop
120
+ requirement: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ type: :development
126
+ prerelease: false
127
+ version_requirements: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
118
132
  description: Amazon S3 output plugin for Fluentd event collector
119
133
  email: frsyuki@gmail.com
120
134
  executables: []