logstash-input-file 4.1.17 → 4.1.18
Sign up to get free protection for your applications and to get access to all the features.
- 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
|