Thanks to the answers of @tdelaney and @ Dolda2000, I ended up with what follows. It should work with both Linux and Windows, as well as handle the parameters logrotate copytruncate or create (respectively copy, crop the size to 0 and move and then recreate the file).
file_name = 'my_log_file' seek_end = True while True: # handle moved/truncated files by allowing to reopen with open(file_name) as f: if seek_end: # reopened files must not seek end f.seek(0, 2) while True: # line reading loop line = f.readline() if not line: try: if f.tell() > os.path.getsize(file_name): # rotation occurred (copytruncate/create) f.close() seek_end = False break except FileNotFoundError: # rotation occurred but new file still not created pass # wait 1 second and retry time.sleep(1) do_stuff_with(line)
The limitation when using the copytruncate parameter is that if lines are attached to the file during sleep mode, and rotation occurs before , the last lines will be "lost" (they will still be in the "old" log file, but I donβt see a decent the way to "follow" this file to finish reading it). This restriction is not related to the "move and create" create option, because the descriptor f will still point to the renamed file, and therefore the last lines will be read before the descriptor is closed and reopened.
source share