Skip to content

Commit 9d698b1

Browse files
author
Guy Boertje
authored
Force all files under rotation to start at 0 or at the sincedb record. (logstash-plugins#217)
* Force all files under rotation to start at 0 or at the sincedb record. * Update travis.yml to update versions. Fixes logstash-plugins#214
1 parent 6438462 commit 9d698b1

File tree

9 files changed

+64
-18
lines changed

9 files changed

+64
-18
lines changed

.travis.yml

+2-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ addons:
77
- docker-ce
88
matrix:
99
include:
10-
- env: ELASTIC_STACK_VERSION=5.6.10
11-
- env: ELASTIC_STACK_VERSION=6.3.0
12-
- env: ELASTIC_STACK_VERSION=6.4.0-SNAPSHOT
10+
- env: ELASTIC_STACK_VERSION=5.6.12
11+
- env: ELASTIC_STACK_VERSION=6.4.2
1312
- env: ELASTIC_STACK_VERSION=7.0.0-alpha1-SNAPSHOT
1413
fast_finish: true
1514
install: ci/unit/docker-setup.sh

CHANGELOG.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 4.1.7
2+
- Fixed problem in rotation handling where the target file being rotated was
3+
subjected to the start_position setting when it must always start from the beginning.
4+
[Issue #214](https://github.com/logstash-plugins/logstash-input-file/issues/214)
5+
16
## 4.1.6
27
- Fixed Errno::ENOENT exception in Discoverer. [Issue #204](https://github.com/logstash-plugins/logstash-input-file/issues/204)
38

@@ -15,7 +20,7 @@
1520
was possible to read into memory allocated but not filled with data resulting
1621
in ASCII NUL (0) bytes in the message field. Now, files are read up to the
1722
size as given by the remote filesystem client. Applies to tail and read modes.
18-
23+
1924
## 4.1.3
2025
- Fixed `read` mode of regular files sincedb write is requested in each read loop
2126
iteration rather than waiting for the end-of-file to be reached. Note: for gz files,

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,5 @@ jar.finalizedBy(copyGemjar)
6464
// See http://www.gradle.org/docs/current/userguide/gradle_wrapper.html
6565
task wrapper(type: Wrapper) {
6666
description = 'Install Gradle wrapper'
67-
gradleVersion = '4.5.1'
67+
gradleVersion = '4.9'
6868
}

gradle/wrapper/gradle-wrapper.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
33
zipStoreBase=GRADLE_USER_HOME
44
zipStorePath=wrapper/dists
5-
distributionUrl=https\://services.gradle.org/distributions/gradle-4.5.1-bin.zip
5+
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip

lib/filewatch/read_mode/processor.rb

+2
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ def process_watched(watched_files)
8080
end
8181
end
8282

83+
## TODO add process_rotation_in_progress
84+
8385
def process_active(watched_files)
8486
logger.trace("Active processing")
8587
# Handles watched_files in the active state.

lib/filewatch/tail_mode/processor.rb

+6-4
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,16 @@ def process_rotation_in_progress(watched_files)
168168
potential_sdb_value = @sincedb_collection.get(potential_key)
169169
logger.trace(">>> Rotation In Progress", "watched_file" => watched_file.details, "found_sdb_value" => sdb_value, "potential_key" => potential_key, "potential_sdb_value" => potential_sdb_value)
170170
if potential_sdb_value.nil?
171+
logger.trace("---------- >>>> Rotation In Progress: rotating as existing file")
172+
watched_file.rotate_as_file
173+
trace_message = "---------- >>>> Rotation In Progress: no potential sincedb value "
171174
if sdb_value.nil?
172-
logger.trace("---------- >>> Rotation In Progress: rotating as initial file, no potential sincedb value AND no found sincedb value")
173-
watched_file.rotate_as_initial_file
175+
trace_message.concat("AND no found sincedb value")
174176
else
175-
logger.trace("---------- >>>> Rotation In Progress: rotating as existing file, no potential sincedb value BUT found sincedb value")
176-
watched_file.rotate_as_file
177+
trace_message.concat("BUT found sincedb value")
177178
sdb_value.clear_watched_file
178179
end
180+
logger.trace(trace_message)
179181
new_sdb_value = SincedbValue.new(0)
180182
new_sdb_value.set_watched_file(watched_file)
181183
@sincedb_collection.set(potential_key, new_sdb_value)

lib/filewatch/watched_file.rb

-6
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,6 @@ def set_stat(stat)
7676
@sdb_key_v1 = @stat.inode_struct
7777
end
7878

79-
def rotate_as_initial_file
80-
# rotation, when no sincedb record exists for new inode - we have never seen this inode before.
81-
rotate_as_file
82-
@initial = true
83-
end
84-
8579
def rotate_as_file(bytes_read = 0)
8680
# rotation, when a sincedb record exists for new inode, but no watched file to rotate from
8781
# probably caused by a deletion detected in the middle of the rename cascade

logstash-input-file.gemspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Gem::Specification.new do |s|
22

33
s.name = 'logstash-input-file'
4-
s.version = '4.1.6'
4+
s.version = '4.1.7'
55
s.licenses = ['Apache-2.0']
66
s.summary = "Streams events from files"
77
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"

spec/filewatch/rotate_spec.rb

+45-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ module FileWatch
2828
let(:max) { 4095 }
2929
let(:stat_interval) { 0.01 }
3030
let(:discover_interval) { 15 }
31-
let(:start_new_files_at) { :beginning }
31+
let(:start_new_files_at) { :end }
3232
let(:sincedb_path) { directory.join("tailing.sdb") }
3333
let(:opts) do
3434
{
@@ -447,5 +447,49 @@ module FileWatch
447447
expect(listener3.lines.size).to eq(0)
448448
end
449449
end
450+
451+
context "? rotation: when an active file is renamed inside the glob - issue 214" do
452+
let(:watch_dir) { directory.join("*L.log") }
453+
let(:file_path) { directory.join("1L.log") }
454+
let(:second_file) { directory.join("2L.log") }
455+
subject { described_class.new(conf) }
456+
let(:listener1) { observer.listener_for(file1_path) }
457+
let(:listener2) { observer.listener_for(second_file.to_path) }
458+
let(:stat_interval) { 0.25 }
459+
let(:discover_interval) { 1 }
460+
let(:line4) { "Line 4 - Some other non lorem ipsum content" }
461+
let(:actions) do
462+
RSpec::Sequencing
463+
.run_after(0.75, "create file") do
464+
file_path.open("wb") { |file| file.puts(line1); file.puts(line2) }
465+
end
466+
.then_after(0.5, "rename") do
467+
file_path.rename(second_file)
468+
file_path.open("wb") { |file| file.puts("#{line3}") }
469+
end
470+
.then("wait for expectations to be met") do
471+
wait(2.0).for{listener1.lines.size + listener2.lines.size}.to eq(3)
472+
end
473+
.then_after(0.5, "rename again") do
474+
file_path.rename(second_file)
475+
file_path.open("wb") { |file| file.puts("#{line4}") }
476+
end
477+
.then("wait for expectations to be met") do
478+
wait(2.0).for{listener1.lines.size + listener2.lines.size}.to eq(4)
479+
end
480+
.then("quit") do
481+
tailing.quit
482+
end
483+
end
484+
485+
it "content is read correctly, the renamed file is not reread from scratch" do
486+
actions.activate_quietly
487+
tailing.watch_this(watch_dir.to_path)
488+
tailing.subscribe(observer)
489+
actions.assert_no_errors
490+
expect(listener1.lines).to eq([line1, line2, line3, line4])
491+
expect(listener2.lines).to eq([])
492+
end
493+
end
450494
end
451495
end

0 commit comments

Comments
 (0)