How to detect log file rotation by looking for a changed inode number
I really like the simplicity of @olisch's answer: just detect when the log file is rotated by detecting when the inode number changes.
This works because if you are logging into ~/mylog.log
, log rotation will periodically rename this file to ~/mylog.log.1
, then to ~/mylog.log.2
, then to ~/mylog.log.3
, etc. Each time it does this sequential renaming of the files to perform log rotation, it will create a brand new file at ~/mylog.log
, which is the active log file, making the inode number of the file at that path change.
This polling-in-a-loop approach especially makes sense if you are already logging at a fixed time interval via a loop anyway!
So, here is a full demo (excluding the logging portion) to show how to detect a changed inode number of a log file at a given path:
import os
import pathlib
# Log into ~/mylog.log. Log rotation will periodically rename this file to
# ~/mylog.log.1, then ~/mylog.log.2, ~/mylog.log.3, etc. Each time it does this,
# it will create a brand new file at ~/mylog.log, making the inode number of
# the file at that path change.
log_file_path = os.path.join(pathlib.Path.home(), 'mylog.log')
# this is your main logging loop
inode_number_old = os.stat(log_file_path).st_ino
while True:
# Detect log rotation events
inode_number_new = os.stat(log_file_path).st_ino
if inode_number_old != inode_number_new:
print("Log file rotation just detected!")
inode_number_old = inode_number_new
# Now do whatever it is you want to do whenever a log rotation is
# detected. Ex: change the new log file's permissions to read/write
# for everyone.
PERMISSIONS_EVERYONE_READ_WRITE = 0o666
os.chmod(log_file_path, PERMISSIONS_EVERYONE_READ_WRITE)
I use the above technique in my cpu_logger.py program in my eRCaGuy_dotfiles repo. I use that logging script to continually log my CPU usage and detect which programs are taking all my CPU and locking up my computer.
Note that you can also read and verify the inode numbers of files at the command-line in Linux with:
ls -i
For an easier-to-look-at single-column output, use:
ls -i1
References
- @olisch's answer
- https://docs.python.org/3/library/os.html#os.stat_result.st_ino - official Python documentation
- Python logger file permissions
- My answer: Ask Ubuntu: How to log CPU load?