logstash-input-s3 3.6.0 → 3.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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