从活动日志文件中删除前 N 行

从活动日志文件中删除前 N 行

有没有办法N从应用程序正在主动附加的日志中删除第一行?

答案1

不,Linux 等操作系统及其文件系统不提供从文件开头删除数据的功能。换句话说,文件存储的起始点是固定的。

删除文件开头的行通常是通过将剩余数据写入新文件并删除旧文件来实现的。如果程序打开旧文件进行写入,则该文件的删除将推迟到应用程序关闭该文件时。


正如评论者所指出的,出于我上一句中给出的原因,您通常需要协调日志文件修剪与编写日志的程序。具体如何执行此操作取决于程序。某些程序会在您向它们发送信号(例如 HUP)时关闭并重新打开其日志文件,这可用于防止将日志记录写入“已删除”的日志文件,而不会中断服务。

有许多实用程序可用于管理日志文件的大小,例如日志旋转

有些程序有自己的实用程序。例如,Apache Web 服务器包含一个旋转日志公用事业。

答案2

我认为这个任务可以通过sed

sed -i '1,10d' myfile

将从文件中删除从第 1到第 10行的行。

我认为每个人都应该至少看看这 sed 1 行

请注意,这对于正在由应用程序主动附加的日志文件不起作用(如问题中所述)。

sed -i将创建一个新文件并“删除”正在写入的文件。大多数应用程序将继续将日志记录写入已删除的日志文件,并将继续填充磁盘空间。新的、被截断的日志文件将不会被附加。这只有在应用程序重新启动或以其他方式发出信号关闭并重新打开其日志文件时才会停止。此时,如果在使用 sed 和应用程序重新启动之间有任何可记录的活动,新日志文件中就会出现间隙(缺少日志记录)。

一种安全的方法是停止应用程序,使用 sed 截断日志,然后重新启动应用程序。这种方法对于某些服务(例如具有高吞吐量和服务连续性要求高的 Web 服务器)是不可接受的

答案3

这是一回答,不是解决方案。这个问题没有解决方案。提问者明确指出:“来自正在被积极追加通过申请”。 你可以继续阅读以了解更多信息,也可以跳到最后查看我根据自己的经验提出的建议假定为什么此代码没有遵循日志记录最佳实践。

需要明确的是:这里的其他“答案”提供了虚假承诺。无论怎样重命名都无法诱使应用程序使用新文件。最有用的信息隐藏在这些错误答案的评论中。

活动文件并不是某种简单地将数据放入的容器。文件名指向一个 inode(文件开头),每个 inode 都有一个指向另一个 inode 的指针(如果有更多数据)。这意味着一个不断写入的文件会不断添加 inode,而您认为的“文件”实际上是 inode 的日志序列。

想象一下,您正在谷歌地图上追踪某人,而该人可以随时传送到世界任何地方,而您正试图将这些点连接起来。

Linux 工具“truncate”可以丢弃文件末尾的数据,只需遍历 inode 树,然后(在您指定的位置/大小)丢弃堆栈中所有后续指针。要执行相反的操作 - 丢弃文件末尾的数据开始文件的 - 将是一个非常复杂和危险的过程,重写 inode 树实时没有人会为公众编写这样的工具,因为它们经常会失败并导致数据丢失。Inode 维基很短,但解释了其中的一些概念。

回到您的问题:这可能是一个内部应用程序(否则有人已经贡献了补丁来修复)。将此行为标记为代码审查,因为这不符合日志记录最佳实践。探索可能的影响……您是否正在拼命防止因磁盘已满而导致的中断?这应该是在审查中记录在案的场景,作为风险。

答案4

我喜欢下面的简单解决方案......

由于我无法预测日志中会删除多少行,因此我保留最后 n 行:

echo "$(tail -1000 /var/log/messages)" > /var/log/messages
echo -e "\n### Log reduced via cronjob at $(date) ###\n" >> /var/log/messages

将上述两行放入 cron 作业中,您就会得到类似日志轮换的功能。命令各部分的解释:

echo "string" >将覆盖整个文件,并在文件末尾添加单词“string”。

echo "string" >>只会在文件末尾添加单词“string”。

echo -e-e选项可以解释反斜杠转义。

echo "$(command)"将会将命令的输出返回到文件。

tail -1000 /var/log/messages返回文件的最后 1000 行/var/log/messages

相关内容