logstash-input-file 4.1.17 → 4.1.18
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 +4 -4
- data/CHANGELOG.md +3 -0
- data/lib/filewatch/read_mode/handlers/read_file.rb +3 -0
- data/lib/filewatch/watch.rb +1 -1
- data/lib/filewatch/watched_files_collection.rb +9 -5
- data/lib/jars/filewatch-1.0.1.jar +0 -0
- data/lib/logstash/inputs/delete_completed_file_handler.rb +5 -0
- data/lib/logstash/inputs/file.rb +24 -10
- data/logstash-input-file.gemspec +1 -1
- data/spec/filewatch/watched_files_collection_spec.rb +2 -2
- data/spec/helpers/spec_helper.rb +1 -0
- data/spec/inputs/file_read_spec.rb +75 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc2b7f39bcc8e3dfb894ea72af1b07e78fff73bf97ad12614a9ec440fed0c2d1
|
4
|
+
data.tar.gz: 6715064a8a25a13538cc07216f5c479f79dd2d3ba73a267377cd357c6e27ea8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fbc9d7cd0f7b50be21721bfe0cb7c26a1e87a1f5697f4a01f14dcdc14a8449c9a9d14ddec58f3ec1b8bd611e624855b538155af8f2924604fb9f1cf120de4e22
|
7
|
+
data.tar.gz: 44b4bdb7b356a6494cb1cde6bf48395d61222234d2ec6cfb134d551a20ed1ab08043b23266b5bc75854b85577d22a1fd36d5b40c17213eb10df68f2903086146
|
data/CHANGELOG.md
CHANGED
@@ -22,6 +22,9 @@ module FileWatch module ReadMode module Handlers
|
|
22
22
|
sincedb_collection.reading_completed(key)
|
23
23
|
sincedb_collection.clear_watched_file(key)
|
24
24
|
watched_file.listener.deleted
|
25
|
+
# NOTE: on top of un-watching we should also remove from the watched files collection
|
26
|
+
# if the file is getting deleted (on completion), that part currently resides in
|
27
|
+
# DeleteCompletedFileHandler - triggered above using `watched_file.listener.deleted`
|
25
28
|
watched_file.unwatch
|
26
29
|
end
|
27
30
|
end
|
data/lib/filewatch/watch.rb
CHANGED
@@ -67,7 +67,7 @@ module FileWatch
|
|
67
67
|
watched_files = @watched_files_collection.values
|
68
68
|
@processor.process_all_states(watched_files)
|
69
69
|
ensure
|
70
|
-
@watched_files_collection.
|
70
|
+
@watched_files_collection.remove_paths(@processor.deletable_filepaths)
|
71
71
|
@processor.deletable_filepaths.clear
|
72
72
|
end
|
73
73
|
end # def each
|
@@ -15,13 +15,17 @@ module FileWatch
|
|
15
15
|
@sort_method.call
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
Array(paths).
|
20
|
-
index = @pointers.delete(
|
21
|
-
|
22
|
-
|
18
|
+
def remove_paths(paths)
|
19
|
+
removed_files = Array(paths).map do |path|
|
20
|
+
index = @pointers.delete(path)
|
21
|
+
if index
|
22
|
+
watched_file = @files.delete_at(index)
|
23
|
+
refresh_pointers
|
24
|
+
watched_file
|
25
|
+
end
|
23
26
|
end
|
24
27
|
@sort_method.call
|
28
|
+
removed_files
|
25
29
|
end
|
26
30
|
|
27
31
|
def close_all
|
Binary file
|
@@ -2,8 +2,13 @@
|
|
2
2
|
|
3
3
|
module LogStash module Inputs
|
4
4
|
class DeleteCompletedFileHandler
|
5
|
+
def initialize(watch)
|
6
|
+
@watch = watch
|
7
|
+
end
|
8
|
+
|
5
9
|
def handle(path)
|
6
10
|
Pathname.new(path).unlink rescue nil
|
11
|
+
@watch.watched_files_collection.remove_paths([path])
|
7
12
|
end
|
8
13
|
end
|
9
14
|
end end
|
data/lib/logstash/inputs/file.rb
CHANGED
@@ -6,6 +6,7 @@ require "logstash/codecs/identity_map_codec"
|
|
6
6
|
require "pathname"
|
7
7
|
require "socket" # for Socket.gethostname
|
8
8
|
require "fileutils"
|
9
|
+
require "concurrent/atomic/atomic_reference"
|
9
10
|
|
10
11
|
require_relative "file/patch"
|
11
12
|
require_relative "file_listener"
|
@@ -247,6 +248,9 @@ class File < LogStash::Inputs::Base
|
|
247
248
|
end
|
248
249
|
end
|
249
250
|
|
251
|
+
# @private used in specs
|
252
|
+
attr_reader :watcher
|
253
|
+
|
250
254
|
def register
|
251
255
|
require "addressable/uri"
|
252
256
|
require "digest/md5"
|
@@ -274,8 +278,6 @@ class File < LogStash::Inputs::Base
|
|
274
278
|
:check_archive_validity => @check_archive_validity,
|
275
279
|
}
|
276
280
|
|
277
|
-
@completed_file_handlers = []
|
278
|
-
|
279
281
|
@path.each do |path|
|
280
282
|
if Pathname.new(path).relative?
|
281
283
|
raise ArgumentError.new("File paths must be absolute, relative path specified: #{path}")
|
@@ -319,15 +321,10 @@ class File < LogStash::Inputs::Base
|
|
319
321
|
@watcher_class = FileWatch::ObservingTail
|
320
322
|
else
|
321
323
|
@watcher_class = FileWatch::ObservingRead
|
322
|
-
if @file_completed_action.include?('log')
|
323
|
-
@completed_file_handlers << LogCompletedFileHandler.new(@file_completed_log_path)
|
324
|
-
end
|
325
|
-
if @file_completed_action.include?('delete')
|
326
|
-
@completed_file_handlers << DeleteCompletedFileHandler.new
|
327
|
-
end
|
328
324
|
end
|
329
325
|
@codec = LogStash::Codecs::IdentityMapCodec.new(@codec)
|
330
326
|
@completely_stopped = Concurrent::AtomicBoolean.new
|
327
|
+
@queue = Concurrent::AtomicReference.new
|
331
328
|
end # def register
|
332
329
|
|
333
330
|
def completely_stopped?
|
@@ -344,13 +341,25 @@ class File < LogStash::Inputs::Base
|
|
344
341
|
# if the pipeline restarts this input,
|
345
342
|
# make sure previous files are closed
|
346
343
|
stop
|
344
|
+
|
347
345
|
@watcher = @watcher_class.new(@filewatch_config)
|
346
|
+
|
347
|
+
@completed_file_handlers = []
|
348
|
+
if read_mode?
|
349
|
+
if @file_completed_action.include?('log')
|
350
|
+
@completed_file_handlers << LogCompletedFileHandler.new(@file_completed_log_path)
|
351
|
+
end
|
352
|
+
if @file_completed_action.include?('delete')
|
353
|
+
@completed_file_handlers << DeleteCompletedFileHandler.new(@watcher.watch)
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
348
357
|
@path.each { |path| @watcher.watch_this(path) }
|
349
358
|
end
|
350
359
|
|
351
360
|
def run(queue)
|
352
361
|
start_processing
|
353
|
-
@queue
|
362
|
+
@queue.set queue
|
354
363
|
@watcher.subscribe(self) # halts here until quit is called
|
355
364
|
# last action of the subscribe call is to write the sincedb
|
356
365
|
exit_flush
|
@@ -361,7 +370,7 @@ class File < LogStash::Inputs::Base
|
|
361
370
|
event.set("[@metadata][host]", @host)
|
362
371
|
event.set("host", @host) unless event.include?("host")
|
363
372
|
decorate(event)
|
364
|
-
@queue << event
|
373
|
+
@queue.get << event
|
365
374
|
end
|
366
375
|
|
367
376
|
def handle_deletable_path(path)
|
@@ -382,6 +391,11 @@ class File < LogStash::Inputs::Base
|
|
382
391
|
end
|
383
392
|
end
|
384
393
|
|
394
|
+
# @private used in specs
|
395
|
+
def queue
|
396
|
+
@queue.get
|
397
|
+
end
|
398
|
+
|
385
399
|
private
|
386
400
|
|
387
401
|
def build_sincedb_base_from_settings(settings)
|
data/logstash-input-file.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-input-file'
|
4
|
-
s.version = '4.1.
|
4
|
+
s.version = '4.1.18'
|
5
5
|
s.licenses = ['Apache-2.0']
|
6
6
|
s.summary = "Streams events from files"
|
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"
|
@@ -85,9 +85,9 @@ module FileWatch
|
|
85
85
|
collection.add(wf3)
|
86
86
|
expect(collection.keys).to eq([filepath1, filepath2, filepath3])
|
87
87
|
|
88
|
-
collection.
|
88
|
+
collection.remove_paths([filepath2,filepath3])
|
89
89
|
expect(collection.keys).to eq([filepath1])
|
90
|
-
|
90
|
+
expect(collection.values.size).to eq 1
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
data/spec/helpers/spec_helper.rb
CHANGED
@@ -247,4 +247,79 @@ describe LogStash::Inputs::File do
|
|
247
247
|
end
|
248
248
|
end
|
249
249
|
end
|
250
|
+
|
251
|
+
let(:temp_directory) { Stud::Temporary.directory }
|
252
|
+
let(:interval) { 0.1 }
|
253
|
+
let(:options) do
|
254
|
+
{
|
255
|
+
'mode' => "read",
|
256
|
+
'path' => "#{temp_directory}/*",
|
257
|
+
'stat_interval' => interval,
|
258
|
+
'discover_interval' => interval,
|
259
|
+
'sincedb_path' => "#{temp_directory}/.sincedb",
|
260
|
+
'sincedb_write_interval' => interval
|
261
|
+
}
|
262
|
+
end
|
263
|
+
|
264
|
+
let(:queue) { Queue.new }
|
265
|
+
let(:plugin) { LogStash::Inputs::File.new(options) }
|
266
|
+
|
267
|
+
describe 'delete on complete' do
|
268
|
+
|
269
|
+
let(:options) do
|
270
|
+
super.merge({ 'file_completed_action' => "delete", 'exit_after_read' => false })
|
271
|
+
end
|
272
|
+
|
273
|
+
let(:sample_file) { File.join(temp_directory, "sample.log") }
|
274
|
+
|
275
|
+
before do
|
276
|
+
plugin.register
|
277
|
+
@run_thread = Thread.new(plugin) do |plugin|
|
278
|
+
Thread.current.abort_on_exception = true
|
279
|
+
plugin.run queue
|
280
|
+
end
|
281
|
+
|
282
|
+
File.open(sample_file, 'w') { |fd| fd.write("sample-content\n") }
|
283
|
+
|
284
|
+
wait_for_start_processing(@run_thread)
|
285
|
+
end
|
286
|
+
|
287
|
+
after { plugin.stop }
|
288
|
+
|
289
|
+
it 'processes a file' do
|
290
|
+
wait_for_file_removal(sample_file) # watched discovery
|
291
|
+
|
292
|
+
expect( plugin.queue.size ).to eql 1
|
293
|
+
event = plugin.queue.pop
|
294
|
+
expect( event.get('message') ).to eql 'sample-content'
|
295
|
+
end
|
296
|
+
|
297
|
+
it 'removes watched file from collection' do
|
298
|
+
wait_for_file_removal(sample_file) # watched discovery
|
299
|
+
sleep(0.25) # give CI some space to execute the removal
|
300
|
+
# TODO shouldn't be necessary once WatchedFileCollection does proper locking
|
301
|
+
watched_files = plugin.watcher.watch.watched_files_collection
|
302
|
+
expect( watched_files ).to be_empty
|
303
|
+
end
|
304
|
+
|
305
|
+
private
|
306
|
+
|
307
|
+
def wait_for_start_processing(run_thread, timeout: 1.0)
|
308
|
+
begin
|
309
|
+
Timeout.timeout(timeout) do
|
310
|
+
sleep(0.01) while run_thread.status != 'sleep'
|
311
|
+
sleep(timeout) unless plugin.queue
|
312
|
+
end
|
313
|
+
rescue Timeout::Error
|
314
|
+
raise "plugin did not start processing (timeout: #{timeout})" unless plugin.queue
|
315
|
+
else
|
316
|
+
raise "plugin did not start processing" unless plugin.queue
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
def wait_for_file_removal(path, timeout: 3 * interval)
|
321
|
+
wait(timeout).for { File.exist?(path) }.to be_falsey
|
322
|
+
end
|
323
|
+
|
324
|
+
end
|
250
325
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-input-file
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.1.
|
4
|
+
version: 4.1.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-04-
|
11
|
+
date: 2020-04-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|