logstash-input-s3 3.6.0 → 3.8.2

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: a4e1cc2ba334eb9e35fc68cc6a773e13b9b7de5bc6c3b4ee40cf98903d140323
4
- data.tar.gz: a43fe645c1016095639e092fa4d3e8e8b77384dd17190a712a0eaa5163e68854
3
+ metadata.gz: 1efe9981371c5b8306ef18f09c13fff78558b66ae2ee667bd2c576b8b88218e9
4
+ data.tar.gz: 843c506610bd7ca9c48759cb7339f80e65211c17df9c3a83c8a5ca6fe850f39f
5
5
  SHA512:
6
- metadata.gz: e10a6e21aa62270ce5f78c269fb3abf0a28b0755f78b0cb7adcc76183be460472327bdabbc94fab51c35774ae930d25846084ad3b9b0e95bd9e021c995c08bbd
7
- data.tar.gz: 23b6882049688b1cd57ccba4b8aa247103bf5b9f91011f1aa426e81280c3b4ca701bf88fd96e278968c7e38fd58a01980a830b4ce2bb9ad8e034cfe07113de79
6
+ metadata.gz: 0cd8360c8eafce836259fada827ab42fc1972a42cec30bafe4ed7d61bea222bcc3db0c4a1ee19471a3727dffd7e9170ad48c0fe57baff5408e76e5ea60de3d44
7
+ data.tar.gz: 2cdeb2452504940dbd999d838d1abd905108ae748c9efa7ab9788a67b9e79c139f247c360c33393ce742189e27bb3a8763bde1725c95c76145884b0aa7a54039
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## 3.8.2
2
+ - Refactor: read sincedb time once per bucket listing [#233](https://github.com/logstash-plugins/logstash-input-s3/pull/233)
3
+
4
+ ## 3.8.1
5
+ - Feat: cast true/false values for additional_settings [#232](https://github.com/logstash-plugins/logstash-input-s3/pull/232)
6
+
7
+ ## 3.8.0
8
+ - Add ECS v8 support.
9
+
10
+ ## 3.7.0
11
+ - Add ECS support. [#228](https://github.com/logstash-plugins/logstash-input-s3/pull/228)
12
+ - Fix missing file in cutoff time change. [#224](https://github.com/logstash-plugins/logstash-input-s3/pull/224)
13
+
1
14
  ## 3.6.0
2
15
  - Fixed unprocessed file with the same `last_modified` in ingestion. [#220](https://github.com/logstash-plugins/logstash-input-s3/pull/220)
3
16
 
data/docs/index.asciidoc CHANGED
@@ -31,6 +31,21 @@ Files ending in `.gz` are handled as gzip'ed files.
31
31
 
32
32
  Files that are archived to AWS Glacier will be skipped.
33
33
 
34
+ [id="plugins-{type}s-{plugin}-ecs_metadata"]
35
+ ==== Event Metadata and the Elastic Common Schema (ECS)
36
+ This plugin adds cloudfront metadata to event.
37
+ When ECS compatibility is disabled, the value is stored in the root level.
38
+ When ECS is enabled, the value is stored in the `@metadata` where it can be used by other plugins in your pipeline.
39
+
40
+ Here’s how ECS compatibility mode affects output.
41
+ [cols="<l,<l,e,<e"]
42
+ |=======================================================================
43
+ | ECS disabled | ECS v1 | Availability | Description
44
+
45
+ | cloudfront_fields | [@metadata][s3][cloudfront][fields] | available when the file is a CloudFront log | column names of log
46
+ | cloudfront_version | [@metadata][s3][cloudfront][version] | available when the file is a CloudFront log | version of log
47
+ |=======================================================================
48
+
34
49
  [id="plugins-{type}s-{plugin}-options"]
35
50
  ==== S3 Input Configuration Options
36
51
 
@@ -47,6 +62,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
47
62
  | <<plugins-{type}s-{plugin}-backup_to_dir>> |<<string,string>>|No
48
63
  | <<plugins-{type}s-{plugin}-bucket>> |<<string,string>>|Yes
49
64
  | <<plugins-{type}s-{plugin}-delete>> |<<boolean,boolean>>|No
65
+ | <<plugins-{type}s-{plugin}-ecs_compatibility>> |<<string,string>>|No
50
66
  | <<plugins-{type}s-{plugin}-endpoint>> |<<string,string>>|No
51
67
  | <<plugins-{type}s-{plugin}-exclude_pattern>> |<<string,string>>|No
52
68
  | <<plugins-{type}s-{plugin}-gzip_pattern>> |<<string,string>>|No
@@ -96,12 +112,12 @@ the connection to s3. See full list in https://docs.aws.amazon.com/sdkforruby/ap
96
112
  [source,ruby]
97
113
  input {
98
114
  s3 {
99
- "access_key_id" => "1234"
100
- "secret_access_key" => "secret"
101
- "bucket" => "logstash-test"
102
- "additional_settings" => {
103
- "force_path_style" => true
104
- "follow_redirects" => false
115
+ access_key_id => "1234"
116
+ secret_access_key => "secret"
117
+ bucket => "logstash-test"
118
+ additional_settings => {
119
+ force_path_style => true
120
+ follow_redirects => false
105
121
  }
106
122
  }
107
123
  }
@@ -167,6 +183,18 @@ The name of the S3 bucket.
167
183
 
168
184
  Whether to delete processed files from the original bucket.
169
185
 
186
+ [id="plugins-{type}s-{plugin}-ecs_compatibility"]
187
+ ===== `ecs_compatibility`
188
+
189
+ * Value type is <<string,string>>
190
+ * Supported values are:
191
+ ** `disabled`: does not use ECS-compatible field names
192
+ ** `v1`,`v8`: uses metadata fields that are compatible with Elastic Common Schema
193
+
194
+ Controls this plugin's compatibility with the
195
+ {ecs-ref}[Elastic Common Schema (ECS)].
196
+ See <<plugins-{type}s-{plugin}-ecs_metadata>> for detailed information.
197
+
170
198
  [id="plugins-{type}s-{plugin}-endpoint"]
171
199
  ===== `endpoint`
172
200
 
@@ -9,6 +9,7 @@ require "stud/interval"
9
9
  require "stud/temporary"
10
10
  require "aws-sdk"
11
11
  require "logstash/inputs/s3/patch"
12
+ require "logstash/plugin_mixins/ecs_compatibility_support"
12
13
 
13
14
  require 'java'
14
15
 
@@ -27,6 +28,7 @@ class LogStash::Inputs::S3 < LogStash::Inputs::Base
27
28
  java_import java.util.zip.ZipException
28
29
 
29
30
  include LogStash::PluginMixins::AwsConfig::V2
31
+ include LogStash::PluginMixins::ECSCompatibilitySupport(:disabled, :v1, :v8 => :v1)
30
32
 
31
33
  config_name "s3"
32
34
 
@@ -88,6 +90,12 @@ class LogStash::Inputs::S3 < LogStash::Inputs::Base
88
90
 
89
91
  CUTOFF_SECOND = 3
90
92
 
93
+ def initialize(*params)
94
+ super
95
+ @cloudfront_fields_key = ecs_select[disabled: 'cloudfront_fields', v1: '[@metadata][s3][cloudfront][fields]']
96
+ @cloudfront_version_key = ecs_select[disabled: 'cloudfront_version', v1: '[@metadata][s3][cloudfront][version]']
97
+ end
98
+
91
99
  def register
92
100
  require "fileutils"
93
101
  require "digest/md5"
@@ -130,6 +138,8 @@ class LogStash::Inputs::S3 < LogStash::Inputs::Base
130
138
  def list_new_files
131
139
  objects = []
132
140
  found = false
141
+ current_time = Time.now
142
+ sincedb_time = sincedb.read
133
143
  begin
134
144
  @s3bucket.objects(:prefix => @prefix).each do |log|
135
145
  found = true
@@ -138,9 +148,9 @@ class LogStash::Inputs::S3 < LogStash::Inputs::Base
138
148
  @logger.debug('Ignoring', :key => log.key)
139
149
  elsif log.content_length <= 0
140
150
  @logger.debug('Object Zero Length', :key => log.key)
141
- elsif !sincedb.newer?(log.last_modified)
151
+ elsif log.last_modified <= sincedb_time
142
152
  @logger.debug('Object Not Modified', :key => log.key)
143
- elsif log.last_modified > (Time.now - CUTOFF_SECOND).utc # file modified within last two seconds will be processed in next cycle
153
+ elsif log.last_modified > (current_time - CUTOFF_SECOND).utc # file modified within last two seconds will be processed in next cycle
144
154
  @logger.debug('Object Modified After Cutoff Time', :key => log.key)
145
155
  elsif (log.storage_class == 'GLACIER' || log.storage_class == 'DEEP_ARCHIVE') && !file_restored?(log.object)
146
156
  @logger.debug('Object Archived to Glacier', :key => log.key)
@@ -227,9 +237,6 @@ class LogStash::Inputs::S3 < LogStash::Inputs::Base
227
237
  else
228
238
  decorate(event)
229
239
 
230
- event.set("cloudfront_version", metadata[:cloudfront_version]) unless metadata[:cloudfront_version].nil?
231
- event.set("cloudfront_fields", metadata[:cloudfront_fields]) unless metadata[:cloudfront_fields].nil?
232
-
233
240
  if @include_object_properties
234
241
  event.set("[@metadata][s3]", object.data.to_h)
235
242
  else
@@ -237,6 +244,8 @@ class LogStash::Inputs::S3 < LogStash::Inputs::Base
237
244
  end
238
245
 
239
246
  event.set("[@metadata][s3][key]", object.key)
247
+ event.set(@cloudfront_version_key, metadata[:cloudfront_version]) unless metadata[:cloudfront_version].nil?
248
+ event.set(@cloudfront_fields_key, metadata[:cloudfront_fields]) unless metadata[:cloudfront_fields].nil?
240
249
 
241
250
  queue << event
242
251
  end
@@ -345,14 +354,22 @@ class LogStash::Inputs::S3 < LogStash::Inputs::Base
345
354
  end
346
355
 
347
356
  def symbolized_settings
348
- @symbolized_settings ||= symbolize(@additional_settings)
357
+ @symbolized_settings ||= symbolize_keys_and_cast_true_false(@additional_settings)
349
358
  end
350
359
 
351
- def symbolize(hash)
352
- return hash unless hash.is_a?(Hash)
353
- symbolized = {}
354
- hash.each { |key, value| symbolized[key.to_sym] = symbolize(value) }
355
- symbolized
360
+ def symbolize_keys_and_cast_true_false(hash)
361
+ case hash
362
+ when Hash
363
+ symbolized = {}
364
+ hash.each { |key, value| symbolized[key.to_sym] = symbolize_keys_and_cast_true_false(value) }
365
+ symbolized
366
+ when 'true'
367
+ true
368
+ when 'false'
369
+ false
370
+ else
371
+ hash
372
+ end
356
373
  end
357
374
 
358
375
  def ignore_filename?(filename)
@@ -448,10 +465,7 @@ class LogStash::Inputs::S3 < LogStash::Inputs::Base
448
465
  @sincedb_path = file
449
466
  end
450
467
 
451
- def newer?(date)
452
- date > read
453
- end
454
-
468
+ # @return [Time]
455
469
  def read
456
470
  if ::File.exists?(@sincedb_path)
457
471
  content = ::File.read(@sincedb_path).chomp.strip
@@ -463,7 +477,7 @@ class LogStash::Inputs::S3 < LogStash::Inputs::Base
463
477
  end
464
478
 
465
479
  def write(since = nil)
466
- since = Time.now() if since.nil?
480
+ since = Time.now if since.nil?
467
481
  ::File.open(@sincedb_path, 'w') { |file| file.write(since.to_s) }
468
482
  end
469
483
  end
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-input-s3'
4
- s.version = '3.6.0'
4
+ s.version = '3.8.2'
5
5
  s.licenses = ['Apache-2.0']
6
6
  s.summary = "Streams events from files in a S3 bucket"
7
7
  s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
@@ -27,4 +27,5 @@ Gem::Specification.new do |s|
27
27
  s.add_development_dependency 'logstash-devutils'
28
28
  s.add_development_dependency "logstash-codec-json"
29
29
  s.add_development_dependency "logstash-codec-multiline"
30
+ s.add_runtime_dependency 'logstash-mixin-ecs_compatibility_support', '~>1.2'
30
31
  end
@@ -9,6 +9,7 @@ require_relative "../support/helpers"
9
9
  require "stud/temporary"
10
10
  require "aws-sdk"
11
11
  require "fileutils"
12
+ require 'logstash/plugin_mixins/ecs_compatibility_support/spec_helper'
12
13
 
13
14
  describe LogStash::Inputs::S3 do
14
15
  let(:temporary_directory) { Stud::Temporary.pathname }
@@ -41,7 +42,9 @@ describe LogStash::Inputs::S3 do
41
42
  expect_any_instance_of(LogStash::Inputs::S3).to receive(:list_new_files).and_return(TestInfiniteS3Object.new(s3_obj))
42
43
  end
43
44
 
44
- it_behaves_like "an interruptible input plugin"
45
+ it_behaves_like "an interruptible input plugin" do
46
+ let(:allowed_lag) { 16 } if LOGSTASH_VERSION.split('.').first.to_i <= 6
47
+ end
45
48
  end
46
49
 
47
50
  describe "#register" do
@@ -81,10 +84,10 @@ describe LogStash::Inputs::S3 do
81
84
  end
82
85
 
83
86
  describe "additional_settings" do
84
- context 'when force_path_style is set' do
87
+ context "supported settings" do
85
88
  let(:settings) {
86
89
  {
87
- "additional_settings" => { "force_path_style" => true },
90
+ "additional_settings" => { "force_path_style" => 'true', "ssl_verify_peer" => 'false', "profile" => 'logstash' },
88
91
  "bucket" => "logstash-test",
89
92
  }
90
93
  }
@@ -92,7 +95,7 @@ describe LogStash::Inputs::S3 do
92
95
  it 'should instantiate AWS::S3 clients with force_path_style set' do
93
96
  expect(Aws::S3::Resource).to receive(:new).with({
94
97
  :region => subject.region,
95
- :force_path_style => true
98
+ :force_path_style => true, :ssl_verify_peer => false, :profile => 'logstash'
96
99
  }).and_call_original
97
100
 
98
101
  subject.send(:get_s3object)
@@ -192,6 +195,7 @@ describe LogStash::Inputs::S3 do
192
195
  it 'should log that no files were found in the bucket' do
193
196
  plugin = LogStash::Inputs::S3.new(config)
194
197
  plugin.register
198
+ allow(plugin.logger).to receive(:info).with(/Using the provided sincedb_path/, anything)
195
199
  expect(plugin.logger).to receive(:info).with(/No files found/, anything)
196
200
  expect(plugin.list_new_files).to be_empty
197
201
  end
@@ -494,12 +498,20 @@ describe LogStash::Inputs::S3 do
494
498
  context 'cloudfront' do
495
499
  let(:log_file) { File.join(File.dirname(__FILE__), '..', 'fixtures', 'cloudfront.log') }
496
500
 
497
- it 'should extract metadata from cloudfront log' do
498
- events = fetch_events(config)
501
+ describe "metadata", :ecs_compatibility_support, :aggregate_failures do
502
+ ecs_compatibility_matrix(:disabled, :v1) do |ecs_select|
503
+ before(:each) do
504
+ allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
505
+ end
499
506
 
500
- events.each do |event|
501
- expect(event.get('cloudfront_fields')).to eq('date time x-edge-location c-ip x-event sc-bytes x-cf-status x-cf-client-id cs-uri-stem cs-uri-query c-referrer x-page-url​ c-user-agent x-sname x-sname-query x-file-ext x-sid')
502
- expect(event.get('cloudfront_version')).to eq('1.0')
507
+ it 'should extract metadata from cloudfront log' do
508
+ events = fetch_events(config)
509
+
510
+ events.each do |event|
511
+ expect(event.get ecs_select[disabled: "cloudfront_fields", v1: "[@metadata][s3][cloudfront][fields]"] ).to eq('date time x-edge-location c-ip x-event sc-bytes x-cf-status x-cf-client-id cs-uri-stem cs-uri-query c-referrer x-page-url​ c-user-agent x-sname x-sname-query x-file-ext x-sid')
512
+ expect(event.get ecs_select[disabled: "cloudfront_version", v1: "[@metadata][s3][cloudfront][version]"] ).to eq('1.0')
513
+ end
514
+ end
503
515
  end
504
516
  end
505
517
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-input-s3
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.6.0
4
+ version: 3.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-11 00:00:00.000000000 Z
11
+ date: 2021-12-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -100,6 +100,20 @@ dependencies:
100
100
  - - ">="
101
101
  - !ruby/object:Gem::Version
102
102
  version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ requirement: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - "~>"
107
+ - !ruby/object:Gem::Version
108
+ version: '1.2'
109
+ name: logstash-mixin-ecs_compatibility_support
110
+ prerelease: false
111
+ type: :runtime
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '1.2'
103
117
  description: This gem is a Logstash plugin required to be installed on top of the
104
118
  Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This
105
119
  gem is not a stand-alone program
@@ -153,8 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
167
  - !ruby/object:Gem::Version
154
168
  version: '0'
155
169
  requirements: []
156
- rubyforge_project:
157
- rubygems_version: 2.6.13
170
+ rubygems_version: 3.1.6
158
171
  signing_key:
159
172
  specification_version: 4
160
173
  summary: Streams events from files in a S3 bucket