我使用以下代码来跟踪ssh登录:
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'
我注意到这个脚本在几天后突然停止工作,我没有收到任何错误,它没有终止,它只是停止工作,好像readline()
永远不会返回。
因此,我执行了一个echo 'test' >> auth.log.1
,脚本最终确实处理了它,因为不久前auth.log
被重命名为auth.log.1
如何跟踪此类日志循环发生的时间并进行相应调整?
5条答案
按热度按时间oknrviil1#
使用e4c5的答案,我最终得到了这段代码,它还解决了每秒多次调用
readline()
的问题。在第一次调用时,它会跳到文件末尾并等待修改,当文件被移动时,它会重新打开文件并读取整个内容,然后开始等待。
ru9i0ody2#
最好用inotify来完成,你不想在循环的每次迭代中不断轮询文件系统来询问是否发生了变化。这会浪费很多IO。
inotify
会在发生变化时 * 通知 * 你。手册中有一个例子显示了它与日志文件的用法。yrwegjxp3#
您可以查看文件的inode。
当inode更改时,文件已旋转。
2lpgd9684#
显然,我不能发表评论,直到我有〉= 50的声誉。
@daniel-f有一个很好的例子!我遇到的唯一一个边缘案例是,当创建我正在阅读的旋转日志文件的服务重新启动时,它会删除旧文件并创建新文件。
这将导致“通知程序”无法看到日志文件(因为它是不同的)。
由于服务每60秒写入一次日志文件,因此我对for循环进行了快速修改,如下所示:
这将在75秒后重新监视文件,而不进行更新。
sh7euo9m5#
如何通过查找更改的inode编号来检测日志文件轮换
我真的很喜欢@olisch回答的简洁:通过检测索引节点号何时改变来检测日志文件何时被轮转。
这是因为,如果您登录到
~/mylog.log
,则日志轮转会定期将此文件重命名为~/mylog.log.1
,然后重命名为~/mylog.log.2
,最后重命名为~/mylog.log.3
,依此类推。每次执行此顺序的文件重命名以执行日志轮转时,它都会在~/mylog.log
(活动日志文件)处创建一个全新的文件,从而使该路径处的文件的索引节点号改变。如果您已经通过循环以固定的时间间隔记录日志,这种循环中轮询的方法尤其有意义!
下面是一个完整的演示(不包括日志记录部分),展示了如何检测给定路径下日志文件的inode编号是否发生了更改:
我在我的eRCaGuy_dotfiles repo的cpu_logger.py程序中使用了上述技术,我使用该日志脚本不断地记录我的CPU使用情况,并检测哪些程序占用了我所有的CPU并锁定了我的计算机。
请注意,您还可以在Linux中的命令行中使用以下命令读取和验证文件的inode编号:
要获得更易于查看的单列输出,请用途:
参考文献
1.@olisch的回答
1.我的答案:Ask Ubuntu: How to log CPU load?