如何在Python脚本执行期间检测文本文件的变化?

4 投票
2 回答
1928 浏览
提问于 2025-04-17 04:10

我正在处理一个有点不稳定的网页应用,具体名字就不说了。这个应用偶尔会出现问题,每当出现问题时,它会把错误信息和堆栈跟踪写入一个叫做 exception.log 的文件。为了及时了解这些问题,我写了一个Python脚本,定期扫描这个日志文件(感谢cron这个工具)。如果 exception.log 的大小大于零,脚本就会把文件内容发到我的邮箱,然后把这些内容移动到 exception_archive.log。我现在的做法是先读取文件,必要时发送邮件并写入异常归档,如果这两个步骤都成功了,我就会

target = open(target_log, 'w')
target.close()

删除原始日志。不过,由于我无法预测系统何时会写入 exception.log,在脚本的某个环节我可能会丢失数据——系统可能在我读取完现有数据并决定覆盖文件后再写入一些内容。此外,我从痛苦的经历中学到,如果 exception.log 不存在,这个不稳定的网页应用不会重新创建它——它只会把异常数据丢掉。所以,简单的“重命名并重新创建日志文件”的解决方案只会把问题推到更深的层次。

所以,问题的核心是:我该如何在一个文本文件和另一个文本文件之间转移、移动或读写数据,以确保在我的脚本执行时,如果有新数据写入文件,丢失数据的可能性为零或尽量减少? 我怀疑这是一个难题,或者是一个已经解决的问题,但我还没听说过解决方案。我也无法扩展这个应用——管理层对修改它非常怀疑,而且它也不是用Python写的,所以我得从头开始。

补充背景:

[me@server ~]$ uname -a
Linux server.example.com 2.6.9-101.ELsmp
#1 SMP Thu Jul 21 17:28:56 EDT 2011 i686 i686 i386 GNU/Linux
[me@server ~]$ python 
Python 2.3.4 (#1, May  5 2011, 17:13:16) 
[GCC 3.4.6 20060404 (Red Hat 3.4.6-11)] on linux2

这个应用运行在很糟糕的共享主机上,这也是我称它为“不稳定”的原因之一。我还因为它在2011年使用Python 2.3而对它有更糟糕的评价。如果我能用现代的Python来处理,这个问题可能会简单一些。


我打算采用Kevin下面的一个变体——因为我控制着crontab,我会让脚本查找在正确时间戳范围内的任何内容并对其进行操作。这还有一个好处,就是相关信息都可以保存在Python脚本中,成为一个单一的真实来源。

2 个回答

1

exception.log 这个文件改个临时的名字,然后处理这个临时文件。(我假设“脾气不好的网页应用”如果找不到 exception.log,会自动重新生成一个)。

2

我建议在网页应用还在运行的时候,不要删除异常日志。可以查看日志,看看有没有新的更新,但不要去改动它。

#lastKnownSizeOfFile is saved somewhere so it persists between executions of this script
if size(file) > lastKnownSizeOfFile: #found an update!
    amountToRead = size(file) - lastKnownSizeOfFile
    file.seek(lastKnownSizeOfFile)
    newData = file.read(amountToRead)
    exceptionArchive.write(newData)
    emailMe(newData)
    lastKnownSizeOfFile += amountToRead

如果你担心这样会导致日志文件变得太大,可以选择在用户不活跃的时候定期删除,比如凌晨2点,这个时候应用一般不会往日志里写东西。

撰写回答