0

I have written following code to log ping RTT with timestamp for a server continuously. Script is working file at command line But my pain the log file Ping_10.112.114.11.txt is empty for which I see no error or warning or syntactical error in code.

Below is my code:

#!/user/bin/perl


use Net::Ping;
use Time::HiRes;
use strict;

open (LOG , ">Ping_10.112.114.11.txt") || die "Cannot create log file :$!";

print LOG "File is ready to write\n\n";
my $host ="10.112.114.11";
my $p = Net::Ping->new();       #tcp echo request for ping check
$p->hires();

do  
{   my ($ret, $duration, $ip) = $p->ping($host);
my $time = localtime;
my $dur = (int(1000*$duration))/1000;
print "$time\t$host is alive (packet RTT: $dur ms)\n";
print LOG "$time\t$host is alive (packet RTT: $dur ms)\n";
}   while(1);

#END

I have also tryed saving the output to a variable then sending it to filehandle for printing but unfortunately none of my efforts seems to be working fine.

my $output = ""$time\t$host is alive (packet RTT: $dur ms)\n";
print LOG "$output";

Can anyone please help me in highlighting my silly mistake as I have written many scripts which use same perl syntax but works fine.

Between my overall requirnment is to write a script which runs to record the RTT & connectivity of servers continuously with time stamp in a log file. Just like the output from Ping -t with additional timestamp value.

Thanks in advance :)

avimehenwal
  • 1,502
  • 3
  • 21
  • 30

1 Answers1

2

The problem is likely to be that the output to your file is buffered, and you aren't waiting long enough for the buffer to be filled and flushed to the file. Enabling autoflush will fix this for you, and there are a few other issues with your code. This refactoring should do what you want.

use strict;
use warnings;

use Net::Ping;
use Time::HiRes;

my $host = '10.112.114.11';

STDOUT->autoflush;

open my $log, '>', "Ping_$host.txt" or die "Cannot create log file: $!";
$log->autoflush;

my $p = Net::Ping->new;
$p->hires;

while () {
  my ($ret, $duration, $ip) = $p->ping($host);
  my $event = sprintf "%s\t%s is alive (packet RTT: %.3fms)\n",
      scalar localtime, $host, $duration;
  print STDOUT $event;
  print $log $event;
}
Borodin
  • 126,100
  • 9
  • 70
  • 144
  • Thanks Borodin for bring flushing problem to light. That might be the reason for non log printing. But as I see there are few minor bugs in your code like you havent defined $log variable. Plus I am not sure if "print $log $event;" would work. Let me check on my machine and thanks for help :) – avimehenwal Jan 08 '13 at 13:54
  • Your code is many time more better and nice looking than mine but its throwing compilation error. D:\AVI MEHENWAL\PERL\SCRIPTS\PROJECTS\Ping Probe Server>perl perl_pingprobe_flus h.pl syntax error at perl_pingprobe_flush.pl line 27, near "print" Global symbol "$event" requires explicit package name at perl_pingprobe_flush.pl line 27. Global symbol "$event" requires explicit package name at perl_pingprobe_flush.pl line 28. Execution of perl_pingprobe_flush.pl aborted due to compilation errors. One thing I just realised is my code is missing Error Handling part ... – avimehenwal Jan 08 '13 at 14:00
  • Thanks TLP and @Borodin Code works excellent now. FLushing problem resolved. But I fail to understand this flushing problem with my code ... because I read somewhere perl has dynamic and automated memory management system then why we need to manually specify for memory clearence in perl code ? Doent it work dynamically during code runtime ? – avimehenwal Jan 09 '13 at 05:56
  • 1
    Dynamic memory allocation is unrelated to output stream buffering, which accumulates the output from your program in a memory buffer and writes it out only when the buffer is full. This is to reduce disk IO to a reasonable minimum, but applications that need real-time output should enable `autoflush`, which writes the output after every `print` statement instead of waiting for the buffer to fill. If you ran your original program for long enough then you would see the information finally appear. In general it's best to enable `autoflush` on console output and leave disk streams buffered. – Borodin Jan 09 '13 at 13:14
  • That completely satisfies me ! Even gave me more clearity on the concept. Thank you sir :) – avimehenwal Jan 10 '13 at 07:25