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

def initialize(opts={})
  if opts[:logger]
    @logger = opts[:logger]
  else
    @logger = Logger.new(STDERR)
    @logger.level = Logger::DEBUG
  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 \
    logger: @opts[:logger],
    ignore_before: @opts[:ignore_before]
  @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



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

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

#sincedb_write(reason = nil) ⇒ Object



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

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



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
114
# File 'lib/filewatch/tail.rb', line 75

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



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

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