我有一个在Debian上运行的Python程序,它使用File对象输出数据。我想设置一个限制我的文件有多大,但我不想停止写文件 - 我只想删除最旧的行(在文件的顶部)。当数据包从客户端到达时,我的数据会随机写入(想想网络日志记录)。
我知道它有效,但是如果我的文件超出限制,那么通过使用File.tell()的组合然后执行以下系统命令来解决这个问题是符合我的最佳利益的吗?
sed -i '1 d' filename
一旦达到大小限制,它将每次执行sed。还有更好的方法吗?
答案 0 :(得分:3)
有一个原因是没有日志记录系统使用此策略。如果不重写整个文件,则无法从文件中删除第一行,因此在大文件上速度非常慢。此外,在重写文件时,无法将新数据写入文件。
正常策略是在当前文件变得太大时开始写入新文件。然后,您可以删除早于阈值的文件。这是其他人提到的“日志轮换”。
如果您真的想要创建一个队列,在添加新数据时删除一行数据,我建议使用数据库。 MongoDB和其他数据库管理器支持数组,但如果需要,您可以使用SQL数据库执行类似操作。
答案 1 :(得分:2)
似乎你不知道logrotate
。您正在寻找类似的实现。看看这个:
答案 2 :(得分:2)
Python的日志记录模块不使用此策略的原因是它所带来的性能损失。如果根据大小或年龄轮换的日志文件根本不可接受,那么我认为你有两个基本选择:覆盖日志文件,然后写一个临时文件然后替换。
如果在适当的位置覆盖日志文件,您首先要选择文件中的整数地址(第一个\ n字节加一个的位置),它将成为“新零”(称之为X)。然后选择块大小,可能是32K。然后开始计数。寻找X +块大小*块号,读取一个块。寻求阻止大小*块号,写回块。当您在读取时到达EOF时,将文件截断为长度块大小*块编号。
如果使用临时文件,请找到“新零”,将文件的其余部分复制到临时文件,然后将其重命名为原始名称。比我想象的更容易,无论如何都更容易解释,但使用的空间更多。
然后,编写新数据并关闭文件。每个日志消息都必须执行整个过程。祝你好运!
答案 3 :(得分:1)
您应该结帐Python logging module,更具体地说是结帐RotatingFileHandler。这允许您写入具有固定大小的文件。但是它不允许按行数进行操作。
答案 4 :(得分:0)
除非您需要从其他进程实时访问该文件,否则我可能会将每个日志行写入固定大小的collections.deque
。您可以实现一种方法,可以根据需要将collections.deque
中的项(行)同步到日志文件中的行。