eventmachine-tail 0.5.20101204110840 → 0.5.20110118081348
Sign up to get free protection for your applications and to get access to all the features.
- 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"
|