4 Python-Tail - Unix tail follow implementation in Python.
6 python-tail can be used to monitor changes to a file.
11 # Create a tail instance
12 t = tail.Tail('file-to-be-followed')
14 # Register a callback function to be called when a new line is found in the followed file.
15 # If no callback function is registerd, new lines would be printed to standard out.
16 t.register_callback(callback_function)
18 # Follow the file with 5 seconds as sleep time between iterations.
19 # If sleep time is not provided 1 second is used as the default time.
22 # Author - Kasun Herath <kasunh01 at gmail.com>
23 # Source - https://github.com/kasun/python-tail
25 # modified by Hans-Christoph Steiner <hans@eds.org> to add the
26 # background thread and support reading multiple lines per read cycle
35 ''' Represents a tail command. '''
36 def __init__(self, tailed_file):
37 ''' Initiate a Tail instance.
38 Check for file validity, assigns callback function to standard out.
41 tailed_file - File to be followed. '''
43 self.check_file_validity(tailed_file)
44 self.tailed_file = tailed_file
45 self.callback = sys.stdout.write
46 self.t_stop = threading.Event()
49 '''Start tailing a file in a background thread.
52 s - Number of seconds to wait between each iteration; Defaults to 3.
55 t = threading.Thread(target=self.follow, args=(s,))
59 '''Stop a background tail.
63 def follow(self, s=1):
64 ''' Do a tail follow. If a callback function is registered it is called with every new line.
65 Else printed to standard out.
68 s - Number of seconds to wait between each iteration; Defaults to 1. '''
70 with open(self.tailed_file, encoding='utf8') as file_:
71 # Go to the end of file
73 while not self.t_stop.is_set():
74 curr_position = file_.tell()
75 lines = file_.readlines()
77 file_.seek(curr_position)
83 def register_callback(self, func):
84 ''' Overrides default callback function to provided function. '''
87 def check_file_validity(self, file_):
88 ''' Check whether the a given file exists, readable and is a file '''
89 if not os.access(file_, os.F_OK):
90 raise TailError("File '%s' does not exist" % (file_))
91 if not os.access(file_, os.R_OK):
92 raise TailError("File '%s' not readable" % (file_))
93 if os.path.isdir(file_):
94 raise TailError("File '%s' is a directory" % (file_))
97 class TailError(Exception):
99 def __init__(self, msg):