eventmachine-tail 0.5.20101204110840 → 0.5.20110118081348
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.
- data/bin/emtail +83 -0
- data/lib/em/filetail.rb +18 -6
- data/lib/em/globwatcher.rb +1 -1
- metadata +5 -7
data/bin/emtail
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "rubygems"
|
3
|
+
require "eventmachine"
|
4
|
+
require "eventmachine-tail"
|
5
|
+
require "optparse"
|
6
|
+
|
7
|
+
class Reader < EventMachine::FileTail
|
8
|
+
def initialize(path, startpos=-1, with_filenames=true)
|
9
|
+
super(path, startpos)
|
10
|
+
@buffer = BufferedTokenizer.new
|
11
|
+
@with_filenames = with_filenames
|
12
|
+
end
|
13
|
+
|
14
|
+
def receive_data(data)
|
15
|
+
@buffer.extract(data).each do |line|
|
16
|
+
if @with_filenames # global flag, see the '-n' option
|
17
|
+
puts "#{path}: #{line}"
|
18
|
+
else
|
19
|
+
puts line
|
20
|
+
end # if @with_filenames
|
21
|
+
end # buffer extract
|
22
|
+
end # def receive_data
|
23
|
+
end # class Reader
|
24
|
+
|
25
|
+
def pattern_to_regexp(pattern)
|
26
|
+
pattern.gsub!(".", "\\.") # fix literal .
|
27
|
+
pattern.gsub!("*", ".+") # * becomes .+
|
28
|
+
pattern.gsub!("?", ".") # ? becomes .
|
29
|
+
return Regexp.new(pattern)
|
30
|
+
end # def pattern_to_regexp
|
31
|
+
|
32
|
+
def main(args)
|
33
|
+
with_filenames = true
|
34
|
+
globcheck_interval = 5
|
35
|
+
exclude_patterns = []
|
36
|
+
|
37
|
+
opts = OptionParser.new do |opts|
|
38
|
+
opts.banner = "Usage: #{$0} [options] <path_or_glob> [path_or_glob2] [...]"
|
39
|
+
|
40
|
+
opts.on("-n", "--no-filename",
|
41
|
+
"Supress prefixing of output with file names") do |x|
|
42
|
+
with_filenames = false
|
43
|
+
end # -n
|
44
|
+
|
45
|
+
opts.on("-i SECONDS", "--check-interval SECONDS",
|
46
|
+
"How frequently, in seconds, to check the glob patterns" \
|
47
|
+
"for new files") do |x|
|
48
|
+
globcheck_interval = x.to_f
|
49
|
+
end # -i SECONDS
|
50
|
+
|
51
|
+
opts.on("-x EXCLUDE", "--exclude EXCLUDE",
|
52
|
+
"A pattern to ignore. Wildcard/globs accepted." \
|
53
|
+
" Can be specified multiple times") do |pattern|
|
54
|
+
exclude_patterns << pattern_to_regexp(pattern)
|
55
|
+
end
|
56
|
+
end # OptionParser
|
57
|
+
|
58
|
+
opts.parse!(args)
|
59
|
+
|
60
|
+
if args.length == 0
|
61
|
+
puts opts.banner
|
62
|
+
return 1
|
63
|
+
end
|
64
|
+
|
65
|
+
EventMachine.run do
|
66
|
+
Signal.trap("INT") do
|
67
|
+
EventMachine.schedule do
|
68
|
+
$stderr.puts "Got SIGINT"
|
69
|
+
exit 128 + (Signal.list["INT"])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
args.each do |path|
|
74
|
+
EventMachine::FileGlobWatchTail.new(path, Reader,
|
75
|
+
interval = globcheck_interval,
|
76
|
+
exclude = exclude_patterns,
|
77
|
+
start_pos = -1,
|
78
|
+
with_filenames = with_filenames)
|
79
|
+
end # args.each
|
80
|
+
end # EventMachine.run
|
81
|
+
end # def main
|
82
|
+
|
83
|
+
exit(main(ARGV))
|
data/lib/em/filetail.rb
CHANGED
@@ -85,7 +85,7 @@ class EventMachine::FileTail
|
|
85
85
|
read_file_metadata
|
86
86
|
|
87
87
|
if @filestat.directory?
|
88
|
-
|
88
|
+
on_exception Errno::EISDIR.new(@path)
|
89
89
|
end
|
90
90
|
|
91
91
|
if block_given?
|
@@ -133,12 +133,17 @@ class EventMachine::FileTail
|
|
133
133
|
@handler.call(self, line)
|
134
134
|
end
|
135
135
|
else
|
136
|
-
|
136
|
+
on_exception NotImplementedError.new("#{self.class.name}#receive_data is not "\
|
137
137
|
"implemented. Did you forget to implement this in your subclass or "\
|
138
138
|
"module?")
|
139
139
|
end
|
140
140
|
end # def receive_data
|
141
141
|
|
142
|
+
def on_exception(exception)
|
143
|
+
@logger.error("Exception raised. Using default handler in #{self.class.name}")
|
144
|
+
raise exception
|
145
|
+
end
|
146
|
+
|
142
147
|
# This method is called when a tailed file reaches EOF.
|
143
148
|
#
|
144
149
|
# If you want to stop reading this file, call close(), otherwise
|
@@ -146,6 +151,7 @@ class EventMachine::FileTail
|
|
146
151
|
# EOF handler is to do nothing.
|
147
152
|
public
|
148
153
|
def eof
|
154
|
+
puts "EOF"
|
149
155
|
# do nothing, subclassers should implement this.
|
150
156
|
end # def eof
|
151
157
|
|
@@ -153,7 +159,7 @@ class EventMachine::FileTail
|
|
153
159
|
# modified or otherwise needs to be acted on.
|
154
160
|
private
|
155
161
|
def notify(status)
|
156
|
-
@logger.
|
162
|
+
@logger.warn("notify: #{status} on #{path}")
|
157
163
|
if status == :modified
|
158
164
|
schedule_next_read
|
159
165
|
elsif status == :moved
|
@@ -177,11 +183,12 @@ class EventMachine::FileTail
|
|
177
183
|
@logger.debug "Opening file #{@path}"
|
178
184
|
@file = File.open(@path, "r")
|
179
185
|
rescue Errno::ENOENT => e
|
180
|
-
@logger.
|
181
|
-
|
186
|
+
@logger.info("File not found: '#{@path}' (#{e})")
|
187
|
+
on_exception(e)
|
182
188
|
end
|
183
189
|
|
184
190
|
@naptime = 0
|
191
|
+
puts "EOF"
|
185
192
|
@position = 0
|
186
193
|
schedule_next_read
|
187
194
|
end # def open
|
@@ -320,7 +327,12 @@ class EventMachine::FileTail
|
|
320
327
|
|
321
328
|
private
|
322
329
|
def read_file_metadata(&block)
|
323
|
-
|
330
|
+
begin
|
331
|
+
filestat = File.stat(@path)
|
332
|
+
rescue => e
|
333
|
+
@logger.debug("File stat on '#{@path}' failed")
|
334
|
+
on_exception e
|
335
|
+
end
|
324
336
|
symlink_stat = nil
|
325
337
|
symlink_target = nil
|
326
338
|
|
data/lib/em/globwatcher.rb
CHANGED
@@ -75,7 +75,7 @@ class EventMachine::FileGlobWatch
|
|
75
75
|
# to work with EventMachine::watch_glob
|
76
76
|
public
|
77
77
|
def file_deleted(path)
|
78
|
-
raise NotImplementedError.new("#{self.class.name}#
|
78
|
+
raise NotImplementedError.new("#{self.class.name}#file_deleted is not "\
|
79
79
|
"implemented. Did you forget to implement this in your subclass or "\
|
80
80
|
"module?")
|
81
81
|
end # def file_found
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eventmachine-tail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 40202408221691
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
7
|
- 5
|
9
|
-
-
|
10
|
-
version: 0.5.
|
8
|
+
- 20110118081348
|
9
|
+
version: 0.5.20110118081348
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Jordan Sissel
|
@@ -15,7 +14,7 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date:
|
17
|
+
date: 2011-01-18 00:00:00 -08:00
|
19
18
|
default_executable:
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
@@ -26,7 +25,6 @@ dependencies:
|
|
26
25
|
requirements:
|
27
26
|
- - ">="
|
28
27
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 3
|
30
28
|
segments:
|
31
29
|
- 0
|
32
30
|
version: "0"
|
@@ -36,6 +34,7 @@ description: Add file 'tail' implemented with EventMachine. Also includes a 'glo
|
|
36
34
|
email: jls@semicomplete.com
|
37
35
|
executables:
|
38
36
|
- rtail
|
37
|
+
- emtail
|
39
38
|
extensions: []
|
40
39
|
|
41
40
|
extra_rdoc_files: []
|
@@ -54,6 +53,7 @@ files:
|
|
54
53
|
- test/alltests.rb
|
55
54
|
- test/testcase_helpers.rb
|
56
55
|
- bin/rtail
|
56
|
+
- bin/emtail
|
57
57
|
has_rdoc: true
|
58
58
|
homepage: http://code.google.com/p/semicomplete/wiki/EventMachineTail
|
59
59
|
licenses: []
|
@@ -69,7 +69,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
69
69
|
requirements:
|
70
70
|
- - ">="
|
71
71
|
- !ruby/object:Gem::Version
|
72
|
-
hash: 3
|
73
72
|
segments:
|
74
73
|
- 0
|
75
74
|
version: "0"
|
@@ -78,7 +77,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
77
|
requirements:
|
79
78
|
- - ">="
|
80
79
|
- !ruby/object:Gem::Version
|
81
|
-
hash: 3
|
82
80
|
segments:
|
83
81
|
- 0
|
84
82
|
version: "0"
|