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