logstash-input-file 2.1.3 → 2.2.0

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
  SHA1:
3
- metadata.gz: 6df644dbc8e574f5611d6c27cef8eb372ecae09d
4
- data.tar.gz: ca7e69428222362a80af560b1728bdc97abf6008
3
+ metadata.gz: 6412fcb09af0a0e32879a180c77e409c868caa43
4
+ data.tar.gz: 1d2fe6993ca73c122b2002a6c72c5d0f68a1fb9a
5
5
  SHA512:
6
- metadata.gz: e60e2247d23a0dad2f69fff24aafb80fb04f44b10a33fc1bb332a19c02a6a3930c2baebf597521646c40a3aefb5e77cee6541e23737e6b36fab863dc42dcfeed
7
- data.tar.gz: 9b1f5ee7af2a8b3340be9d11592cc1d1056198c07ce7deec5b204dd91c98fb534903d50aae27d5a52effef4ec9fbfaaee90798186d7434fc8ab9139f2c8e4543
6
+ metadata.gz: 2418a21eb0d3ea85185158c69ccbb971b332da29476fcdd7508249f3c28edda61c6a98e6886484a4a9bda6fd3e2b9ac0057eb6a8a84de17b2af075f4671cbae6
7
+ data.tar.gz: 189d29b3ccfbabdc6ad77d510cccb416dc0c738564676101a76beec9f37129c922f79ba613fb280d7486e70b4450693f9f08872a50372f93e467b09640cd9e73
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 2.2.0
2
+ - Use ruby-filewatch 0.8.0, major rework of filewatch. See [Pull Request 74](https://github.com/jordansissel/ruby-filewatch/pull/74)
3
+ - add max_open_files config option, defaults to 4095, the input will process much more than this but have this number of files open at any time - files are closed based on the close_older setting, thereby making others openable.
4
+ - Changes the close_older logic to measure the time since the file was last read internlly rather than using the file stat modified time.
5
+ - Use logstash-codec-multiline 2.0.7, fixes a bug with auto_flush deadlocking when multiple file inputs are defined in the LS config.
6
+
1
7
  ## 2.1.3
2
8
  - Use ruby-filewatch 0.7.1, re-enable close after file is modified again
3
9
 
@@ -35,6 +35,10 @@ require "socket" # for Socket.gethostname
35
35
  # patterns with any frequency it might make sense to explicitly choose
36
36
  # a sincedb path with the `sincedb_path` option.
37
37
  #
38
+ # A different `sincedb_path` must be used for each input. Using the same
39
+ # path will cause issues. The read checkpoints for each input must be
40
+ # stored in a different path so the information does not override.
41
+ #
38
42
  # Sincedb files are text files with four columns:
39
43
  #
40
44
  # . The inode number (or equivalent).
@@ -141,11 +145,24 @@ class LogStash::Inputs::File < LogStash::Inputs::Base
141
145
  # longer ignored and any new data is read. The default is 24 hours.
142
146
  config :ignore_older, :validate => :number, :default => 24 * 60 * 60
143
147
 
144
- # If this option is specified, the file input closes any files that remain
145
- # unmodified for longer than the specified timespan in seconds.
148
+ # If this option is specified, the file input closes any files that were last
149
+ # read the specified timespan in seconds ago.
150
+ # This has different implications depending on if a file is being tailed or
151
+ # read. If tailing, and there is a large time gap in incoming data the file
152
+ # can be closed (allowing other files to be opened) but will be queued for
153
+ # reopening when new data is detected. If reading, the file will be closed
154
+ # after closed_older seconds from when the last bytes were read.
146
155
  # The default is 1 hour
147
156
  config :close_older, :validate => :number, :default => 1 * 60 * 60
148
157
 
158
+ # What is the maximum number of file_handles that this input consumes
159
+ # at any one time. Use close_older to close some files if you need to
160
+ # process more files than this number. This should not be set to the
161
+ # maximum the OS can do because file handles are needed for other
162
+ # LS plugins and OS processes.
163
+ # The default of 4095 is set in filewatch.
164
+ config :max_open_files, :validate => :number
165
+
149
166
  public
150
167
  def register
151
168
  require "addressable/uri"
@@ -161,7 +178,8 @@ class LogStash::Inputs::File < LogStash::Inputs::Base
161
178
  :sincedb_write_interval => @sincedb_write_interval,
162
179
  :delimiter => @delimiter,
163
180
  :ignore_older => @ignore_older,
164
- :close_older => @close_older
181
+ :close_older => @close_older,
182
+ :max_open_files => @max_open_files
165
183
  }
166
184
 
167
185
  @path.each do |path|
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-input-file'
4
- s.version = '2.1.3'
4
+ s.version = '2.2.0'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "Stream 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/plugin install gemname. This gem is not a stand-alone program"
@@ -24,8 +24,8 @@ Gem::Specification.new do |s|
24
24
 
25
25
  s.add_runtime_dependency 'logstash-codec-plain'
26
26
  s.add_runtime_dependency 'addressable'
27
- s.add_runtime_dependency 'filewatch', ['>= 0.7.1', '~> 0.7']
28
- s.add_runtime_dependency 'logstash-codec-multiline', ['~> 2.0.5']
27
+ s.add_runtime_dependency 'filewatch', ['>= 0.8.0', '~> 0.8']
28
+ s.add_runtime_dependency 'logstash-codec-multiline', ['~> 2.0.7']
29
29
 
30
30
  s.add_development_dependency 'stud', ['~> 0.0.19']
31
31
  s.add_development_dependency 'logstash-devutils'
@@ -152,6 +152,10 @@ describe LogStash::Inputs::File do
152
152
  let(:sincedb_path) { Stud::Temporary.pathname }
153
153
  let(:tmpdir_path) { Stud::Temporary.directory }
154
154
 
155
+ after :each do
156
+ FileUtils.rm_rf(sincedb_path)
157
+ end
158
+
155
159
  context "when data exists and then more data is appended" do
156
160
  subject { described_class.new(conf) }
157
161
 
@@ -369,6 +373,7 @@ describe LogStash::Inputs::File do
369
373
  conf.update(
370
374
  "path" => tmpdir_path + "/*.log",
371
375
  "start_position" => "beginning",
376
+ "stat_interval" => 0.1,
372
377
  "sincedb_path" => sincedb_path)
373
378
 
374
379
  File.open(file_path, "w") do |fd|
@@ -382,14 +387,98 @@ describe LogStash::Inputs::File do
382
387
  subject.register
383
388
  expect(lsof_proc.call).to eq("")
384
389
  run_thread_proc.call
385
- sleep 0.1
390
+ sleep 0.25
386
391
  first_lsof = lsof_proc.call
387
- expect(first_lsof).not_to eq("")
392
+ expect(first_lsof.scan(file_path).size).to eq(1)
388
393
  run_thread_proc.call
389
- sleep 0.1
394
+ sleep 0.25
390
395
  second_lsof = lsof_proc.call
391
- expect(second_lsof).to eq(first_lsof)
396
+ expect(second_lsof.scan(file_path).size).to eq(1)
397
+ end
398
+ end
399
+
400
+ describe "specifying max_open_files" do
401
+ subject { described_class.new(conf) }
402
+ before do
403
+ File.open("#{tmpdir_path}/a.log", "w") do |fd|
404
+ fd.puts("line1-of-a")
405
+ fd.puts("line2-of-a")
406
+ fd.fsync
407
+ end
408
+ File.open("#{tmpdir_path}/z.log", "w") do |fd|
409
+ fd.puts("line1-of-z")
410
+ fd.puts("line2-of-z")
411
+ fd.fsync
412
+ end
392
413
  end
414
+
415
+ context "when close_older is NOT specified" do
416
+ before do
417
+ conf.clear
418
+ conf.update(
419
+ "type" => "blah",
420
+ "path" => "#{tmpdir_path}/*.log",
421
+ "sincedb_path" => sincedb_path,
422
+ "stat_interval" => 0.1,
423
+ "max_open_files" => 1,
424
+ "start_position" => "beginning",
425
+ "delimiter" => FILE_DELIMITER)
426
+ subject.register
427
+ Thread.new { subject.run(events) }
428
+ sleep 0.1
429
+ end
430
+ it "collects line events from only one file" do
431
+ # wait for one path to be mapped as identity
432
+ expect(pause_until{ subject.codec.identity_count == 1 }).to be_truthy
433
+ subject.stop
434
+ # stop flushes last event
435
+ expect(pause_until{ events.size == 2 }).to be_truthy
436
+
437
+ e1, e2 = events
438
+ if Dir.glob("#{tmpdir_path}/*.log").first =~ %r{a\.log}
439
+ #linux and OSX have different retrieval order
440
+ expect(e1["message"]).to eq("line1-of-a")
441
+ expect(e2["message"]).to eq("line2-of-a")
442
+ else
443
+ expect(e1["message"]).to eq("line1-of-z")
444
+ expect(e2["message"]).to eq("line2-of-z")
445
+ end
446
+ end
447
+ end
448
+
449
+ context "when close_older IS specified" do
450
+ before do
451
+ conf.update(
452
+ "type" => "blah",
453
+ "path" => "#{tmpdir_path}/*.log",
454
+ "sincedb_path" => sincedb_path,
455
+ "stat_interval" => 0.1,
456
+ "max_open_files" => 1,
457
+ "close_older" => 1,
458
+ "start_position" => "beginning",
459
+ "delimiter" => FILE_DELIMITER)
460
+ subject.register
461
+ Thread.new { subject.run(events) }
462
+ sleep 0.1
463
+ end
464
+
465
+ it "collects line events from both files" do
466
+ # close flushes last event of each identity
467
+ expect(pause_until{ events.size == 4 }).to be_truthy
468
+ subject.stop
469
+ if Dir.glob("#{tmpdir_path}/*.log").first =~ %r{a\.log}
470
+ #linux and OSX have different retrieval order
471
+ e1, e2, e3, e4 = events
472
+ else
473
+ e3, e4, e1, e2 = events
474
+ end
475
+ expect(e1["message"]).to eq("line1-of-a")
476
+ expect(e2["message"]).to eq("line2-of-a")
477
+ expect(e3["message"]).to eq("line1-of-z")
478
+ expect(e4["message"]).to eq("line2-of-z")
479
+ end
480
+ end
481
+
393
482
  end
394
483
  end
395
484
  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: 2.1.3
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-04 00:00:00.000000000 Z
11
+ date: 2016-01-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logstash-core
@@ -64,18 +64,18 @@ dependencies:
64
64
  requirements:
65
65
  - - '>='
66
66
  - !ruby/object:Gem::Version
67
- version: 0.7.1
67
+ version: 0.8.0
68
68
  - - ~>
69
69
  - !ruby/object:Gem::Version
70
- version: '0.7'
70
+ version: '0.8'
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - '>='
74
74
  - !ruby/object:Gem::Version
75
- version: 0.7.1
75
+ version: 0.8.0
76
76
  - - ~>
77
77
  - !ruby/object:Gem::Version
78
- version: '0.7'
78
+ version: '0.8'
79
79
  prerelease: false
80
80
  type: :runtime
81
81
  - !ruby/object:Gem::Dependency
@@ -84,12 +84,12 @@ dependencies:
84
84
  requirements:
85
85
  - - ~>
86
86
  - !ruby/object:Gem::Version
87
- version: 2.0.5
87
+ version: 2.0.7
88
88
  requirement: !ruby/object:Gem::Requirement
89
89
  requirements:
90
90
  - - ~>
91
91
  - !ruby/object:Gem::Version
92
- version: 2.0.5
92
+ version: 2.0.7
93
93
  prerelease: false
94
94
  type: :runtime
95
95
  - !ruby/object:Gem::Dependency
@@ -147,7 +147,6 @@ files:
147
147
  - NOTICE.TXT
148
148
  - README.md
149
149
  - lib/logstash/inputs/file.rb
150
- - lib/logstash/inputs/identity_map_codec_component.rb
151
150
  - logstash-input-file.gemspec
152
151
  - spec/inputs/file_spec.rb
153
152
  - spec/spec_helper.rb
@@ -1,56 +0,0 @@
1
- # encoding: utf-8
2
- require "logstash/inputs/component"
3
- require "logstash/codecs/identity_map_codec"
4
-
5
- module LogStash module Inputs class IdentityMapCodecComponent
6
- include Component
7
-
8
- attr_reader :codec
9
-
10
- def add_codec(codec)
11
- @codec = LogStash::Codecs::IdentityMapCodec.new(codec)
12
- self
13
- end
14
-
15
- def stop
16
- @codec.close
17
- end
18
-
19
- def do_work(context, data)
20
- do_line(context, data) || do_eviction(context, data)
21
- end
22
-
23
- def process(context, data)
24
- # data should be an event
25
- deliver(context, data)
26
- end
27
-
28
- private
29
-
30
- def do_line(context, data)
31
- return false unless line?(context)
32
- @codec.decode_accept(context, data, self)
33
- # above should call back on #process
34
- true
35
- end
36
-
37
- def do_eviction(context, data)
38
- return false unless evicting?(context)
39
- path = context[:path]
40
- @codec.evict(path) if path
41
- true
42
- end
43
-
44
- def line?(ctx)
45
- action(ctx) == "line"
46
- end
47
-
48
- def evicting?(ctx)
49
- _action = action(ctx)
50
- _action == "timed_out" || _action == "deleted"
51
- end
52
-
53
- def action(ctx)
54
- ctx[:action]
55
- end
56
- end end end