有没有办法N
从应用程序正在主动添加的日志中删除第一行?
有没有办法N
从应用程序正在主动添加的日志中删除第一行?
Answers:
不,像Linux这样的操作系统及其文件系统,没有为从文件开头删除数据做好准备。换句话说,文件存储的起点是固定的。
通常通过将剩余数据写入新文件并删除旧文件来完成从文件开头删除行的操作。如果程序打开了要写入的旧文件,则该文件的删除将推迟到应用程序关闭该文件为止。
正如评论者所指出的那样,由于我上一句话中提到的原因,您通常需要将日志文件修剪与正在编写日志的程序进行协调。确切的操作方式取决于程序。当您向它们发送信号(例如HUP)时,某些程序将关闭并重新打开其日志文件,这可用于防止将日志记录写入“已删除”日志文件,而不会中断服务。
有许多实用程序可用于管理日志文件的大小,例如logrotate
一些程序具有自己的实用程序。例如,Apache Web服务器包含一个rotatelogs实用程序。
我认为这个任务可以通过 sed
sed -i '1,10d' myfile
将消除从1行第一至10 个线形式的文件。
我认为每个人至少应该看看sed 1衬板。
请注意,这不适用于应用程序正在主动附加的日志文件(如问题中所述)。
sed -i
将创建一个新文件并“删除”正在写入的文件。大多数应用程序将继续将日志记录写入已删除的日志文件,并将继续填充磁盘空间。新的,被截断的日志文件将不会附加到该文件。仅当应用程序重新启动或以其他方式发出关闭并重新打开其日志文件的信号时,此操作才会停止。如果在使用sed和应用程序重新启动之间进行了任何可记录的活动,则新日志文件中将存在一个间隙(缺少日志记录)。
一种安全的方法是停止应用程序,使用sed截断日志,然后重新启动应用程序。对于某些服务(例如,具有高吞吐量和高服务连续性要求的Web服务器),这种方法可能是不可接受的
sed -i
创建一个新文件,并且删除了旧文件,因此您不编辑活动文件:$ ls -i --- 6823554 testfile --- $ sed -i 's/test/final/' testfile --- $ ls -i --- 6823560 testfile
------请检查其sed -i
工作方式。为什么这个错误的答案会有这么多的反对?
否。解决此日志文件增长的一般问题的方法是日志轮换。这涉及将现有日志文件定期(通常每晚或每周一次)移动到其他文件名,并从一个空的日志文件重新开始。一段时间后,旧的日志文件将被丢弃。
参见:http : //www-uxsup.csx.cam.ac.uk/~jw35/courses/apache/html/x1670.htm
这是一个答案,而不是解决方案。这个问题没有解决方案。询问者清楚地指出:“从应用程序正在主动添加的日志中”。 您可以继续阅读以了解更多信息,并根据我的推测跳过最后的建议,以使我理解为什么此代码未遵循最佳实践。
需要明确的是:此处的其他“答案”提供了虚假的承诺。重命名不会欺骗应用程序使用新文件。在对这些错误答案的评论中掩藏了最有用的信息。
活动文件不是您只是将数据放入其中的某种容器。文件名指向一个inode(文件的开始),每个inode都有一个指向另一个inode的指针(如果有更多数据)。这意味着一个连续写入的文件中将添加一个恒定的inode流,并且您对“文件”的想法实际上是inode的日志序列。
想象一下,您正在跟踪Google Maps上的某个人,并且该人可以随时随地传送到世界任何地方,并且您试图连接这些点。
Linux工具“截断”可以通过简单地遍历inode树来丢弃文件末尾的数据,并且(在您指定的位置/大小处)它将丢弃堆栈中的所有后续指针。进行相反的操作(在文件开头丢弃数据)将是一个极其复杂且冒险的过程,需要实时重写inode树,没人会为公众编写此类工具,因为它们经常会失败并导致数据丢失。该索引节点维基是短暂的,但解释了这些概念。
**我的建议:解决此问题-为什么此应用程序会以这种方式运行?有许多日志记录最佳实践,但是通常它们与您的日志记录系统(syslog等)实际联系在一起。从根本上讲,应用程序应该“释放”它对文件的处理,因此logrotate(等)可以处理旧数据的进一步处理。
每当我听到“发送到活动日志文件”时,我都会立即要求该人告诉我此应用程序背后的“特殊故事”。通常是“开发人员退出,我们无法更改代码。这实际上是安全性的倒退,它有其自身的一系列风险。但是我得到您想要一种避免接触源代码的解决方案。如果这是情况下,需要一个更具体的问题。
以崇高的文本打开即使文件被追加,删除行并保存文件也可以以某种方式工作,但是我是来这里搜索命令行解决方案的,所以我将在这里保留这个有效但无用的解决方案!
也许复制,截断,拖尾复制到size = 0截断,然后删除副本?
更好的是从尾部到尾部复制,截断原件,将concat尾部复制到原件上。
您会在日志中找到尾部长度的行,因此比字节长度限制更好。
修改评论的详细信息:
首先,您可以使用Python3中的记录器脚本
from time import sleep
idx = 0
while 1 == 1:
idx = (idx + 1)
lf = open('tailTrunc.log', 'a')
lf.write("line to file " + str(idx) + '\n')
lf.close()
sleep(0.01)
然后我们有截断器
#!/usr/bin/env bash
trap "kill 0" EXIT
rm tailTrunc.log
touch tailTrunc.log
python3 logLoop.py &
loggerPID=$!
sleep 1
kill -STOP $loggerPID
tail -10 tailTrunc.log > trimEnd.log
truncate -s 0 tailTrunc.log
kill -CONT $loggerPID
sleep 1
trimEnd.log显示80到89
日志显示90结束
无论如何,有志者事竟成。
合并器的许多更复杂的示例以及写流的打开或关闭方式可能需要针对每个cpu内核进行调整,等等。如果可以在记录器中记录日志过程等,只需暂停写入并排队。