logstash-output-s3 4.3.4 → 4.3.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
  SHA256:
3
- metadata.gz: 841014c4e389a87dc3e63adb53303b5f6ea231221c45bc17b0eec5efb89a4bc6
4
- data.tar.gz: a6f52f77844ce60a32a0fe05915e2865838a05505beee6ff095d402f2201d502
3
+ metadata.gz: 238e7be91fe40e4fcb80736f3e8d62e76b6f8108be35e5a0c054cb19bb239428
4
+ data.tar.gz: eb0c70181aa21d20b794cd05d2e458b322b10f6e343ae41d96a1e6f49cf85858
5
5
  SHA512:
6
- metadata.gz: 211e4bb8bef9cfa55e8af453d456fa4dbe4670559a747a625b0bf91344c8c475d0a8f8d4e00eba070c7d32f81b39cf7af2ab9a8f248a18042678722ea7393165
7
- data.tar.gz: bd1f5c0e3f3337b20cdc1c4d9e835b24dda0882b0b8d2ad7d47a55fe9658c91e6137ca5869869e7dee90d0a506601e7d1557287c7c7aa833c44678bd2ebaae01
6
+ metadata.gz: 1194c4ee3defe1104fcc1c68d914c20e2ca2548ba6405960c75d4b398a7cd9949287c3410ead913ff82b5183164c4bd5bf858fe836f94f63654c582efab78ab5
7
+ data.tar.gz: cb135c3b28297db0f5ad90a4f7ab4ba6b8c112574815e38bdccdec685f5caa28ed7636f68569586f71205d651118dad7cc7dd0194786efb59bfb8113fa7d0afb
data/CHANGELOG.md CHANGED
@@ -1,17 +1,27 @@
1
+ ## 4.3.7
2
+ - Refactor: avoid usage of CHM (JRuby 9.3.4 work-around) [#248](https://github.com/logstash-plugins/logstash-output-s3/pull/248)
3
+
4
+ ## 4.3.6
5
+ - Docs: more documentation on restore + temp dir [#236](https://github.com/logstash-plugins/logstash-output-s3/pull/236)
6
+ * minor logging improvements - use the same path: naming convention
7
+
8
+ ## 4.3.5
9
+ - Feat: cast true/false values for additional_settings [#241](https://github.com/logstash-plugins/logstash-output-s3/pull/241)
10
+
1
11
  ## 4.3.4
2
- - [DOC] Added note about performance implications of interpolated strings in prefixes [#233](https://github.com/logstash-plugins/logstash-output-s3/pull/233)
12
+ - [DOC] Added note about performance implications of interpolated strings in prefixes [#233](https://github.com/logstash-plugins/logstash-output-s3/pull/233)
3
13
 
4
14
  ## 4.3.3
5
- - [DOC] Updated links to use shared attributes [#230](https://github.com/logstash-plugins/logstash-output-s3/pull/230)
15
+ - [DOC] Updated links to use shared attributes [#230](https://github.com/logstash-plugins/logstash-output-s3/pull/230)
6
16
 
7
17
  ## 4.3.2
8
- - [DOC] Added note that only AWS S3 is supported. No other S3 compatible storage solutions are supported. [#223](https://github.com/logstash-plugins/logstash-output-s3/pull/223)
18
+ - [DOC] Added note that only AWS S3 is supported. No other S3 compatible storage solutions are supported. [#223](https://github.com/logstash-plugins/logstash-output-s3/pull/223)
9
19
 
10
20
  ## 4.3.1
11
- - [DOC] Updated setting descriptions for clarity [#219](https://github.com/logstash-plugins/logstash-output-s3/pull/219) and [#220](https://github.com/logstash-plugins/logstash-output-s3/pull/220)
21
+ - [DOC] Updated setting descriptions for clarity [#219](https://github.com/logstash-plugins/logstash-output-s3/pull/219) and [#220](https://github.com/logstash-plugins/logstash-output-s3/pull/220)
12
22
 
13
23
  ## 4.3.0
14
- - Feat: Added retry_count and retry_delay config [#218](https://github.com/logstash-plugins/logstash-output-s3/pull/218)
24
+ - Feat: Added retry_count and retry_delay config [#218](https://github.com/logstash-plugins/logstash-output-s3/pull/218)
15
25
 
16
26
  ## 4.2.0
17
27
  - Added ability to specify [ONEZONE_IA](https://aws.amazon.com/s3/storage-classes/#__) as storage_class
data/docs/index.asciidoc CHANGED
@@ -30,8 +30,9 @@ Other S3 compatible storage solutions are not supported.
30
30
  S3 outputs create temporary files into the OS' temporary directory.
31
31
  You can specify where to save them using the `temporary_directory` option.
32
32
 
33
- IMPORTANT: For configurations containing multiple s3 outputs with the restore
34
- option enabled, each output should define its own 'temporary_directory'.
33
+ IMPORTANT: For configurations containing multiple s3 outputs with the `restore`
34
+ option enabled, each output should define its own `temporary_directory`.
35
+ Shared or nested directories can cause data loss upon recovery.
35
36
 
36
37
  ===== Requirements
37
38
 
@@ -255,6 +256,10 @@ The AWS Region
255
256
  Used to enable recovery after crash/abnormal termination.
256
257
  Temporary log files will be recovered and uploaded.
257
258
 
259
+ NOTE: If you're using multiple S3 outputs, always set
260
+ <<plugins-{type}s-{plugin}-temporary_directory>> to a
261
+ unique directory. Otherwise the recovery mechanism won't work correctly.
262
+
258
263
  [id="plugins-{type}s-{plugin}-retry_count"]
259
264
  ===== `retry_count`
260
265
 
@@ -388,7 +393,12 @@ Defaults to STANDARD.
388
393
  * Default value is `"/tmp/logstash"`
389
394
 
390
395
  Set the directory where logstash will store the tmp files before sending it to S3
391
- default to the current OS temporary directory in linux /tmp/logstash
396
+ default to the current OS temporary directory in linux `/tmp/logstash`.
397
+
398
+ WARNING: Using multiple S3 outputs with `restore => true` requires unique directories
399
+ per output. All of the directory's contents are processed and deleted upon recovery, and shared or nested directories can cause data loss.
400
+ For example, an output using `/tmp/s3` and a second configured with `/tmp/s3/sub` would
401
+ cause issues. Having temporary directories `/tmp/s3/sub1` and `/tmp/s3/sub2` is fine.
392
402
 
393
403
  [id="plugins-{type}s-{plugin}-time_file"]
394
404
  ===== `time_file`
@@ -1,11 +1,9 @@
1
1
  # encoding: utf-8
2
2
  require "java"
3
- require "concurrent"
3
+ require "concurrent/map"
4
4
  require "concurrent/timer_task"
5
5
  require "logstash/util"
6
6
 
7
- ConcurrentHashMap = java.util.concurrent.ConcurrentHashMap
8
-
9
7
  module LogStash
10
8
  module Outputs
11
9
  class S3
@@ -41,7 +39,7 @@ module LogStash
41
39
  end
42
40
 
43
41
  class FactoryInitializer
44
- include java.util.function.Function
42
+
45
43
  def initialize(tags, encoding, temporary_directory, stale_time)
46
44
  @tags = tags
47
45
  @encoding = encoding
@@ -49,9 +47,10 @@ module LogStash
49
47
  @stale_time = stale_time
50
48
  end
51
49
 
52
- def apply(prefix_key)
50
+ def create_value(prefix_key)
53
51
  PrefixedValue.new(TemporaryFileFactory.new(prefix_key, @tags, @encoding, @temporary_directory), @stale_time)
54
52
  end
53
+
55
54
  end
56
55
 
57
56
  def initialize(tags, encoding, temporary_directory,
@@ -59,7 +58,7 @@ module LogStash
59
58
  sweeper_interval = DEFAULT_STATE_SWEEPER_INTERVAL_SECS)
60
59
  # The path need to contains the prefix so when we start
61
60
  # logtash after a crash we keep the remote structure
62
- @prefixed_factories = ConcurrentHashMap.new
61
+ @prefixed_factories = Concurrent::Map.new
63
62
 
64
63
  @sweeper_interval = sweeper_interval
65
64
 
@@ -69,18 +68,19 @@ module LogStash
69
68
  end
70
69
 
71
70
  def keys
72
- @prefixed_factories.keySet
71
+ @prefixed_factories.keys
73
72
  end
74
73
 
75
74
  def each_files
76
- @prefixed_factories.elements.each do |prefixed_file|
75
+ @prefixed_factories.values.each do |prefixed_file|
77
76
  prefixed_file.with_lock { |factory| yield factory.current }
78
77
  end
79
78
  end
80
79
 
81
80
  # Return the file factory
82
81
  def get_factory(prefix_key)
83
- @prefixed_factories.computeIfAbsent(prefix_key, @factory_initializer).with_lock { |factory| yield factory }
82
+ prefix_val = @prefixed_factories.fetch_or_store(prefix_key) { @factory_initializer.create_value(prefix_key) }
83
+ prefix_val.with_lock { |factory| yield factory }
84
84
  end
85
85
 
86
86
  def get_file(prefix_key)
@@ -97,7 +97,7 @@ module LogStash
97
97
 
98
98
  def remove_stale(k, v)
99
99
  if v.stale?
100
- @prefixed_factories.remove(k, v)
100
+ @prefixed_factories.delete_pair(k, v)
101
101
  v.delete!
102
102
  end
103
103
  end
@@ -106,7 +106,7 @@ module LogStash
106
106
  @stale_sweeper = Concurrent::TimerTask.new(:execution_interval => @sweeper_interval) do
107
107
  LogStash::Util.set_thread_name("S3, Stale factory sweeper")
108
108
 
109
- @prefixed_factories.forEach{|k,v| remove_stale(k,v)}
109
+ @prefixed_factories.each { |k, v| remove_stale(k,v) }
110
110
  end
111
111
 
112
112
  @stale_sweeper.execute
@@ -110,7 +110,8 @@ class LogStash::Outputs::S3 < LogStash::Outputs::Base
110
110
 
111
111
  # Set the size of file in bytes, this means that files on bucket when have dimension > file_size, they are stored in two or more file.
112
112
  # If you have tags then it will generate a specific size file for every tags
113
- ##NOTE: define size of file is the better thing, because generate a local temporary file on disk and then put it in bucket.
113
+ #
114
+ # NOTE: define size of file is the better thing, because generate a local temporary file on disk and then put it in bucket.
114
115
  config :size_file, :validate => :number, :default => 1024 * 1024 * 5
115
116
 
116
117
  # Set the time, in MINUTES, to close the current sub_time_section of bucket.
@@ -118,10 +119,10 @@ class LogStash::Outputs::S3 < LogStash::Outputs::Base
118
119
  # If it's valued 0 and rotation_strategy is 'time' or 'size_and_time' then the plugin reaise a configuration error.
119
120
  config :time_file, :validate => :number, :default => 15
120
121
 
121
- ## IMPORTANT: if you use multiple instance of s3, you should specify on one of them the "restore=> true" and on the others "restore => false".
122
- ## This is hack for not destroy the new files after restoring the initial files.
123
- ## If you do not specify "restore => true" when logstash crashes or is restarted, the files are not sent into the bucket,
124
- ## for example if you have single Instance.
122
+ # If `restore => false` is specified and Logstash crashes, the unprocessed files are not sent into the bucket.
123
+ #
124
+ # NOTE: that the `recovery => true` default assumes multiple S3 outputs would set a unique `temporary_directory => ...`
125
+ # if they do not than only a single S3 output is safe to recover (since let-over files are processed and deleted).
125
126
  config :restore, :validate => :boolean, :default => true
126
127
 
127
128
  # The S3 canned ACL to use when putting the file. Defaults to "private".
@@ -147,6 +148,9 @@ class LogStash::Outputs::S3 < LogStash::Outputs::Base
147
148
 
148
149
  # Set the directory where logstash will store the tmp files before sending it to S3
149
150
  # default to the current OS temporary directory in linux /tmp/logstash
151
+ #
152
+ # NOTE: the reason we do not have a unique (isolated) temporary directory as a default, to support multiple plugin instances,
153
+ # is that we would have to rely on something static that does not change between restarts (e.g. a user set id => ...).
150
154
  config :temporary_directory, :validate => :string, :default => File.join(Dir.tmpdir, "logstash")
151
155
 
152
156
  # Specify a prefix to the uploaded filename, this can simulate directories on S3. Prefix does not require leading slash.
@@ -283,17 +287,24 @@ class LogStash::Outputs::S3 < LogStash::Outputs::Base
283
287
  end
284
288
 
285
289
  def symbolized_settings
286
- @symbolized_settings ||= symbolize_keys(@additional_settings)
290
+ @symbolized_settings ||= symbolize_keys_and_cast_true_false(@additional_settings)
287
291
  end
288
292
 
289
- def symbolize_keys(hash)
290
- return hash unless hash.is_a?(Hash)
291
- symbolized = {}
292
- hash.each { |key, value| symbolized[key.to_sym] = symbolize_keys(value) }
293
- symbolized
293
+ def symbolize_keys_and_cast_true_false(hash)
294
+ case hash
295
+ when Hash
296
+ symbolized = {}
297
+ hash.each { |key, value| symbolized[key.to_sym] = symbolize_keys_and_cast_true_false(value) }
298
+ symbolized
299
+ when 'true'
300
+ true
301
+ when 'false'
302
+ false
303
+ else
304
+ hash
305
+ end
294
306
  end
295
307
 
296
-
297
308
  def normalize_key(prefix_key)
298
309
  prefix_key.gsub(PathValidator.matches_re, PREFIX_KEY_NORMALIZE_CHARACTER)
299
310
  end
@@ -340,10 +351,10 @@ class LogStash::Outputs::S3 < LogStash::Outputs::Base
340
351
  temp_file = factory.current
341
352
 
342
353
  if @rotation.rotate?(temp_file)
343
- @logger.debug("Rotate file",
344
- :strategy => @rotation.class.name,
345
- :key => temp_file.key,
346
- :path => temp_file.path)
354
+ @logger.debug? && @logger.debug("Rotate file",
355
+ :key => temp_file.key,
356
+ :path => temp_file.path,
357
+ :strategy => @rotation.class.name)
347
358
 
348
359
  upload_file(temp_file)
349
360
  factory.rotate!
@@ -353,7 +364,7 @@ class LogStash::Outputs::S3 < LogStash::Outputs::Base
353
364
  end
354
365
 
355
366
  def upload_file(temp_file)
356
- @logger.debug("Queue for upload", :path => temp_file.path)
367
+ @logger.debug? && @logger.debug("Queue for upload", :path => temp_file.path)
357
368
 
358
369
  # if the queue is full the calling thread will be used to upload
359
370
  temp_file.close # make sure the content is on disk
@@ -376,7 +387,7 @@ class LogStash::Outputs::S3 < LogStash::Outputs::Base
376
387
  end
377
388
 
378
389
  def clean_temporary_file(file)
379
- @logger.debug("Removing temporary file", :file => file.path)
390
+ @logger.debug? && @logger.debug("Removing temporary file", :path => file.path)
380
391
  file.delete!
381
392
  end
382
393
 
@@ -391,7 +402,7 @@ class LogStash::Outputs::S3 < LogStash::Outputs::Base
391
402
  .each do |file|
392
403
  temp_file = TemporaryFile.create_from_existing_file(file, temp_folder_path)
393
404
  if temp_file.size > 0
394
- @logger.debug("Recovering from crash and uploading", :file => temp_file.path)
405
+ @logger.debug? && @logger.debug("Recovering from crash and uploading", :path => temp_file.path)
395
406
  @crash_uploader.upload_async(temp_file, :on_complete => method(:clean_temporary_file), :upload_options => upload_options)
396
407
  else
397
408
  clean_temporary_file(temp_file)
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-output-s3'
3
- s.version = '4.3.4'
3
+ s.version = '4.3.7'
4
4
  s.licenses = ['Apache-2.0']
5
5
  s.summary = "Sends Logstash events to the Amazon Simple Storage Service"
6
6
  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"
@@ -88,8 +88,8 @@ describe LogStash::Outputs::S3::FileRepository do
88
88
 
89
89
  it "returns all available keys" do
90
90
  subject.get_file(prefix_key) { |file| file.write("something") }
91
- expect(subject.keys.toArray).to include(prefix_key)
92
- expect(subject.keys.toArray.size).to eq(1)
91
+ expect(subject.keys).to include(prefix_key)
92
+ expect(subject.keys.size).to eq(1)
93
93
  end
94
94
 
95
95
  it "clean stale factories" do
@@ -105,9 +105,14 @@ describe LogStash::Outputs::S3::FileRepository do
105
105
 
106
106
  @file_repository.get_file("another-prefix") { |file| file.write("hello") }
107
107
  expect(@file_repository.size).to eq(2)
108
+ sleep 1.2 # allow sweeper to kick in
108
109
  try(10) { expect(@file_repository.size).to eq(1) }
109
110
  expect(File.directory?(path)).to be_falsey
111
+
112
+ sleep 1.5 # allow sweeper to kick in, again
113
+ expect(@file_repository.size).to eq(1)
110
114
  end
115
+
111
116
  end
112
117
 
113
118
 
@@ -140,7 +140,7 @@ describe LogStash::Outputs::S3 do
140
140
 
141
141
  describe "temporary directory" do
142
142
  let(:temporary_directory) { Stud::Temporary.pathname }
143
- let(:options) { super.merge({ "temporary_directory" => temporary_directory }) }
143
+ let(:options) { super().merge({ "temporary_directory" => temporary_directory }) }
144
144
 
145
145
  it "creates the directory when it doesn't exist" do
146
146
  expect(Dir.exist?(temporary_directory)).to be_falsey
@@ -160,13 +160,15 @@ describe LogStash::Outputs::S3 do
160
160
  end
161
161
 
162
162
  describe "additional_settings" do
163
- context "when enabling force_path_style" do
163
+ context "supported settings" do
164
164
  let(:additional_settings) do
165
- { "additional_settings" => { "force_path_style" => true } }
165
+ { "additional_settings" => { "force_path_style" => 'true', "ssl_verify_peer" => 'false', "profile" => 'logstash' } }
166
166
  end
167
167
 
168
168
  it "validates the prefix" do
169
- expect(Aws::S3::Bucket).to receive(:new).twice.with(anything, hash_including(:force_path_style => true)).and_call_original
169
+ expect(Aws::S3::Bucket).to receive(:new).twice.
170
+ with(anything, hash_including(:force_path_style => true, :ssl_verify_peer => false, :profile => 'logstash')).
171
+ and_call_original
170
172
  described_class.new(options.merge(additional_settings)).register
171
173
  end
172
174
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-output-s3
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.4
4
+ version: 4.3.7
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-02 00:00:00.000000000 Z
11
+ date: 2022-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -185,8 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
185
185
  - !ruby/object:Gem::Version
186
186
  version: '0'
187
187
  requirements: []
188
- rubyforge_project:
189
- rubygems_version: 2.6.13
188
+ rubygems_version: 3.1.6
190
189
  signing_key:
191
190
  specification_version: 4
192
191
  summary: Sends Logstash events to the Amazon Simple Storage Service