perl redirect output to file ..not working

here is simple perl script i wanted for my net connection ... just to check if default gateway is pingable or not if not write in log file but problem is that i can not write in file i can print on STDOUT but not in file ...why so ??

same thing was there when i was tying to write on sockets across the servers and on client side i was reading on port and trying to write to file but that didnt work either ... so just curious to know why i am not able to write to file ...

#!/usr/bin/perl -w
use strict;

use Net::Ping ;

my $config_file = "PingDetails.xml" ;   # ignore this this was config file ..not used 
my $host        = "122.122.122.122" ; # just random IP address which will always fail
my $TimeOut   = "25" ; # Time to wait after each successful ping in sec
my $FailOut     = "5" ; # time to wait after each unsuccessful ping in sec
my $LogFile     = "Pingreport.txt" ; # defined but not used

sub main {
    ## commented config file section as XML::Simple was giving some error
    #&ReadConfig("$config_file") ;
    &PingResults ; 
}

sub ReadConfig($)
{
    my $_file = $_[0] ;
    my $xml = XMLin($_file) ;
    
    $host    = $xml->{Host} ;
    $TimeOut = $xml->{TimeDuration} ;
    $FailOut = $xml->{FailTimeOut} ;
    $LogFile = $xml->{LogFile} ;
}

sub PingResults() 
{
    
    my $TO = "" ;
    print "******\n" ;
    print "Going To PING [$host] server after every [".($TimeOut+5)."] sec\n" ;
    print "if server fails to respond will ping server every [".( $FailOut+5)."] sec\n" ;
    print "put all logs in [$LogFile]\n" ;
    print "******\n" ;
    print "CNTL-C to Abort ...\n" ;
    
    print "Here ....\n" ;
    open (LOGFILE,">ping.log") or die "can not open file $LogFile : $!\n" ;
    print "Ping.log not found \n" if ( ! -e "ping.log" )  ;
    printf LOGFILE "%25s   %16s   %20s\n","TIME(yyyymmdd_hh:mi:ss)","HOST","STATUS" ;
    while () 
    {
        $TO = "" ;
	my $p = Net::Ping->new() ; 
        if ( $p->ping($host) ) 
        {
	   # This means host is reachable 
	   $TO = $TimeOut ;
	   print STDOUT "$host - reachable\n" ;
        } else 
        {
	   # This means host is not reachable
	   $TO = $FailOut ;
	   my $stat = "".timestamp()."        : $host  : Not reachable" ;
	   &WriteLog("$stat") ; 
	   print STDOUT "$stat\n" ;
        }
        sleep ($TO)
    }
    close LOGFILE ; 
}

sub timestamp()
{
   my ( $sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime ;
   $year += 1900 ;
   $mon += 1 ;
   my $timeStamp = sprintf "%04d%02d%02d_%02d:%02d:%02d",
                   $year, $mon, $mday, $hour, $min, $sec ;
   return $timeStamp ;
}

# this sub routine i though might be because of while loop its not printing in # file so created new sub routine
sub WriteLog($) 
{
    print "in write log\n" ;
    my $_msg = $_[0] ; 
    print LOGFILE "$_msg\n" ;
}
main () ;

I took this subset of your script and ran it, it writes successfully to ping.log:

#!/usr/bin/perl -w

    open (LOGFILE,">ping.log") or die "can not open file $LogFile : $!\n" ;
    print "Ping.log not found \n" if ( ! -e "ping.log" )  ;
    printf LOGFILE "%25s   %16s   %20s\n","TIME(yyyymmdd_hh:mi:ss)","HOST","STAT
US" ;
    close LOGFILE;

Same for you?

Its not apparent why nothing is being written to the file, but this looks a little dangerous:

    while () 

that will start an endless loop. Are you manually killing this script?

Are there no warnings or error generated by the script anywhere? In the server error log maybe?

@Annihilannic

yes it works no problems ... i can write to file but only with that code snippet

@KevinADC

ok my requirement is my Net gets disconnected evey now and then in night just to monitor frequency of disconnection i have written this script. and yes i am manually killing script

here is the o/p of script

******
Going To PING [172.30.0.16] server after every [35] sec
if server fails to respond will ping server every [10] sec
put all logs in [ping.log]
******
CNTL-C to Abort ...
20081017_13:40:30        : 172.30.0.16  : Not reachable
20081017_13:40:40        : 172.30.0.16  : Not reachable
20081017_13:40:50        : 172.30.0.16  : Not reachable

CNTL-C

-rw-r--r--   1 mhatrnin   idcuser          0 Oct 17 13:40 ping.log
mhatrnin(hpux1572)-/idcuser/mhatrnin>cat ping.log
mhatrnin(hpux1572)-/idcuser/mhatrnin>

yup checked syslog nothing there related to script.

does this script works at your end ???

The problem is that output is buffered, and since you are in an endless while loop, with small amounts of output, it will take a while before the log data is written from buffer to disk. Test this by moving your close after your print to the logfile. If you want to see data in real time, you'll have to unbuffer output to the file.

unbuffer the output ... with " $| =1 " but even that is not working for infinite while loop if put counter and run loop only 10 times it works.
so rather than using a Net::Ping i am using ping command redirect the o/p to file and search from "time out" which is working fine... any ways thanx for help

ahh.... excellent observation. I should have noticed that myself.

       $|      If set to nonzero, forces a flush right away and after every
               write or print on the currently selected output channel.
               Default is 0 (regardless of whether the channel is really
               buffered by the system or not; $| tells you only whether you've
               asked Perl explicitly to flush after each write).  STDOUT will
               typically be line buffered if output is to the terminal and
               block buffered otherwise.  Setting this variable is useful pri-
               marily when you are outputting to a pipe or socket, such as
               when you are running a Perl program under rsh and want to see
               the output as it's happening.  This has no effect on input
               buffering.  See "getc" in perlfunc for that.  (Mnemonic: when
               you want your pipes to be piping hot.)