in reply to Re^2: trying to implement file tail with regular expression
in thread trying to implement file tail with regular expression

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,

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

    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; } } }

      Try this. Note I have used a module to read the ini file.

      #!perl use strict; use File::Tail; use Config::Tiny; #die "Usage: $0 <app_root_dir>" unless @ARGV == 1; my $app_root_dir = shift; =head1 content of param.ini DIAGFILE = diagfile HOSTNAME1 = hostname1 HOSTNAME2 = hostname2 =cut my $Config = Config::Tiny->read( "$app_root_dir/config/param.ini" ) or die "$!"; my $ref = tie *DIAG,"File::Tail",( name => $Config->{'_'}{'DIAGFILE'}, interval => 1, # wait at start maxinterval => 10, # change to suit adjustafter => 10 # change to suit ); my $restart; while (my $line = <DIAG>) { if ($line =~ /is higher than 5 seconds/) { # restart only if more than 60 seconds since last restart if (time() - $restart > 60) { run_command('stop',1); run_command('stop',2); run_command('start',1); run_command('start',2); $restart = time(); } } } # execute start/stop sub run_command { my ($action,$n) = @_; my $host = $Config->{_}{'HOSTNAME'.$n}; my $cmd = join ' ','sc',"\\\\$host",$action,'AudioSrv', ">$app_root_dir\\logs\\${action}ServiceOutput${n}.txt"; #system($cmd); print "$cmd\n"; # replace with system after testing }
      poj

        again thanks for your support. I tried your code but I faced the same issue. when its reaching while (my $line = <DIAG>) its stop. I am using Eclipse for step by step troubleshooting. I dont understand why this is happening. without using the file tail class it works fine and I was able to read from the file!!!!!! do you have any other idea please?