【问题标题】:How can I trim log files using Perl?如何使用 Perl 修剪日志文件?
【发布时间】:2009-02-10 04:13:03
【问题描述】:

我最近遇到了一种情况,当一些相当大的日志文件超过一定大小时,我需要修剪它们。每个文件中除了最后 1000 行之外的所有内容都会被处理掉,作业由 cron 每半小时运行一次。我的解决方案是简单地遍历文件列表,检查大小并在必要时进行修剪。

for $file (@fileList) {
  if ( ((-s $file) / (1024 * 1024)) > $CSize) {
      open FH, "$file" or die "Cannot open ${file}: $!\n";
      $lineNo = 0;
      my @tLines;

      while(<FH>) {
        push @tLines, $_;
        shift @tLines if ++$lineNo < CLLimit;
      }
      close FH;

      open FH, ">$file" or die "Cannot write to ${file}: $!\n";
      print FH @tLines;
      close FH;
}

这在当前形式下有效,但是对于大型日志文件(尤其是具有 100_000+ 行的日志文件)有很多开销,因为需要读取每一行并在必要时进行移位。

有什么方法可以读取文件的一部分,例如在这种情况下,我希望能够仅访问最后的“CLLimit”行。由于该脚本部署在一个已经过得更好的系统上(想想 Celeron 700MHz 和 64MB RAM),我正在寻找使用 Perl 的更快替代方案。

【问题讨论】:

    标签: performance perl file-io


    【解决方案1】:

    我知道您想使用 Perl,但如果这是一个 UNIX 系统,为什么不使用“tail”实用程序进行修整?你可以用一个非常简单的脚本在 BASH 中做到这一点:

    if [ `stat -f "%z" "$file"` -gt "$MAX_FILE_SIZE" ]; then
        tail -1000 $file > $file.tmp
        #copy and then rm to avoid inode problems
        cp $file.tmp $file
        rm $file.tmp
    fi
    

    话虽如此,如果您打算为此使用 Perl,您可能会发现 this post 非常有用。

    【讨论】:

    • 感谢 bash 示例,我的任务与此类似,但我正在将所有 bash 脚本转换为 Perl,因此需要一些指导。 Perl Monks 教程看起来很有希望,我稍后会看看。
    【解决方案2】:

    估计日志中一行的平均长度 - 称之为 N 字节。

    从文件末尾向后搜索 1000 * 1.10 * N(因子 1.10 中的 10% 误差余量)。从那里向前阅读,只保留最近的 1000 行。


    问题被问到了 - 哪个函数或模块?

    内置函数seek在我看来像使用的工具吗?

    【讨论】:

    • 我确实想过这样的事情,但是由于我对 Perl 的了解相当有限,我不知道要使用哪些模块来完成任务。例如我将使用什么函数在 Perl 中的文件中向后查找?
    【解决方案3】:

    考虑简单地使用 logrotate 实用程序;它包含在大多数现代 Linux 发行版中。 BSD 系统的相关工具称为 newsyslog。这些工具或多或少是为您的预期目的而设计的:它以原子方式将日志文件移出位置,创建一个新文件(与以前的名称相同)来保存新的日志条目,指示生成消息的程序使用新文件,然后(可选)压缩旧文件。您可以配置要保留多少轮换日志。这是一个潜在的教程: http://www.debian-administration.org/articles/117

    这并不完全是您想要的界面(保留一定数量的行),但该程序可能比您自己编写的程序更健壮;例如,这里的答案不涉及以原子方式移动文件并通知日志程序使用新文件,因此存在丢失某些日志消息的风险。

    【讨论】:

    • 我以前解决过这个问题,我同意你在供应方管理消息缓存的观点。如果不使用 syslog 接口,移动文件时会发生奇怪的事情。
    猜你喜欢
    • 2011-05-02
    • 2019-03-08
    • 2012-03-28
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    相关资源
    最近更新 更多