log_server_status.pl errors

I am trying to get this script that came with apache to run.  I this:

Can't locate sys/socket.ph in @INC (did you run h2ph?) (@INC contains: /usr/perl5/5.6.1/lib/sun4-solaris-64int /usr/perl5/5.6.1/lib /usr/perl5/site_perl/5.6.1/sun4-solaris-64int /usr/perl5/site_perl/5.6.1 /usr/perl5/site_perl /usr/perl5/vendor_perl/5.6.1/sun4-solaris-64int /usr/perl5/vendor_perl/5.6.1 /usr/perl5/vendor_perl .) at ./log_server_status.pl line 3.

Can you help?

Thanks,

Trav
Traverse-61Asked:
Who is Participating?
 
kanduraCommented:
Traverse-61,

> Issuing "/usr/bin/ftp -n"
ftp.perl.org: unknown host or invalid literal address

Looks like your local dns configuration is broken.

Maybe this is a good moment to ask yourself if you want to fix your entire server, or just revert to using sockets. I'm not sure either way: the script is very easy with LWP::Simple, and therefore easy to maintain; but now you have to deal with dependencies, and it's giving you a lot of problems. So maybe the tradeoff would be to try and fix up your original script. Your call.

Here's a version that uses IO::Socket. Hope you have that installed at least!


#!/bin/perl

use strict;
use warnings;
use POSIX qw/strftime/;
use File::Spec;
use IO::Socket::INET;

my $wherelog = "./var/log/graph/";  # Logs will be like "/var/log/graph/19960312"
my $server = "localhost";          # Name of server, could be "www.foo.com"
my $port = "80";                   # Port on server
my $request = "/status/?auto";     # Request to send


### Main

{
    my $day  = strftime ("%F", localtime);
    my $time = strftime ("%T", localtime);

    my $log = File::Spec->catfile($wherelog, $day);
    open(OUT,">>$log") or die "Error opening log $log: $!";

   
    my @lines = get($server, $port, $request);

    warn "@lines";

    unless (@lines) {
            warn "Could not GET $server:$port$request";
            print OUT "$time:-1:-1:-1:-1:-1\n";
            exit 1;
    }

    my ($requests,$idle,$number,$cpu) = (0)x4;
    foreach (@lines) {
            $requests=$1 if ( m|^BusyServers:\ (\S+)|);
            $idle=$1 if ( m|^IdleServers:\ (\S+)|);
            $number=$1 if ( m|sses:\ (\S+)|);
            $cpu=$1 if (m|^CPULoad:\ (\S+)|);
    }

    print OUT "$time:$requests:$idle:$number:$cpu\n";
}

sub get
{
    my ($s, $p, $r) = @_;
    my $uri = "http://$s:$p$r";
    my $sock = IO::Socket::INET->new(PeerAddr => $s,
                                 PeerPort => $p,
                                 Proto    => 'tcp');
   
    $sock->print(qq{GET $uri HTTP/1.0\r\n\r\n});
   
    return $sock->getlines;
}
0
 
Traverse-61Author Commented:
Oh yea... the script:

#!/bin/perl

require 'sys/socket.ph';

$wherelog = "/var/log/graph/";  # Logs will be like "/var/log/graph/19960312"
$server = "localhost";          # Name of server, could be "www.foo.com"
$port = "80";                   # Port on server
$request = "/status/?auto";     # Request to send

sub tcp_connect
{
        local($host,$port) =@_;
        $sockaddr='S n a4 x8';
        chop($hostname=`hostname`);
        $port=(getservbyname($port, 'tcp'))[2]  unless $port =~ /^\d+$/;
        $me=pack($sockaddr,&AF_INET,0,(gethostbyname($hostname))[4]);
        $them=pack($sockaddr,&AF_INET,$port,(gethostbyname($host))[4]);
        socket(S,&PF_INET,&SOCK_STREAM,(getprotobyname('tcp'))[2]) ||
                die "socket: $!";
        bind(S,$me) || return "bind: $!";
        connect(S,$them) || return "connect: $!";
        select(S);
        $| = 1;
        select(stdout);
        return "";
}

### Main

{
        $year=`date +%y`;
        chomp($year);
        $year += ($year < 70) ? 2000 : 1900;
        $date = $year . `date +%m%d:%H%M%S`;
        chomp($date);
        ($day,$time)=split(/:/,$date);
        $res=&tcp_connect($server,$port);
        open(OUT,">>$wherelog$day");
        if ($res) {
                print OUT "$time:-1:-1:-1:-1:$res\n";
                exit 1;
        }
        print S "GET $request\n";
        while (<S>) {
                $requests=$1 if ( m|^BusyServers:\ (\S+)|);
                $idle=$1 if ( m|^IdleServers:\ (\S+)|);
                $number=$1 if ( m|sses:\ (\S+)|);
                $cpu=$1 if (m|^CPULoad:\ (\S+)|);
        }
        print OUT "$time:$requests:$idle:$number:$cpu\n";
0
 
kanduraCommented:
Hi Traverse-61,

Replace
> require 'sys/socket.ph';
with

    use Socket;

Remove the ampersands from the constants.
Read the documentation for the Socket module for details.

HTH,
Kandura
0
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

 
Traverse-61Author Commented:
Kanundra:

Runs Great!  Thanks!

Now can you tell me in layman's terms what I just did?  :)

Can you tell me how to read the output? :)

root@2u08# more 050420

100132::::
100217::::
100220::::
100223::::
100223::::
100224::::


One more thing... I tried to locate "socket module" documentation at apache.org.  I can't find mod_socket or anything that looks close.  Any clues here.

You have been most helpfule so far... Thanks.

Trav

0
 
manav_mathurCommented:
perldoc Socket
0
 
kanduraCommented:
As manav just pointed out ever so succinctly, the Socket module is a perl library. It provides access to the low level socket functions. See http://perldoc.perl.org/Socket.html for the complete documentation.

As for the output... It looks like you're trying to get the apache status report, but you're not getting any output. The only thing I can suggest offhand, is to add an extra new line to the request line:

    print S "GET $request HTTP/1.0\n\n";

I'll give it a run myself, and then compare to the script that I use for that (it's buried somewhere deep inside procallator.pl, which is a part of the Orca program).
0
 
kanduraCommented:
Hah! I cheated, by using the GET command line utility:

    @lines = `GET 'http://localhost/server-status?auto'`;

No need for all the socket dancing :)

0
 
manav_mathurCommented:
>it's buried somewhere deep inside procallator.pl, which is a part of the Orca program

Are you designing CGI scripts for middle-earth?? The names suggest so.
0
 
kanduraCommented:
hehehe. No, Orca is a program for graphing server stats. See http://www.orcaware.com/orca/ .
0
 
Traverse-61Author Commented:
Ok you guys are loosing me here.  I am a Perl novice, so bear with me.  So what I gather is that I need to add:

@lines = `GET 'http://localhost/server-status?auto'`;


...in the log_server_status script some where. right?   But where exactly?  
0
 
manav_mathurCommented:
Instead of the 'GET' http request, you use the 'GET' command line utility.
Instead of creating all your connection using tcp_connect(), you just fire off the 'GET' command line utility, and read the output.

#!/usr/bin/perl -w
use strict ;
@lines = `GET 'http://localhost/server-status?auto'`;
       for (@lines) {
                $requests=$1 if ( m|^BusyServers:\ (\S+)|);
                $idle=$1 if ( m|^IdleServers:\ (\S+)|);
                $number=$1 if ( m|sses:\ (\S+)|);
                $cpu=$1 if (m|^CPULoad:\ (\S+)|);
        }

If you insist on sockets, do have a look at IO::Socket::INET, which makes life easier by handling all the coket(), bind() etc calls itself.
0
 
manav_mathurCommented:
In the earlier script, you need to initialize all lexicals.
0
 
kanduraCommented:
here's a quicky rewrite. hope it works for you (it does for me).


#!/bin/perl

use strict;
use warnings;
use POSIX qw/strftime/;
use File::Spec;

my $wherelog = "/var/log/graph/";  # Logs will be like "/var/log/graph/19960312"
my $server = "localhost";          # Name of server, could be "www.foo.com"
my $port = "80";                   # Port on server
my $request = "/status/?auto";     # Request to send


### Main

{
    my $day  = strftime ("%F", localtime);
    my $time = strftime ("%T", localtime);

    my $log = File::Spec->catfile($wherelog, $day);
    open(OUT,">>$log") or die "Error opening log $log: $!";

    my $uri = "http://$server:$port$request";
    my @lines = `GET '$uri'`;

    warn "@lines"; # for debugging

    unless (@lines) {
            warn "Could not GET $uri";
            print OUT "$time:-1:-1:-1:-1:-1\n";
            exit 1;
    }

    my ($requests,$idle,$number,$cpu) = (0)x4;
    foreach (@lines) {
            $requests=$1 if ( m|^BusyServers:\ (\S+)|);
            $idle=$1 if ( m|^IdleServers:\ (\S+)|);
            $number=$1 if ( m|sses:\ (\S+)|);
            $cpu=$1 if (m|^CPULoad:\ (\S+)|);
    }

    print OUT "$time:$requests:$idle:$number:$cpu\n";
}
0
 
Traverse-61Author Commented:
Getting this:


# ./log_server_status2.pl
sh: GET: not found
Warning: something's wrong at ./log_server_status2.pl line 26.
Could not GET http://localhost:80/status/?auto at ./log_server_status2.pl line 29.
0
 
manav_mathurCommented:
Can you try and run this on your shell command prompt??

GET 'http://localhost/server-status?auto'
0
 
kanduraCommented:
bummer. that probably means you haven't installed lwp yet.

can you try this instead of the `GET...` line

    use LWP::Simple;
    @lines = get($uri);
0
 
Traverse-61Author Commented:
Thanks for sticking with me folks... I really need to make this work.

manav:

# GET 'http://localhost/server-status?auto'
bash: GET: command not found

Kanundra:

added your code like this:

    my $uri = "http://$server$request";
    use LWP::Simple;
    my @lines = get($uri);

... and got this:

Can't locate LWP/Simple.pm in @INC (@INC contains: /usr/perl5/5.6.1/lib/sun4-solaris-64int /usr/perl5/5.6.1/lib /usr/perl5/site_perl/5.6.1/sun4-solaris-64int /usr/perl5/site_perl/5.6.1 /usr/perl5/site_perl /usr/perl5/vendor_perl/5.6.1/sun4-solaris-64int /usr/perl5/vendor_perl/5.6.1 /usr/perl5/vendor_perl .) at ./log_server_status2.pl line 24.
BEGIN failed--compilation aborted at ./log_server_status2.pl line 24.

Trav
0
 
manav_mathurCommented:
Then you don't have either the GET utility, or the LWP::Simple module.
Assuming you are on a unixish platform, do this

perl -MCPAN -e 'shell'

this will take you to a commandline interface, there type
install LWP::Simple

If the installation of the module is successfull, Kandura's code should work then.
0
 
kanduraCommented:
manav,

Thanks for clearing that up.

> Assuming you are on a unixish platform

That's obvious:

> @INC contains: /usr/perl5/5.6.1/lib/sun4-solaris-64int

I'm happy to see that this solaris at least comes with perl 5.6!
0
 
manav_mathurCommented:
<quote>
> Assuming you are on a unixish platform

That's obvious:
</quote>

Only if you look closely at the code, which you always manage to and I never.
0
 
Traverse-61Author Commented:
Morning manav & kanundra:

I tried to install LWP ... still running into a few problems:

# perl -MCPAN -e 'shell'

cpan shell -- CPAN exploration and modules installation (v1.59_54)
ReadLine support available (try 'install Bundle::CPAN')

cpan> install LWP::Simple
LWP not available

  Please, install Net::FTP as soon as possible. CPAN.pm installs it for you
  if you just type
      install Bundle::libnet

Issuing "/usr/bin/ftp -n"
ftp.perl.org: unknown host or invalid literal address
Not connected.
Local directory now /export/home/rpullm/.cpan/sources/authors
Not connected.
Not connected.
Not connected.
Not connected.
Not connected.
Not connected.
Not connected.
Bad luck... Still failed!
Can't access URL ftp://ftp.perl.org/pub/CPAN/MIRRORED.BY./authors/01mailrc.txt.gz.

Please check, if the URLs I found in your configuration file
(ftp://ftp.perl.org/pub/CPAN/MIRRORED.BY./) are valid. The urllist can be
edited. E.g. with 'o conf urllist push ftp://myurl/'

Could not fetch authors/01mailrc.txt.gz
LWP not available
Issuing "/usr/bin/ftp -n"
ftp.perl.org: unknown host or invalid literal address
Not connected.
Local directory now /export/home/rpullm/.cpan/sources/modules
Not connected.
Not connected.
Not connected.
Not connected.
Not connected.
Not connected.
Not connected.
Bad luck... Still failed!
Can't access URL ftp://ftp.perl.org/pub/CPAN/MIRRORED.BY./modules/02packages.details.txt.gz.

Please check, if the URLs I found in your configuration file
(ftp://ftp.perl.org/pub/CPAN/MIRRORED.BY./) are valid. The urllist can be
edited. E.g. with 'o conf urllist push ftp://myurl/'

Could not fetch modules/02packages.details.txt.gz
LWP not available
Issuing "/usr/bin/ftp -n"
ftp.perl.org: unknown host or invalid literal address
Not connected.
Local directory now /export/home/rpullm/.cpan/sources/modules
Not connected.
Not connected.
Not connected.
Not connected.
Not connected.
Not connected.
Not connected.
Bad luck... Still failed!
Can't access URL ftp://ftp.perl.org/pub/CPAN/MIRRORED.BY./modules/03modlist.data.gz.

Please check, if the URLs I found in your configuration file
(ftp://ftp.perl.org/pub/CPAN/MIRRORED.BY./) are valid. The urllist can be
edited. E.g. with 'o conf urllist push ftp://myurl/'

Could not fetch modules/03modlist.data.gz
Warning: Cannot install LWP::Simple, don't know what it is.
Try the command

    i /LWP::Simple/

to find objects with matching identifiers.

cpan>
0
 
Traverse-61Author Commented:
I also tried this... still no luck.


cpan> o conf urllist push ftp://ftp.perl.org/pub/CPAN/MIRRORED.BY./

cpan> install LWP::Simple
Warning: Cannot install LWP::Simple, don't know what it is.
Try the command

    i /LWP::Simple/

to find objects with matching identifiers.

cpan> i /LWP::Simple/
No objects found of any type for argument /LWP::Simple/

cpan>
0
 
Traverse-61Author Commented:
kanundra:

Worked!!!  Thank you very much for your help!  Ok one last thing.  I run the script and get some very nice standard output that I would like to capture in a file.  I try using # ./log_server_status3.pl > testlog.txt but my file is empty.  How can I capture this output?

# ./log_server_status3.pl
HTTP/1.1 200 OK
 Date: Thu, 21 Apr 2005 12:47:56 GMT
 Server: Apache
 Content-Length: 438
 Connection: close
 Content-Type: text/plain
 
 Total Accesses: 10233
 Total kBytes: 199901
 CPULoad: .00211336
 Uptime: 151891
 ReqPerSec: .0673707
 BytesPerSec: 1347.67
 BytesPerReq: 20003.8
 BusyWorkers: 7
 IdleWorkers: 6
 Scoreboard: WWWWW____W__W...................................................................................................................................................................................................................................................
# more /var/log/graph/Thursday
08:34:09:0:0:0:0
08:37:14:6:4:0:.00207605
08:38:12:6:4:0:.00206864
08:41:42:6:4:0:.00205917
08:44:54:6:4:0:.00204996
08:47:10:7:6:0:.00227205
08:47:11:7:5:0:.00224568
08:47:12:7:4:0:.00222592
08:47:13:7:4:0:.00221274
08:47:14:7:5:0:.00219297
08:47:15:8:4:0:.0021732
08:47:16:7:7:0:.00215343
08:47:56:7:6:0:.00211336
# ./log_server_status3.pl > testlog.txt
HTTP/1.1 200 OK
 Date: Thu, 21 Apr 2005 12:49:02 GMT
 Server: Apache
 Content-Length: 438
 Connection: close
 Content-Type: text/plain
 
 Total Accesses: 10235
 Total kBytes: 199901
 CPULoad: .00302715
 Uptime: 151958
 ReqPerSec: .0673541
 BytesPerSec: 1347.07
 BytesPerReq: 19999.9
 BusyWorkers: 6
 IdleWorkers: 5
 Scoreboard: W.WWWW___W__....................................................................................................................................................................................................................................................
# more testlog.txt
0
 
manav_mathurCommented:
warn prints on STDERR. so try

./log_server_status3.pl 2>&1 1>testlog.txt
0
 
Traverse-61Author Commented:
Not quite ... but this did work...

# ./log_server_status3.pl 2>&1 2>testlog.txt

Listen folks, you have been a BIG help here.  Thank you so much.  I wish could give you both the max on points... hate to split'em up.

Peace!

Trav
0
 
kanduraCommented:
Yes, that output comes from the <<warn "@lines";>> line. That was actually a debug statement.
0
 
Traverse-61Author Commented:
I like that output much better than the /var/log/graph stuff :) ...for humans ya know.
0
 
manav_mathurCommented:
Actually, I should never have got any of the points. Kandura did all the hard work here.

And your file descriptor problem looks real funny to me. If you have already redirected STDERR to where STDOUT goes, how come you are still getting things at STDERR
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.