python: read file continuously, even after it has been logrotated

前端 未结 3 2054
青春惊慌失措
青春惊慌失措 2021-02-03 13:28

I have a simple python script, where I read logfile continuosly (same as tail -f)

while True:
    line = f.readline()
    if line:
        print lin         


        
3条回答
  •  时光说笑
    2021-02-03 14:07

    Thanks to @tdelaney and @Dolda2000's answers, I ended up with what follows. It should work on both Linux and Windows, and also handle logrotate's copytruncate or create options (respectively copy then truncate size to 0 and move then recreate 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)
    

    A limitation when using copytruncate option is that if lines are appended to the file while time-sleeping, and rotation occurs before wake-up, the last lines will be "lost" (they will still be in the now "old" log file, but I cannot see a decent way to "follow" that file to finish reading it). This limitation is not relevant with "move and create" create option because f descriptor will still point to the renamed file and therefore last lines will be read before the descriptor is closed and opened again.

提交回复
热议问题