【问题标题】:How to read continuously updating log file & match particular pattern in perl script如何读取持续更新的日志文件并匹配 perl 脚本中的特定模式
【发布时间】:2019-04-23 17:34:01
【问题描述】:

我想阅读不断更新的日志文件。如果我得到特定的模式,那么我应该能够发送我能够做的邮件。

use strict;
use warnings;
my $line;
my $to = 'abc@abc.com';
my $from = 'xyz@abc.com';
my $subject = 'Connection Pool Issue';
my $message = 'There is connection pool issue. Please check Logs for more details';

open my $fh, '<', 'error.txt';
my @file = <$fh>;
close $fh;

foreach my $line (@file) {


 if ($line =~ /The connection is closed./) 

 { 

    open(MAIL, "|/usr/sbin/sendmail -t");
    print MAIL "To: $to\n";
    print MAIL "From: $from\n";
    print MAIL "Subject: $subject\n\n";
    # Email Body
    print MAIL $message;

    close(MAIL);
    print "Email Sent Successfully\n";

    last;
  }
}

我不想从文件处理程序 0 读取文件,这意味着从起始位置。

我希望从当前文件处理程序位置读取文件。 它不应包含已读的行。

请提出建议。 谢谢

【问题讨论】:

  • 提示:不要不必要地使用全局变量!使用open(my $MAIL, ...) 而不是open(MAIL, ...)

标签: perl file-handling


【解决方案1】:

使用File::Tail

use File::Tail qw( );

my $tail = File::Tail->new( name => $qfn );
while (defined( my $line = $tail->read() )) {
   if ($line =~ /The connection is closed\./) {
      ...
   }
}

如果你需要前面几行,

use File::Tail qw( );

my $tail = File::Tail->new( name => $qfn );
my @buf;
while (defined( my $line = $tail->read() )) {
   push @buf, $line;
   if ($line =~ /The connection is closed\./) {
      ...
      @buf = ();
   }
}

【讨论】:

    【解决方案2】:

    我已经用两种不同的方式解决了这个问题。

    没有模块,您可以执行以下操作:

    -Check if line count file exists and read into variable
    -loop through file line by line, increment counter
    -if $loop_line_count < $line_count_previous_run : skip
    -if $total_line_count < $line_count_previous_run : reset file count to 0
    -write total_line_count to file
    

    带文件::尾

    my $file=File::Tail->new( name=>"$log_file",internal=>10, maxinterval=>30, adjustafter=>5);
    
    while (defined(my $line=$file->read)) {
        ...
    }
    

    【讨论】:

    • 第一种方法会影响 CPU 和文件系统。它也不处理日志轮换。
    • 它确实处理日志轮换。如果总文件数小于上一次运行,它将重置日志文件计数器并将计数器重置为 0。此外,每个 File::Tail 读取整个文件以及 CPU/磁盘使用率将基本相同。
    • 这不是真的。 F::T 内置了延迟来专门避免这种情况,并且它在检测日志轮换方面做得比你做得更好。你的方法并不总是有效。 (您提出此声明很奇怪,因为您的 F::T 示例显示您覆盖了解决这两个问题的机制使用的默认值!!!)
    • interval 是默认值,最大间隔减半(60 -> 30)并且调整后也减半(10-> 5),这几乎没有改变任何东西,而不是我的脚本对新行的响应时间。我的用例是一个微笑大小的日志文件,每天轮换。
    • 你想通过提及这个来证明什么?我不明白你的意思。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多