#!/usr/bin/python

# POE has a "FollowTail" wheel that works like tail -F --- if log
# rotation renames the file, creates a new one under the original
# name, and starts appending to it, it switches to watching the new
# file.

# This "followtail" module provides a way to do the same thing in
# Twisted Python.

from __future__ import nested_scopes
import twisted.internet.reactor, os, stat, sys

def file_identity(struct_stat):
    return struct_stat[stat.ST_DEV], struct_stat[stat.ST_INO]

def followtail(filename, callback, freq=1, fileobj=None, fstat=None):
    if fileobj is None:
        fileobj = open(filename)
        fileobj.seek(0, 2)
    callback(fileobj.read())
    if fstat is None: fstat = os.fstat(fileobj.fileno())
    try: stat = os.stat(filename)
    except: stat = fstat
    if file_identity(stat) != file_identity(fstat):
        fileobj = open(filename)
        fstat = os.fstat(fileobj.fileno())
        # don't do this on new files: fileobj.seek(0, 2)
    twisted.internet.reactor.callLater(freq, lambda:
                                       followtail(filename, callback, freq,
                                                  fileobj, fstat))

if __name__ == '__main__':
    followtail(sys.argv[1], sys.stdout.write)
    twisted.internet.reactor.run()

Reply via email to