in reply to trying to implement file tail with regular expression

The second example of use seems to fit your situation:

use File::Tail; my $ref=tie *DIAG,"File::Tail",(name=>$name); while (<DIAG>) { # your while (1) loop processing goes here }

You open LOGFILE each time thru the outermost while, but close it only if the if statement is true. I would try to make this consistent; perhaps you don't need to close it, now that you have File::Tail to read it.

I believe you will not need the sleep statement anymore. File::Tail keeps track of how often it finds data, and adjusts how often it reads accordingly.

But God demonstrates His own love toward us, in that while we were yet sinners, Christ died for us. Romans 5:8 (NASB)

Replies are listed 'Best First'.
Re^2: trying to implement file tail with regular expression
by mkhayat (Initiate) on Feb 14, 2016 at 08:12 UTC

    Thank you very much for your help. I did what you said but the issue is once I reach to while (<DIAG>) it hang for some reason. please help!!

    use File::Tail; my $diagfile; my $Checkoutput; my $hostName1; my $hostName2; sub init { my ($dir) = @_; my $line; my $var; my $val; open (LREP2, "$dir/config/param.ini"); while ($line = <LREP2>) { chop $line; ($var,$val) = split(/=/, $line); if ($var eq "DIAGFILE") { $diagfile = $val; } if ($var eq "CHECKFILE") { $Checkoutput = $val; } if ($var eq "HOSTNAME1") { $hostName1 = $val; } if ($var eq "HOSTNAME2") { $hostName2 = $val; } } close LREP2; } #MAIN die "Usage: $0 <app_root_dir>" unless @ARGV == 1; my $app_root_dir = shift; &init($app_root_dir); my $line; open (DIAG, "$diagfile"); my $ref=tie *DIAG,"File::Tail",(name=> $diagfile); my $clock = 0; while (<DIAG>){ while (1) { open LOGFILE, ">>$app_root_dir/logs/detailedlog.log"; while ($line = <DIAG>) { if ($line =~ /is higher than 5 seconds/) { if ($clock == 0) { $clock = 60; my $commandStr2 = "sc \\\\$hostName1 stop AudioSrv + >$app_root_dir\\logs\\StopServiceOutput1.txt" ; print LOGFILE "about to execute=$commandStr2\n"; system($commandStr2); print LOGFILE "just executed=$commandStr2\n"; my $commandStr4 = "sc \\\\$hostName2 stop AudioSrv + >$app_root_dir\\logs\\StopServiceOutput2.txt" ; print LOGFILE "about to execute=$commandStr4\n"; system($commandStr4); print LOGFILE "just executed=$commandStr4\n"; sleep(5); my $commandStr3 = "sc \\\\$hostName1 start AudioSr +v >$app_root_dir\\logs\\StartServiceOutput1.txt"; print LOGFILE "about to execute=$commandStr3\n"; system($commandStr3); print LOGFILE "just executed=$commandStr3\n"; my $commandStr5 = "sc \\\\$hostName2 start AudioSr +v >$app_root_dir\\logs\\StartServiceOutput2.txt"; print LOGFILE "about to execute=$commandStr5\n"; system($commandStr5); print LOGFILE "just executed=$commandStr5\n"; } $clock --; sleep(1); } close LOGFILE; } sleep(65); } }

      Hello mkhayat, and welcome to the Monastery!

      the issue is once I reach to while (<DIAG>) it hang for some reason.

      The nested loops in the MAIN code have the following structure:

      while (<DIAG>){ while (1) { open LOGFILE, ">>$app_root_dir/logs/detailedlog.log"; while ($line = <DIAG>) { if ($line =~ /is higher than 5 seconds/) { if ($clock == 0) { $clock = 60; # call "print LOGFILE" then "system(...)", 4 times } $clock --; sleep(1); } close LOGFILE; } sleep(65); } }

      There are at least 3 problems here:

      1. There are two while (<DIAG>) loops, one nested inside the other.
      2. There is no last statement inside the while (1) loop, so that loop will never terminate.
      3. As GotToBTru observed: Within the inner while ($line = <DIAG>) loop, you close the filehandle LOGFILE after the first iteration, so on all subsequent iterations the print LOGFILE ... statements have nowhere to write to.

      In addition, you still have calls to sleep although GotToBTru advised that they are not needed when using the File::Tail module.

      Hope that helps,

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

        Thanks for your reply. I am new to Perl language so please be patient with me. for the first problem you mentioned, I dont understand what I should do here. GotToBTru suggested to put while (<DIAG>) first and put inside this loop the rest of the statements. maybe i misunderstand what he suggested. please help me to understand. for problem 2 i put the last as you suggested. for the third issue I completely removed the LOGFILE because I dont need it. the purpose of this script is to check a diagnostic file (.dia) which is continuously updated and once it match a statement "higher than 5 seconds" to shutdown a service and start it again. and then continue to work. below is the updated code please take a look and let me know what should i do as I am desperate :( :( :(

        #!C:\Perl64\bin\perl.exe use File::Tail; my $routerip; my $diagfile; my $Checkoutput; my $hostName1; my $hostName2; sub init { my ($dir) = @_; my $line; my $var; my $val; open (LREP2, "$dir/config/param.ini"); while ($line = <LREP2>) { chop $line; ($var,$val) = split(/=/, $line); if ($var eq "ROUTERIP") { $routerip = $val; } if ($var eq "DIAGFILE") { $diagfile = $val; } if ($var eq "CHECKFILE") { $Checkoutput = $val; } if ($var eq "HOSTNAME1") { $hostName1 = $val; } if ($var eq "HOSTNAME2") { $hostName2 = $val; } } close LREP2; } #MAIN die "Usage: $0 <app_root_dir>" unless @ARGV == 1; my $app_root_dir = shift; &init($app_root_dir); my $line; open (DIAG, "$diagfile"); my $ref=tie *DIAG,"File::Tail",(name=> $diagfile); my $clock = 0; while (<DIAG>) { while (1) { while ($line = <DIAG>) { if ($line =~ /is higher than 5 seconds/) { if ($clock == 0) { $clock = 60; my $commandStr2 = "sc \\\\$hostName1 stop AudioSrv + >$app_root_dir\\logs\\StopServiceOutput1.txt" ; system($commandStr2); my $commandStr4 = "sc \\\\$hostName2 stop AudioSrv + >$app_root_dir\\logs\\StopServiceOutput2.txt" ; system($commandStr4); sleep(5); my $commandStr3 = "sc \\\\$hostName1 start AudioSr +v >$app_root_dir\\logs\\StartServiceOutput1.txt"; system($commandStr3); my $commandStr5 = "sc \\\\$hostName2 start AudioSr +v >$app_root_dir\\logs\\StartServiceOutput2.txt"; system($commandStr5); } $clock --; } last; } } }