file-tail 0.1.4 → 1.0.0

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/CHANGES CHANGED
@@ -1,3 +1,13 @@
1
+ 2007-03-30 * 1.0.0 * Bugfix: David.Barzilay@swisscom.com reported, that file
2
+ tails may skip some log file lines, after rotating it. I
3
+ think, І fixed that problem.
4
+ I added a after_reopen callback as well, that is called
5
+ after reopening of the tailed file has occured.
6
+ * Removed rewind/wind methods even earlier than planned: I
7
+ placed the deprecation warning for rewind method in File
8
+ instead of File::Tail, which caused rewind to stop working
9
+ completely after loading file/tail. Duh! I blame vim's
10
+ matchit, because it jumped to the wrong end keyword.
1
11
  2007-02-08 * 0.1.4 * Renamed rewind method to backward, and wind method to
2
12
  forward, because someone already had the good idea to name
3
13
  a method IO#rewind, which was overwritten by the mixed in
data/Rakefile CHANGED
@@ -36,45 +36,19 @@ task :clean do
36
36
  end
37
37
 
38
38
  spec = Gem::Specification.new do |s|
39
-
40
- #### Basic information.
41
-
42
39
  s.name = 'file-tail'
43
40
  s.version = PKG_VERSION
44
41
  s.summary = "File::Tail for Ruby"
45
42
  s.description = "Library to tail files in Ruby"
46
43
 
47
- #### Dependencies and requirements.
48
-
49
- #s.add_dependency('log4r', '> 1.0.4')
50
- #s.requirements << ""
51
-
52
44
  s.files = PKG_FILES
53
45
 
54
- #### C code extensions.
55
-
56
- #s.extensions << "ext/extconf.rb"
57
-
58
- #### Load-time details: library and application (you will need one or both).
59
-
60
- s.require_path = 'lib' # Use these for libraries.
61
- #s.autorequire = 'file/tail'
62
-
63
- #s.bindir = "bin" # Use these for applications.
64
- #s.executables = ["bla.rb"]
65
- #s.default_executable = "bla.rb"
66
-
67
- #### Documentation and testing.
46
+ s.require_path = 'lib'
68
47
 
69
48
  s.has_rdoc = true
70
- #s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a
71
- s.rdoc_options <<
72
- '--title' << 'File::Tail' <<
73
- # '--line-numbers'
49
+ s.rdoc_options << '--title' << 'File::Tail' << '--line-numbers'
74
50
  s.test_files << 'tests/test_file-tail.rb'
75
51
 
76
- #### Author and project details.
77
-
78
52
  s.author = "Florian Frank"
79
53
  s.email = "flori@ping.de"
80
54
  s.homepage = "http://file-tail.rubyforge.org"
@@ -86,4 +60,23 @@ Rake::GemPackageTask.new(spec) do |pkg|
86
60
  pkg.package_files += PKG_FILES
87
61
  end
88
62
 
63
+ desc m = "Writing version information for #{PKG_VERSION}"
64
+ task :version do
65
+ puts m
66
+ File.open(File.join('lib', 'file', 'tail', 'version.rb'), 'w') do |v|
67
+ v.puts <<EOT
68
+ class File
69
+ module Tail
70
+ # File::Tail version
71
+ VERSION = '#{PKG_VERSION}'
72
+ VERSION_ARRAY = VERSION.split(/\\./).map { |x| x.to_i } # :nodoc:
73
+ VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
74
+ VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
75
+ VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
76
+ end
77
+ end
78
+ EOT
79
+ end
80
+ end
81
+
89
82
  task :release => [ :clean, :package ]
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.4
1
+ 1.0.0
data/install.rb CHANGED
@@ -8,12 +8,15 @@ include Config
8
8
 
9
9
  cd 'lib' do
10
10
  libdir = CONFIG["sitelibdir"]
11
- subdir = 'file'
12
- filename = 'tail.rb'
13
11
 
14
- dest = File.join(libdir, subdir)
12
+ dest = File.join(libdir, 'file')
15
13
  mkdir_p(dest)
16
- file = File.join('file', filename)
14
+ file = File.join('file', 'tail.rb')
15
+ install(file, dest)
16
+
17
+ dest = File.join(dest, 'tail')
18
+ mkdir_p(dest)
19
+ file = File.join('file', 'tail', 'version.rb')
17
20
  install(file, dest)
18
21
  end
19
22
  # vim: set et sw=2 ts=2:
data/lib/file/tail.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  #
2
+ require 'file/tail/version'
2
3
  # = File::Tail - Tailing files in Ruby
3
4
  #
4
5
  # == Description
@@ -92,8 +93,11 @@ class File
92
93
  # in the logfile for 10 lines at the start. The buffersize
93
94
  # for going backwards can be set with the
94
95
  # * <code>:bufsiz => 8192</code> option.
95
- # Every attribute of File::Tail can be set with a
96
- # <code>:attributename => value</code> option.
96
+ # To define a callback, that will be called after a reopening occurs, use:
97
+ # * <code>:after_reopen => lambda { |file| p file }</code>
98
+ #
99
+ # Every attribute of File::Tail can be set with a <code>:attributename =>
100
+ # value</code> option.
97
101
  def self.open(filename, opts = {}) # :yields: file
98
102
  file = new filename
99
103
  opts.each do |o, v|
@@ -111,6 +115,9 @@ class File
111
115
  elsif forward = opts[:forward] || opts[:wind]
112
116
  file.forward(forward)
113
117
  end
118
+ if opts[:after_reopen]
119
+ file.after_reopen &opts[:after_reopen]
120
+ end
114
121
  if block_given?
115
122
  yield file
116
123
  nil
@@ -187,6 +194,13 @@ class File
187
194
  # <code>suspicious_interval</code> seconds of silence.
188
195
  attr_accessor :reopen_suspicious
189
196
 
197
+ # The callback is called with _self_ as an argument after a reopen has
198
+ # occured. This allows a tailing script to find out, if a logfile has been
199
+ # rotated.
200
+ def after_reopen(&block)
201
+ @after_reopen = block
202
+ end
203
+
190
204
  # This attribute is the invterval in seconds before File::Tail
191
205
  # gets suspicious that something has happend to it's tailed file
192
206
  # and an attempt to reopen it is made.
@@ -215,12 +229,6 @@ class File
215
229
  self
216
230
  end
217
231
 
218
- # The wind method is deprecated, use forward instead.
219
- def wind(*args)
220
- warn "File::Tail#wind method is deprecated, use forward instead"
221
- forward *args
222
- end
223
-
224
232
  # Rewind the last <code>n</code> lines of this file, starting
225
233
  # from the end. The default is to start tailing directly from the
226
234
  # end of the file.
@@ -279,6 +287,7 @@ class File
279
287
  # call doesn't return, but yields to block for every new line read from
280
288
  # this file for ever.
281
289
  def tail(n = nil, &block) # :yields: line
290
+ @n = n
282
291
  result = []
283
292
  array_result = false
284
293
  unless block
@@ -289,10 +298,15 @@ class File
289
298
  loop do
290
299
  begin
291
300
  restat
292
- read_line(n, &block)
301
+ read_line(&block)
293
302
  redo
294
303
  rescue ReopenException => e
304
+ until eof? || @n == 0
305
+ block.call readline
306
+ @n -= 1 if @n
307
+ end
295
308
  reopen_file(e.mode)
309
+ @after_reopen.call self if @after_reopen
296
310
  rescue ReturnException
297
311
  return array_result ? result : nil
298
312
  end
@@ -301,12 +315,13 @@ class File
301
315
 
302
316
  private
303
317
 
304
- def read_line(n)
305
- if n
306
- n.times do
318
+ def read_line
319
+ if @n
320
+ until @n == 0
307
321
  yield readline
308
322
  @lines += 1
309
323
  @no_read = 0
324
+ @n -= 1
310
325
  debug
311
326
  end
312
327
  raise ReturnException
@@ -323,8 +338,7 @@ class File
323
338
  raise BreakException if @break_if_eof
324
339
  raise ReturnException if @return_if_eof
325
340
  sleep_interval
326
- rescue Errno::ENOENT
327
- rescue Errno::ESTALE
341
+ rescue Errno::ENOENT, Errno::ESTALE
328
342
  raise ReopenException
329
343
  end
330
344
 
@@ -354,8 +368,7 @@ class File
354
368
  else
355
369
  @stat = stat
356
370
  end
357
- rescue Errno::ENOENT
358
- rescue Errno::ESTALE
371
+ rescue Errno::ENOENT, Errno::ESTALE
359
372
  raise ReopenException
360
373
  end
361
374
 
@@ -384,8 +397,7 @@ class File
384
397
  if mode == :bottom
385
398
  backward
386
399
  end
387
- rescue Errno::ESTALE
388
- rescue Errno::ENOENT
400
+ rescue Errno::ESTALE, Errno::ENOENT
389
401
  if @reopen_deleted
390
402
  sleep @max_interval
391
403
  retry
@@ -400,20 +412,11 @@ class File
400
412
  :lines => @lines,
401
413
  :interval => @interval,
402
414
  :no_read => @no_read,
415
+ :n => @n,
403
416
  }
404
417
  $stderr.print h.inspect, "\n"
405
418
  end
406
419
  end
407
-
408
- # The rewind method is deprecated and will be removed soon, use backward
409
- # instead. At the moment rewind accidentially overwrites the IO#rewind
410
- # method, after the removal of the ol rewind mixin method, this will be no
411
- # longer the case.
412
- def rewind(*args)
413
- warn "File::Tail#rewind method is deprecated and will be removed soon, "\
414
- "use backward instead"
415
- backward *args
416
- end
417
420
  end
418
421
 
419
422
  if $0 == __FILE__
@@ -0,0 +1,10 @@
1
+ class File
2
+ module Tail
3
+ # File::Tail version
4
+ VERSION = '0.1.5'
5
+ VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
6
+ VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
7
+ VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
8
+ VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
9
+ end
10
+ end
@@ -176,6 +176,8 @@ class TC_FileTail < Test::Unit::TestCase
176
176
  def test_tail_remove
177
177
  return if File::PATH_SEPARATOR == ';' # Grmpf! Windows...
178
178
  @in.backward
179
+ reopened = false
180
+ @in.after_reopen { |f| reopened = true }
179
181
  lines = []
180
182
  threads = []
181
183
  threads << appender = Thread.new do
@@ -198,6 +200,77 @@ class TC_FileTail < Test::Unit::TestCase
198
200
  end
199
201
  threads.collect { |t| t.wakeup and t.join }
200
202
  assert_equal(10, lines.size)
203
+ assert reopened
204
+ end
205
+
206
+ def test_tail_remove2
207
+ return if File::PATH_SEPARATOR == ';' # Grmpf! Windows...
208
+ @in.backward
209
+ reopened = false
210
+ @in.after_reopen { |f| reopened = true }
211
+ lines = []
212
+ threads = []
213
+ threads << appender = Thread.new do
214
+ Thread.stop
215
+ @out.close
216
+ File.unlink(@out.path)
217
+ @out = File.new(@in.path, "wb")
218
+ append(@out, 10)
219
+ sleep 1
220
+ append(@out, 10)
221
+ File.unlink(@out.path)
222
+ @out = File.new(@in.path, "wb")
223
+ append(@out, 10)
224
+ end
225
+ threads << Thread.new do
226
+ begin
227
+ timeout(2) do
228
+ @in.tail do |l|
229
+ lines << l
230
+ lines.size == 100 and appender.wakeup
231
+ end
232
+ end
233
+ rescue TimeoutError
234
+ end
235
+ end
236
+ threads.collect { |t| t.wakeup and t.join }
237
+ assert_equal(30, lines.size)
238
+ assert reopened
239
+ end
240
+
241
+ def test_tail_remove3
242
+ return if File::PATH_SEPARATOR == ';' # Grmpf! Windows...
243
+ @in.backward
244
+ reopened = false
245
+ @in.after_reopen { |f| reopened = true }
246
+ lines = []
247
+ threads = []
248
+ threads << appender = Thread.new do
249
+ Thread.stop
250
+ @out.close
251
+ File.unlink(@out.path)
252
+ @out = File.new(@in.path, "wb")
253
+ append(@out, 10)
254
+ sleep 1
255
+ append(@out, 10)
256
+ File.unlink(@out.path)
257
+ @out = File.new(@in.path, "wb")
258
+ append(@out, 10)
259
+ end
260
+ threads << Thread.new do
261
+ begin
262
+ timeout(2) do
263
+ @in.tail(15) do |l|
264
+ lines << l
265
+ lines.size == 100 and appender.wakeup
266
+ end
267
+ end
268
+ rescue TimeoutError
269
+ end
270
+ end
271
+ threads.collect { |t| t.wakeup and t.join }
272
+ assert_equal(15, lines.size)
273
+ assert reopened
201
274
  end
202
275
 
203
276
  def teardown
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.11
2
+ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: file-tail
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.4
7
- date: 2007-02-08 00:00:00 +01:00
6
+ version: 1.0.0
7
+ date: 2007-04-01 00:00:00 +02:00
8
8
  summary: File::Tail for Ruby
9
9
  require_paths:
10
10
  - lib
@@ -25,6 +25,7 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
25
25
  platform: ruby
26
26
  signing_key:
27
27
  cert_chain:
28
+ post_install_message:
28
29
  authors:
29
30
  - Florian Frank
30
31
  files:
@@ -41,14 +42,15 @@ files:
41
42
  - examples/pager.rb
42
43
  - examples/tail.rb
43
44
  - lib/file
45
+ - lib/file/tail
44
46
  - lib/file/tail.rb
45
- test_files: &id001 []
46
-
47
+ - lib/file/tail/version.rb
48
+ test_files:
49
+ - tests/test_file-tail.rb
47
50
  rdoc_options:
48
51
  - --title
49
52
  - File::Tail
50
- - *id001
51
- - tests/test_file-tail.rb
53
+ - --line-numbers
52
54
  extra_rdoc_files: []
53
55
 
54
56
  executables: []