logstash-input-file 4.1.18 → 4.2.0
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 +4 -0
- data/lib/filewatch/discoverer.rb +9 -8
- data/lib/filewatch/observing_base.rb +1 -2
- data/lib/filewatch/processor.rb +55 -0
- data/lib/filewatch/read_mode/handlers/base.rb +8 -6
- data/lib/filewatch/read_mode/handlers/read_file.rb +19 -6
- data/lib/filewatch/read_mode/handlers/read_zip_file.rb +8 -6
- data/lib/filewatch/read_mode/processor.rb +22 -36
- data/lib/filewatch/sincedb_collection.rb +11 -9
- data/lib/filewatch/stat/generic.rb +8 -13
- data/lib/filewatch/stat/windows_path.rb +7 -9
- data/lib/filewatch/tail_mode/handlers/delete.rb +2 -4
- data/lib/filewatch/tail_mode/processor.rb +47 -54
- data/lib/filewatch/watch.rb +9 -14
- data/lib/filewatch/watched_file.rb +25 -14
- data/lib/filewatch/watched_files_collection.rb +11 -78
- data/lib/jars/filewatch-1.0.1.jar +0 -0
- data/lib/logstash/inputs/file.rb +2 -1
- data/logstash-input-file.gemspec +2 -1
- data/spec/filewatch/reading_spec.rb +60 -9
- data/spec/filewatch/settings_spec.rb +3 -0
- data/spec/filewatch/spec_helper.rb +12 -14
- data/spec/filewatch/tailing_spec.rb +14 -12
- data/spec/filewatch/watched_file_spec.rb +30 -0
- data/spec/filewatch/watched_files_collection_spec.rb +62 -8
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6cdc2495fe9eb7a2c84aaaac6ea922a6034a9ad1bd8223f021ed9bd77fedae74
|
4
|
+
data.tar.gz: 4e6ba1c9fc044ff6cd93cbc92c16d114415357877ea75ad2fce375514517f0d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a790d7f2a79551d8e8a96ca8cee597c1baba4dd9eabff1f9cc806432072a58826c6066922431f020105d7d86a53b22a2a0136e3c132d1b4d532f844a4a815f2e
|
7
|
+
data.tar.gz: 0d4528eab5b7c56b9b6b62b7f0e7124c8bd47745ac46fb915210a7647021fd3fd0f97f4ef031d14fdd6ec03b28b697dd255c9ec9676d888cbf1107d987609c92
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## 4.2.0
|
2
|
+
- Fix: watched files performance with huge filesets [#268](https://github.com/logstash-plugins/logstash-input-file/pull/268)
|
3
|
+
- Updated logging to include full traces in debug (and trace) levels
|
4
|
+
|
1
5
|
## 4.1.18
|
2
6
|
- Fix: release watched files on completion (in read-mode) [#271](https://github.com/logstash-plugins/logstash-input-file/pull/271)
|
3
7
|
|
data/lib/filewatch/discoverer.rb
CHANGED
@@ -9,6 +9,8 @@ module FileWatch
|
|
9
9
|
# associated with a sincedb entry if one can be found
|
10
10
|
include LogStash::Util::Loggable
|
11
11
|
|
12
|
+
attr_reader :watched_files_collection
|
13
|
+
|
12
14
|
def initialize(watched_files_collection, sincedb_collection, settings)
|
13
15
|
@watching = Concurrent::Array.new
|
14
16
|
@exclude = Concurrent::Array.new
|
@@ -37,8 +39,7 @@ module FileWatch
|
|
37
39
|
@exclude.each do |pattern|
|
38
40
|
if watched_file.pathname.basename.fnmatch?(pattern)
|
39
41
|
if new_discovery
|
40
|
-
logger.trace("
|
41
|
-
"because it matches exclude #{pattern}")
|
42
|
+
logger.trace("skipping file because it matches exclude", :path => watched_file.path, :pattern => pattern)
|
42
43
|
end
|
43
44
|
watched_file.unwatch
|
44
45
|
return true
|
@@ -56,13 +57,13 @@ module FileWatch
|
|
56
57
|
end
|
57
58
|
|
58
59
|
def discover_any_files(path, ongoing)
|
59
|
-
fileset = Dir.glob(path).select{|f| File.file?(f)}
|
60
|
-
logger.trace("discover_files",
|
60
|
+
fileset = Dir.glob(path).select { |f| File.file?(f) }
|
61
|
+
logger.trace("discover_files", :count => fileset.size)
|
61
62
|
fileset.each do |file|
|
62
|
-
pathname = Pathname.new(file)
|
63
63
|
new_discovery = false
|
64
|
-
watched_file = @watched_files_collection.
|
64
|
+
watched_file = @watched_files_collection.get(file)
|
65
65
|
if watched_file.nil?
|
66
|
+
pathname = Pathname.new(file)
|
66
67
|
begin
|
67
68
|
path_stat = PathStatClass.new(pathname)
|
68
69
|
rescue Errno::ENOENT
|
@@ -74,7 +75,7 @@ module FileWatch
|
|
74
75
|
# if it already unwatched or its excluded then we can skip
|
75
76
|
next if watched_file.unwatched? || can_exclude?(watched_file, new_discovery)
|
76
77
|
|
77
|
-
logger.trace("
|
78
|
+
logger.trace? && logger.trace("handling:", :new_discovery => new_discovery, :watched_file => watched_file.details)
|
78
79
|
|
79
80
|
if new_discovery
|
80
81
|
watched_file.initial_completed if ongoing
|
@@ -86,7 +87,7 @@ module FileWatch
|
|
86
87
|
# associated with a different watched_file
|
87
88
|
if @sincedb_collection.associate(watched_file)
|
88
89
|
if watched_file.file_ignorable?
|
89
|
-
logger.trace("
|
90
|
+
logger.trace("skipping file because it was last modified more than #{@settings.ignore_older} seconds ago", :path => file)
|
90
91
|
# on discovery ignorable watched_files are put into the ignored state and that
|
91
92
|
# updates the size from the internal stat
|
92
93
|
# so the existing contents are not read.
|
@@ -62,8 +62,7 @@ module FileWatch
|
|
62
62
|
@sincedb_collection = SincedbCollection.new(@settings)
|
63
63
|
@sincedb_collection.open
|
64
64
|
discoverer = Discoverer.new(watched_files_collection, @sincedb_collection, @settings)
|
65
|
-
@watch = Watch.new(discoverer,
|
66
|
-
@watch.add_processor build_specific_processor(@settings)
|
65
|
+
@watch = Watch.new(discoverer, build_specific_processor(@settings), @settings)
|
67
66
|
end
|
68
67
|
|
69
68
|
def watch_this(path)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/util/loggable"
|
3
|
+
require 'concurrent/atomic/atomic_reference'
|
4
|
+
|
5
|
+
module FileWatch
|
6
|
+
class Processor
|
7
|
+
include LogStash::Util::Loggable
|
8
|
+
|
9
|
+
attr_reader :watch
|
10
|
+
|
11
|
+
def initialize(settings)
|
12
|
+
@settings = settings
|
13
|
+
@deletable_paths = Concurrent::AtomicReference.new []
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_watch(watch)
|
17
|
+
@watch = watch
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def clear_deletable_paths
|
22
|
+
@deletable_paths.get_and_set []
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_deletable_path(path)
|
26
|
+
@deletable_paths.get << path
|
27
|
+
end
|
28
|
+
|
29
|
+
def restat(watched_file)
|
30
|
+
changed = watched_file.restat!
|
31
|
+
if changed
|
32
|
+
# the collection (when sorted by modified_at) needs to re-sort every time watched-file is modified,
|
33
|
+
# we can perform these update operation while processing files (stat interval) instead of having to
|
34
|
+
# re-sort the whole collection every time an entry is accessed
|
35
|
+
@watch.watched_files_collection.update(watched_file)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def error_details(error, watched_file)
|
42
|
+
details = { :path => watched_file.path,
|
43
|
+
:exception => error.class,
|
44
|
+
:message => error.message,
|
45
|
+
:backtrace => error.backtrace }
|
46
|
+
if logger.debug?
|
47
|
+
details[:file] = watched_file
|
48
|
+
else
|
49
|
+
details[:backtrace] = details[:backtrace].take(8) if details[:backtrace]
|
50
|
+
end
|
51
|
+
details
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -34,19 +34,21 @@ module FileWatch module ReadMode module Handlers
|
|
34
34
|
|
35
35
|
def open_file(watched_file)
|
36
36
|
return true if watched_file.file_open?
|
37
|
-
logger.trace("opening
|
37
|
+
logger.trace? && logger.trace("opening", :path => watched_file.path)
|
38
38
|
begin
|
39
39
|
watched_file.open
|
40
|
-
rescue
|
40
|
+
rescue => e
|
41
41
|
# don't emit this message too often. if a file that we can't
|
42
42
|
# read is changing a lot, we'll try to open it more often, and spam the logs.
|
43
43
|
now = Time.now.to_i
|
44
44
|
logger.trace("opening OPEN_WARN_INTERVAL is '#{OPEN_WARN_INTERVAL}'")
|
45
45
|
if watched_file.last_open_warning_at.nil? || now - watched_file.last_open_warning_at > OPEN_WARN_INTERVAL
|
46
|
-
|
46
|
+
backtrace = e.backtrace
|
47
|
+
backtrace = backtrace.take(3) if backtrace && !logger.debug?
|
48
|
+
logger.warn("failed to open", :path => watched_file.path, :exception => e.class, :message => e.message, :backtrace => backtrace)
|
47
49
|
watched_file.last_open_warning_at = now
|
48
50
|
else
|
49
|
-
logger.trace("suppressed warning
|
51
|
+
logger.trace("suppressed warning (failed to open)", :path => watched_file.path, :exception => e.class, :message => e.message)
|
50
52
|
end
|
51
53
|
watched_file.watch # set it back to watch so we can try it again
|
52
54
|
end
|
@@ -75,7 +77,7 @@ module FileWatch module ReadMode module Handlers
|
|
75
77
|
watched_file.update_bytes_read(sincedb_value.position)
|
76
78
|
else
|
77
79
|
sincedb_value.set_watched_file(watched_file)
|
78
|
-
logger.trace("add_or_update_sincedb_collection: switching from
|
80
|
+
logger.trace("add_or_update_sincedb_collection: switching from", :watched_file => watched_file.details)
|
79
81
|
watched_file.rotate_from(existing_watched_file)
|
80
82
|
end
|
81
83
|
|
@@ -92,7 +94,7 @@ module FileWatch module ReadMode module Handlers
|
|
92
94
|
def add_new_value_sincedb_collection(watched_file)
|
93
95
|
sincedb_value = SincedbValue.new(0)
|
94
96
|
sincedb_value.set_watched_file(watched_file)
|
95
|
-
logger.trace("add_new_value_sincedb_collection:
|
97
|
+
logger.trace("add_new_value_sincedb_collection:", :path => watched_file.path, :position => sincedb_value.position)
|
96
98
|
sincedb_collection.set(watched_file.sincedb_key, sincedb_value)
|
97
99
|
end
|
98
100
|
end
|
@@ -31,7 +31,7 @@ module FileWatch module ReadMode module Handlers
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def controlled_read(watched_file, loop_control)
|
34
|
-
logger.trace("reading...",
|
34
|
+
logger.trace? && logger.trace("reading...", :filename => watched_file.filename, :iterations => loop_control.count, :amount => loop_control.size)
|
35
35
|
loop_control.count.times do
|
36
36
|
break if quit?
|
37
37
|
begin
|
@@ -43,22 +43,35 @@ module FileWatch module ReadMode module Handlers
|
|
43
43
|
delta = line.bytesize + @settings.delimiter_byte_size
|
44
44
|
sincedb_collection.increment(watched_file.sincedb_key, delta)
|
45
45
|
end
|
46
|
-
rescue EOFError
|
47
|
-
|
46
|
+
rescue EOFError => e
|
47
|
+
log_error("controlled_read: eof error reading file", watched_file, e)
|
48
48
|
loop_control.flag_read_error
|
49
49
|
break
|
50
|
-
rescue Errno::EWOULDBLOCK, Errno::EINTR
|
51
|
-
|
50
|
+
rescue Errno::EWOULDBLOCK, Errno::EINTR => e
|
51
|
+
log_error("controlled_read: block or interrupt error reading file", watched_file, e)
|
52
52
|
watched_file.listener.error
|
53
53
|
loop_control.flag_read_error
|
54
54
|
break
|
55
55
|
rescue => e
|
56
|
-
|
56
|
+
log_error("controlled_read: general error reading file", watched_file, e)
|
57
57
|
watched_file.listener.error
|
58
58
|
loop_control.flag_read_error
|
59
59
|
break
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
63
|
+
|
64
|
+
def log_error(msg, watched_file, error)
|
65
|
+
details = { :path => watched_file.path,
|
66
|
+
:exception => error.class,
|
67
|
+
:message => error.message,
|
68
|
+
:backtrace => error.backtrace }
|
69
|
+
if logger.debug?
|
70
|
+
details[:file] = watched_file
|
71
|
+
else
|
72
|
+
details[:backtrace] = details[:backtrace].take(8) if details[:backtrace]
|
73
|
+
end
|
74
|
+
logger.error(msg, details)
|
75
|
+
end
|
63
76
|
end
|
64
77
|
end end end
|
@@ -1,13 +1,15 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'java'
|
3
|
-
java_import java.io.InputStream
|
4
|
-
java_import java.io.InputStreamReader
|
5
|
-
java_import java.io.FileInputStream
|
6
|
-
java_import java.io.BufferedReader
|
7
|
-
java_import java.util.zip.GZIPInputStream
|
8
|
-
java_import java.util.zip.ZipException
|
9
3
|
|
10
4
|
module FileWatch module ReadMode module Handlers
|
5
|
+
|
6
|
+
java_import java.io.InputStream
|
7
|
+
java_import java.io.InputStreamReader
|
8
|
+
java_import java.io.FileInputStream
|
9
|
+
java_import java.io.BufferedReader
|
10
|
+
java_import java.util.zip.GZIPInputStream
|
11
|
+
java_import java.util.zip.ZipException
|
12
|
+
|
11
13
|
class ReadZipFile < Base
|
12
14
|
def handle_specifically(watched_file)
|
13
15
|
add_or_update_sincedb_collection(watched_file) unless sincedb_collection.member?(watched_file.sincedb_key)
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require
|
3
|
-
|
2
|
+
require 'filewatch/processor'
|
4
3
|
require_relative "handlers/base"
|
5
4
|
require_relative "handlers/read_file"
|
6
5
|
require_relative "handlers/read_zip_file"
|
@@ -9,20 +8,7 @@ module FileWatch module ReadMode
|
|
9
8
|
# Must handle
|
10
9
|
# :read_file
|
11
10
|
# :read_zip_file
|
12
|
-
class Processor
|
13
|
-
include LogStash::Util::Loggable
|
14
|
-
|
15
|
-
attr_reader :watch, :deletable_filepaths
|
16
|
-
|
17
|
-
def initialize(settings)
|
18
|
-
@settings = settings
|
19
|
-
@deletable_filepaths = []
|
20
|
-
end
|
21
|
-
|
22
|
-
def add_watch(watch)
|
23
|
-
@watch = watch
|
24
|
-
self
|
25
|
-
end
|
11
|
+
class Processor < FileWatch::Processor
|
26
12
|
|
27
13
|
def initialize_handlers(sincedb_collection, observer)
|
28
14
|
# we deviate from the tail mode handler initialization here
|
@@ -48,24 +34,23 @@ module FileWatch module ReadMode
|
|
48
34
|
private
|
49
35
|
|
50
36
|
def process_watched(watched_files)
|
51
|
-
logger.trace(
|
37
|
+
logger.trace(__method__.to_s)
|
52
38
|
# Handles watched_files in the watched state.
|
53
39
|
# for a slice of them:
|
54
40
|
# move to the active state
|
55
41
|
# should never have been active before
|
56
42
|
# how much of the max active window is available
|
57
|
-
to_take = @settings.max_active - watched_files.count{|wf| wf.active?}
|
43
|
+
to_take = @settings.max_active - watched_files.count { |wf| wf.active? }
|
58
44
|
if to_take > 0
|
59
|
-
watched_files.select
|
60
|
-
path = watched_file.path
|
45
|
+
watched_files.select(&:watched?).take(to_take).each do |watched_file|
|
61
46
|
begin
|
62
|
-
watched_file
|
47
|
+
restat(watched_file)
|
63
48
|
watched_file.activate
|
64
49
|
rescue Errno::ENOENT
|
65
|
-
common_deleted_reaction(watched_file,
|
50
|
+
common_deleted_reaction(watched_file, __method__)
|
66
51
|
next
|
67
52
|
rescue => e
|
68
|
-
common_error_reaction(
|
53
|
+
common_error_reaction(watched_file, e, __method__)
|
69
54
|
next
|
70
55
|
end
|
71
56
|
break if watch.quit?
|
@@ -74,7 +59,7 @@ module FileWatch module ReadMode
|
|
74
59
|
now = Time.now.to_i
|
75
60
|
if (now - watch.lastwarn_max_files) > MAX_FILES_WARN_INTERVAL
|
76
61
|
waiting = watched_files.size - @settings.max_active
|
77
|
-
logger.warn(@settings.max_warn_msg
|
62
|
+
logger.warn("#{@settings.max_warn_msg}, files yet to open: #{waiting}")
|
78
63
|
watch.lastwarn_max_files = now
|
79
64
|
end
|
80
65
|
end
|
@@ -83,17 +68,18 @@ module FileWatch module ReadMode
|
|
83
68
|
## TODO add process_rotation_in_progress
|
84
69
|
|
85
70
|
def process_active(watched_files)
|
86
|
-
logger.trace(
|
71
|
+
logger.trace(__method__.to_s)
|
87
72
|
# Handles watched_files in the active state.
|
88
|
-
watched_files.
|
89
|
-
|
73
|
+
watched_files.each do |watched_file|
|
74
|
+
next unless watched_file.active?
|
75
|
+
|
90
76
|
begin
|
91
|
-
watched_file
|
77
|
+
restat(watched_file)
|
92
78
|
rescue Errno::ENOENT
|
93
|
-
common_deleted_reaction(watched_file,
|
79
|
+
common_deleted_reaction(watched_file, __method__)
|
94
80
|
next
|
95
81
|
rescue => e
|
96
|
-
common_error_reaction(
|
82
|
+
common_error_reaction(watched_file, e, __method__)
|
97
83
|
next
|
98
84
|
end
|
99
85
|
break if watch.quit?
|
@@ -114,19 +100,19 @@ module FileWatch module ReadMode
|
|
114
100
|
def common_detach_when_allread(watched_file)
|
115
101
|
watched_file.unwatch
|
116
102
|
watched_file.listener.reading_completed
|
117
|
-
|
118
|
-
logger.trace("
|
103
|
+
add_deletable_path watched_file.path
|
104
|
+
logger.trace? && logger.trace("whole file read, removing from collection", :path => watched_file.path)
|
119
105
|
end
|
120
106
|
|
121
107
|
def common_deleted_reaction(watched_file, action)
|
122
108
|
# file has gone away or we can't read it anymore.
|
123
109
|
watched_file.unwatch
|
124
|
-
|
125
|
-
logger.trace("#{action} - stat failed
|
110
|
+
add_deletable_path watched_file.path
|
111
|
+
logger.trace? && logger.trace("#{action} - stat failed, removing from collection", :path => watched_file.path)
|
126
112
|
end
|
127
113
|
|
128
|
-
def common_error_reaction(
|
129
|
-
logger.error("#{action} - other error
|
114
|
+
def common_error_reaction(watched_file, error, action)
|
115
|
+
logger.error("#{action} - other error", error_details(error, watched_file))
|
130
116
|
end
|
131
117
|
end
|
132
118
|
end end
|
@@ -56,12 +56,12 @@ module FileWatch
|
|
56
56
|
logger.trace("open: count of keys read: #{@sincedb.keys.size}")
|
57
57
|
rescue => e
|
58
58
|
#No existing sincedb to load
|
59
|
-
logger.trace("open: error:
|
59
|
+
logger.trace("open: error:", :path => path, :exception => e.class, :message => e.message)
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
63
|
def associate(watched_file)
|
64
|
-
logger.trace("associate: finding",
|
64
|
+
logger.trace? && logger.trace("associate: finding", :path => watched_file.path, :inode => watched_file.sincedb_key.inode)
|
65
65
|
sincedb_value = find(watched_file)
|
66
66
|
if sincedb_value.nil?
|
67
67
|
# sincedb has no record of this inode
|
@@ -71,7 +71,8 @@ module FileWatch
|
|
71
71
|
logger.trace("associate: unmatched")
|
72
72
|
return true
|
73
73
|
end
|
74
|
-
logger.trace("associate: found sincedb record",
|
74
|
+
logger.trace? && logger.trace("associate: found sincedb record", :filename => watched_file.filename,
|
75
|
+
:sincedb_key => watched_file.sincedb_key, :sincedb_value => sincedb_value)
|
75
76
|
if sincedb_value.watched_file.nil?
|
76
77
|
# not associated
|
77
78
|
if sincedb_value.path_in_sincedb.nil?
|
@@ -106,7 +107,8 @@ module FileWatch
|
|
106
107
|
# after the original is deleted
|
107
108
|
# are not yet in the delete phase, let this play out
|
108
109
|
existing_watched_file = sincedb_value.watched_file
|
109
|
-
logger.trace("----------------- >> associate: the found sincedb_value has a watched_file - this is a rename",
|
110
|
+
logger.trace? && logger.trace("----------------- >> associate: the found sincedb_value has a watched_file - this is a rename",
|
111
|
+
:this_watched_file => watched_file.details, :existing_watched_file => existing_watched_file.details)
|
110
112
|
watched_file.rotation_in_progress
|
111
113
|
true
|
112
114
|
end
|
@@ -149,8 +151,8 @@ module FileWatch
|
|
149
151
|
end
|
150
152
|
|
151
153
|
def watched_file_deleted(watched_file)
|
152
|
-
|
153
|
-
|
154
|
+
value = @sincedb[watched_file.sincedb_key]
|
155
|
+
value.unset_watched_file if value
|
154
156
|
end
|
155
157
|
|
156
158
|
def store_last_read(key, pos)
|
@@ -195,7 +197,7 @@ module FileWatch
|
|
195
197
|
watched_file.initial_completed
|
196
198
|
if watched_file.all_read?
|
197
199
|
watched_file.ignore
|
198
|
-
logger.trace("handle_association fully read, ignoring.....",
|
200
|
+
logger.trace? && logger.trace("handle_association fully read, ignoring.....", :watched_file => watched_file.details, :sincedb_value => sincedb_value)
|
199
201
|
end
|
200
202
|
end
|
201
203
|
|
@@ -214,8 +216,8 @@ module FileWatch
|
|
214
216
|
@write_method.call
|
215
217
|
@serializer.expired_keys.each do |key|
|
216
218
|
@sincedb[key].unset_watched_file
|
217
|
-
delete(key)
|
218
|
-
logger.trace("sincedb_write: cleaned",
|
219
|
+
delete(key) # delete
|
220
|
+
logger.trace? && logger.trace("sincedb_write: cleaned", :key => key)
|
219
221
|
end
|
220
222
|
@sincedb_last_write = time
|
221
223
|
@write_requested = false
|
@@ -3,24 +3,19 @@
|
|
3
3
|
module FileWatch module Stat
|
4
4
|
class Generic
|
5
5
|
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :inode, :modified_at, :size, :inode_struct
|
7
7
|
|
8
8
|
def initialize(source)
|
9
|
-
@source = source
|
10
|
-
@identifier = nil
|
9
|
+
@source = source # Pathname
|
11
10
|
restat
|
12
11
|
end
|
13
12
|
|
14
|
-
def add_identifier(identifier) self; end
|
15
|
-
|
16
13
|
def restat
|
17
|
-
|
18
|
-
@inode =
|
19
|
-
@modified_at =
|
20
|
-
@size =
|
21
|
-
@
|
22
|
-
@dev_minor = @inner_stat.dev_minor
|
23
|
-
@inode_struct = InodeStruct.new(@inode, @dev_major, @dev_minor)
|
14
|
+
stat = @source.stat
|
15
|
+
@inode = stat.ino.to_s
|
16
|
+
@modified_at = stat.mtime.to_f
|
17
|
+
@size = stat.size
|
18
|
+
@inode_struct = InodeStruct.new(@inode, stat.dev_major, stat.dev_minor)
|
24
19
|
end
|
25
20
|
|
26
21
|
def windows?
|
@@ -28,7 +23,7 @@ module FileWatch module Stat
|
|
28
23
|
end
|
29
24
|
|
30
25
|
def inspect
|
31
|
-
"
|
26
|
+
"<#{self.class.name} size=#{@size}, modified_at=#{@modified_at}, inode='#{@inode}', inode_struct=#{@inode_struct}>"
|
32
27
|
end
|
33
28
|
end
|
34
29
|
end end
|