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 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
- raise Errno::EISDIR.new(@path)
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
- raise NotImplementedError.new("#{self.class.name}#receive_data is not "\
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.debug("notify: #{status} on #{path}")
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.debug("File not found: '#{@path}' (#{e})")
181
- raise e
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
- filestat = File.stat(@path)
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
 
@@ -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}#file_found is not "\
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
- - 20101204110840
10
- version: 0.5.20101204110840
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: 2010-12-04 00:00:00 -08:00
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"