I use the following code to track ssh log-ins:
def follow(thefile):
thefile.seek(0,2)
while True:
line = thefile.readline()
if not line:
time.sleep(0.1)
continue
yield line
if __name__ == '__main__':
logfile = open('/var/log/auth.log', 'r')
loglines = follow(logfile)
for line in loglines:
print 'do something here'
I've noticed that this script suddenly stops working after a couple of days. I don't get any error, it doesn't terminate, it just stops working, as if readline()
would never return.
So I executed a echo 'test' >> auth.log.1
and this indeed ends up getting processed by the script, because sometime ago auth.log
got renamed to auth.log.1
How can I track when such a log rotation happens and adjust accordingly?
you can have a look at the inode, of the file.
When the inode changes, the file has been rotated.
Apparently, I can't comment until I have >= 50 reputation.
@daniel-f has a GREAT example! Only edge case I ran into is that, when the service creating the rotating log files I am reading restarts, it deletes the old files and creates new ones.
This causes the 'notifier' to lose visibility into the log file (since it is different).
Since the service writes to the log file every 60 seconds, I did a quick modification to the for loop, shown below:
This re-watches the file after 75 seconds without an update.
Using e4c5's answer I ended up with this code, which also solves the issue of calling
readline()
multiple times per second.During the first invocation it skips to the end of the file and waits for modifications. When the file is moved, it reopens the file and reads the entire content, then starts to wait.
This is best done with inotify you don't want to keep polling the file system to ask if things have changed during each iteration of the loop. That's a lot of wasted IO.
inotify
will notify you when a change occurs. There is an example right from the manual which shows it's usage with log file.