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.



20
21
22
23
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
60
# File 'lib/filewatch/tail.rb', line 20

def initialize(opts={})
  if opts[:logger]
    @logger = opts[:logger]
  else
    @logger = Logger.new(STDERR)
    @logger.level = Logger::INFO
  end
  @evict = nil
  @files = {}
  @locked = Hash.new { |h, k| h[k] = false }
  @changed = Hash.new { |h, k| h[k] = 0 }
  @lastwarn = Hash.new { |h, k| h[k] = 0 }
  @buffers = {}
  @sincedb = {}
  @sincedb_last_write = Time.now.to_i
  @sincedb_write_pending = false
  @sincedb_writing = false
  @statcache = {}
  @opts = {
    :ignore_before => 0, # Ignore files last modified before this timestamp
    :eviction_interval => 300, # Let go of file handles after five minutes
    :sincedb_write_interval => 10,
    :stat_interval => 1,
    :discover_interval => 5,
    :exclude => [],
    :start_new_files_at => :end,
    :follow_only_path => false
  }.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 = FileWatch::Watch.new ignore_before: @opts[:ignore_before]
  @watch.logger = @logger
  @watch.exclude(@opts[:exclude])
  _start_eviction
  _sincedb_open
end

Instance Attribute Details

#loggerObject

Returns the value of attribute logger.



15
16
17
# File 'lib/filewatch/tail.rb', line 15

def logger
  @logger
end

Instance Method Details

#quitObject



308
309
310
311
# File 'lib/filewatch/tail.rb', line 308

def quit
  @evict && @evict.kill
  @watch.quit
end

#sincedb_write(reason = nil) ⇒ Object



213
214
215
216
# File 'lib/filewatch/tail.rb', line 213

def sincedb_write(reason=nil)
  @logger.debug("caller requested sincedb write (#{reason})")
  _sincedb_write(true)  # since this is an external request, force the write
end

#subscribe(&block) ⇒ Object



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
109
110
111
112
113
# File 'lib/filewatch/tail.rb', line 74

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[path].nil?
        @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[path].nil?
        @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(":delete for #{path}, deleted from @files")
      # if File::exist?(path) # Rotated
      #   if @files[path].nil?
      #     _open_file(path, event)
      #   end
      #   _read_file(path, &block)
      # end
      @files.delete(path).close rescue nil
      @statcache.delete(path)
    when :noupdate
      # @logger.debug(":noupdate for #{path}, from @files")
      _sincedb_write_if_pending   # will check to see if sincedb_write requests are pending 
    else
      @logger.warn("unknown event type #{event} for #{path}")
    end
  end # @watch.subscribe
end

#tail(path) ⇒ Object



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

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