gnu@perl has asked for the wisdom of the Perl Monks concerning the following question:

I have a situation where there are any number of servers and any number of users. I am attempting to write a program that will allow any user to connect to any server and view selected logfile information. Pretty simple idea, here's the catch though. All I can use is what comes with perl 5.00503 and I cannot load any additional modules. Also, no servers of any kind can exist on the target machines.

Expect is not loaded on all of the users stations (SUN Solaris) so it is out of the question. What I have been trying to do is use open3 to telnet to the target machines, tail the log file specified by the user, print that output to a file opened by the program then exit the telnet session and move on to the next machine.

All in all, it works ok, but it is pretty ugly and rough. The target machines all have different information presented to the user upon login so standardizing the process is kind of out of the question.

Any ideas, changes or suggestions would be appreciated.

Here is an little sample code to illustrate what I am doing. Please go easy on the code, it is not 100% as it is in flux between different ideas I have, but it does give the general idea.

#!/usr/bin/perl -w use strict; use POSIX; use IPC::Open3; use IO qw( Select Handle ); $|++; my $host = "deneb"; my $login = "username"; my $pword = "password"; my $logfil = "/var/log/syslog"; my $cmd = "telnet"; my $count = 0; my ($infh,$outfh,$errfh); my $pid; my $sel = new IO::Select; open (OUTFILE, ">deneb.log"); OUTFILE->autoflush(1); eval { $pid = open3($infh,$outfh,$errfh, "$cmd $host" ) }; die $@ if $@; $sel->add($outfh,$errfh); while (my @ready = $sel->can_read){ foreach my $fh (@ready) { my $line; my $len = sysread $fh, $line, 4096; if (not defined $len) { die "Error reading from child: $!\n"; } elsif ($len == 0){ $sel->remove($fh); }else { if ($fh == $outfh){ if ($count == 0){ print "$line\n"; print $infh "$login\n"; print $infh "$pword\n"; print $infh "tail $logfil"; $count = 1; }elsif ($count == 1){ print $infh "\n"; $count = 2; }elsif ($count == 2){ print OUTFILE $line; sleep 1; $count = 3; print $infh "exit\n"; }else {exit}; }elsif ($fh == $errfh){ print "From STDERR: $errfh\n"; }else { print "Should never be here!!\n"; } } } }

Replies are listed 'Best First'.
Re: grabbing logfile excerpts from remote machines
by bart (Canon) on Aug 31, 2002 at 01:20 UTC
    What I have been trying to do is use open3 to telnet to the target machines
    One idea: you can use Net::Telnet to access the remote machine. It might make the interface a bit more versatile. I'm not absolutely sure, but I wouldn't be too surprised if it comes with Perl.

    Lincoln Stein has written about it in his book "Network programming with Perl", and this particular chapter about telnet, is available online.

      MY GOD WAS I MAKING THAT HARDER THAN IT HAD TO BE!!!

      This was SOOOOOOOOOOOOO easy, thanks for the Net::Telnet tip.

      BTW, here's the code. I went from what I have above to this:

      #!/usr/bin/perl –w use strict; use Net::Telnet; my $tnet = new Net::Telnet; $tnet = new Net::Telnet; $tnet->open("deneb"); $tnet->login($username, $passwd); my @lines = $tnet->cmd("tail /var/log/syslog"); print @lines;
        All I can use is what comes with perl 5.00503 and I cannot load any additional modules.

        Well, I guess it's a good thing bart gave you that tip in spite of the above comment in your original question. Does Net::Telnet really come with 5.00503?

        -sauoq
        "My two cents aren't worth a dime.";
        
      Thanks a lot, I didn't even think of it. I will definately check that out.
Re: grabbing logfile excerpts from remote machines
by sauoq (Abbot) on Aug 31, 2002 at 00:12 UTC
    Also, no servers of any kind can exist on the target machines.
    ...
    What I have been trying to do is use open3 to telnet to the target machines, tail the log file specified by the user, print that output to a file opened by the program then exit the telnet session and move on to the next machine.

    Well, the machines are apparently already running telnet servers. Are there any other servers that are already running that might make your job easier? Maybe rshd or a webserver?

    As it looks like you are interested in syslog, maybe you should explore other options. Setting up a centralized syslog server might make sense in your case.

    -sauoq
    "My two cents aren't worth a dime.";
    
      The problem is that I cannot add any services to the machines (large group of them). Pretty much the only service that is running is telnet. As for syslog, that was just put in as a test. There are a large number of logfiles, both system generated and created by in house developed programs.

      Thanks for your input though.