Hello Perl People.... I was wondering if someone could enlighten me on an observation I have been seeing..
A little Background info: Where I work we have been seeing very slow ssh connections times (it's not DNS. Maybe NIS, NFS, but definitely not DNS). Anyways I wanted to write a script that would log the time it takes to connect to a remote server via ssh and issue a command (uname -n). The tricky part was that I wanted the remote connections to kick off every 60 secs. (some ssh connections take a lot longer. 120+ in some cases). The log should enable me to pinpoint any time correlation to the long ssh connect occurrences (every 5 minutes? 1/2 past every hour? etc). So here we are back to the script.. The script works as expected, with one item of strangeness. I was expecting the log messages to be printed in the order they complete. For example, if the connection attempt at 12:01 took 75 seconds to return, and the connection attempt at 12:02 to 5 seconds to return, I would expect the 12:02 message to appear first then the 12:01, but it doesn't. The 12:02 connection won't print until the 12:01 returns. Here is my code: use strict; use Getopt::Std; use Sys::Hostname; use File::Basename; use Net::SSH qw( sshopen2 ); use Time::HiRes qw( gettimeofday tv_interval ); $|++; $SIG{CHLD} = 'IGNORE'; my %opts; getopts('dr:', \%opts); my $localhost = hostname(); my $r_host = $opts{'r'} ? $opts{'r'} : die "need remote host <-r> \n"; my $debug = $opts{'d'}; my $short_name = basename("$0", ".pl"); # --- set the counter to zero. We'll print the counter to the log for easier sorting # --- of data where the ssh connections take longer than a minute to return. my $ct = 0; while (1) { my $pid = fork(); if ($pid) { # parent } elsif ($pid == 0) { # child my $p = _initialize($ct); waitpid($p, 0); exit 0; } else { die "couldnt fork: $!\n"; } $ct++; sleep 60; } # --- # --- sub: initialize # --- descr: for easier viewing of the code for the fork process. # --- returns: nothing # --- sub _initialize{ my($count) = @_; my $now = scalar localtime(); my $start = [gettimeofday()]; my $ret = connect_to_remote_host("$r_host"); my $elapsed = tv_interval( $start ); if ($count < 10){ $count = "0$count"; } if ($count < 99){ $count = "0$count"; } my $msg = "$count - [$now] $localhost to $r_host Elapsed time: $elapsed "; write_to_log($msg); return; } # --- # --- sub: connect_to_remote_host # --- descr: uses ssh to connect to a remote host via ssh keys only. # --- returns: nothing. # --- sub connect_to_remote_host { my($host) = @_; my $user = 'root'; my $cmd = "uname -n"; my $out = ""; sshopen2("$user\@$host", *READER, *WRITER, "$cmd") || die "ssh: $!"; while (<READER>) { chomp(); #print "$_\n"; $out = $_; } close(READER); close(WRITER); return $out; } # --- # --- sub: write_to_log # --- descr: write messages to log file or print to stdout when in debug # --- returns: nothing sub write_to_log{ my ($message) = @_; my $log = "/tmp/$short_name.log"; if ($debug){ print "$message\n"; } open L, ">>$log" or die "Cannot open $log:$!\n"; print L "$message\n"; close L; } Just wondering why the messages being printed to the console waits for the previous pid (or pids) to complete before it's viewable. FYI - I implemented the Counter thinking the messages weren't always going to be in order and that I could always to a quick sort on the counter to get the correct timeline..... Thanks, Chad -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/