Class: FileWatch::Tail

Inherits:
Object
  • Object
show all
Defined in:
lib/filewatch/tail.rb

Defined Under Namespace

Classes: NoSinceDBPathGiven

Constant Summary collapse

OPEN_WARN_INTERVAL =

how often (in seconds) we @logger.warn a failed file open, per path.

ENV["FILEWATCH_OPEN_WARN_INTERVAL"] ?
ENV["FILEWATCH_OPEN_WARN_INTERVAL"].to_i : 300

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Tail

Returns a new instance of Tail.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/filewatch/tail.rb', line 24

def initialize(opts={})
  @iswindows = ((RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/) != nil)

  if opts[:logger]
    @logger = opts[:logger]
  else
    @logger = Logger.new(STDERR)
    @logger.level = Logger::INFO
  end
  @files = {}
  @lastwarn = Hash.new { |h, k| h[k] = 0 }
  @buffers = {}
  @watch = FileWatch::Watch.new
  @watch.logger = @logger
  @sincedb = {}
  @sincedb_last_write = 0
  @statcache = {}
  @opts = {
    :sincedb_write_interval => 10,
    :stat_interval => 1,
    :discover_interval => 5,
    :exclude => [],
    :start_new_files_at => :end,
    :delimiter => "\n"
  }.merge(opts)
  if !@opts.include?(:sincedb_path)
    @opts[:sincedb_path] = File.join(ENV["HOME"], ".sincedb") if ENV.include?("HOME")
    @opts[:sincedb_path] = ENV["SINCEDB_PATH"] if ENV.include?("SINCEDB_PATH")
  end
  if !@opts.include?(:sincedb_path)
    raise NoSinceDBPathGiven.new("No HOME or SINCEDB_PATH set in environment. I need one of these set so I can keep track of the files I am following.")
  end
  @watch.exclude(@opts[:exclude])

  _sincedb_open
end

Instance Attribute Details

#loggerObject

Returns the value of attribute logger.



19
20
21
# File 'lib/filewatch/tail.rb', line 19

def logger
  @logger
end

Instance Method Details

#quitObject



241
242
243
244
# File 'lib/filewatch/tail.rb', line 241

def quit
  _sincedb_write
  @watch.quit
end

#sincedb_record_uid(path, stat) ⇒ Object



111
112
113
114
115
# File 'lib/filewatch/tail.rb', line 111

def sincedb_record_uid(path, stat)
  inode = @watch.inode(path,stat)
  @statcache[path] = inode
  return inode
end

#sincedb_write(reason = nil) ⇒ Object



204
205
206
207
# File 'lib/filewatch/tail.rb', line 204

def sincedb_write(reason=nil)
  @logger.debug? && @logger.debug("caller requested sincedb write (#{reason})")
  _sincedb_write
end

#subscribe(&block) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/filewatch/tail.rb', line 73

def subscribe(&block)
  # subscribe(stat_interval = 1, discover_interval = 5, &block)
  @watch.subscribe(@opts[:stat_interval],
                   @opts[:discover_interval]) do |event, path|
    case event
    when :create, :create_initial
      if @files.member?(path)
        @logger.debug? && @logger.debug("#{event} for #{path}: already exists in @files")
        next
      end
      if _open_file(path, event)
        _read_file(path, &block)
      end
    when :modify
      if !@files.member?(path)
        @logger.debug? && @logger.debug(":modify for #{path}, does not exist in @files")
        if _open_file(path, event)
          _read_file(path, &block)
        end
      else
        _read_file(path, &block)
      end
    when :delete
      @logger.debug? && @logger.debug(":delete for #{path}, deleted from @files")
      if @files[path]
        _read_file(path, &block)
        @files[path].close
      end
      @files.delete(path)
      inode = @statcache.delete(path)
      @sincedb.delete(inode)
    else
      @logger.warn("unknown event type #{event} for #{path}")
    end
  end # @watch.subscribe
end

#tail(path) ⇒ Object



68
69
70
# File 'lib/filewatch/tail.rb', line 68

def tail(path)
  @watch.watch(path)
end