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 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"