http://qs1969.pair.com?node_id=250423

I was experimenting with CGI::Push and came up with a really CUFP. It's tiny, but oh-so-neat and I'm not sure why I haven't stumbled upon this before on the web.

It updates the browser every second. It's too bad IE doesn't conform to standards, I think this (server push) could've led to some neat web services.

You will most likely need to edit it to point to your access_log.

#!/usr/bin/perl -w use strict; use CGI::Push qw(:standard); use CGI::Carp qw(fatalsToBrowser); use CGI::Carp qw(warningsToBrowser); do_push( -type => "text/plain", -nph => 0, -delay => 1, -next_page => sub { return `uptime`, "\n", `tail /var/www/logs/access_log`, "\n", `ps auxw`; }, );

Replies are listed 'Best First'.
•Re: Server status through HTTP using CGI::Push
by merlyn (Sage) on Apr 15, 2003 at 03:50 UTC
      It is worth noting that server push ties up one TCP connection and one process per client, so doesn't scale very well. That's not a concern for running low traffic scripts like this one is probably meant to be, but means you can't do much else than low traffic scripts before your server starts going toes-up.

      Makeshifts last the longest.

Re: Server status through HTTP using CGI::Push (multiple parameters to import())
by Aristotle (Chancellor) on Apr 15, 2003 at 01:02 UTC
    use CGI::Carp qw(fatalsToBrowser); use CGI::Carp qw(warningsToBrowser);
    You know you can combine these, right?
    use CGI::Carp qw(fatalsToBrowser warningsToBrowser);

    Makeshifts last the longest.

Re: Server status through HTTP using CGI::Push (HTML version)
by itodd (Acolyte) on Apr 15, 2003 at 17:56 UTC
    I took the liberty of expanding on this and came up with a useful top-like script (including filter links and formatted fields):
    #!/usr/bin/perl -w use strict; use CGI 'param'; use CGI::Push qw(:standard); use CGI::Carp qw(fatalsToBrowser warningsToBrowser); do_push( -nph => 0, -delay => 2, -next_page => sub { my($q, $count) = @_; my @return; my $command = "ps -auxwr"; $command .= " -U ".getpwuid(param("uid")) if param("uid") =~ /^[0-9]+$/; my @lines = split /\n/, `$command`; my @header = split /\s+/, shift @lines; my %format = ( "USER" => sub { my($value) = @_; my $uid = getpwnam($value); return $value if ($uid == param("uid") && defined param("uid")); return "<a href=\"$ENV{SCRIPT_NAME}?uid=$uid\">$value< +/a>"; }, "\%CPU" => sub { my($value) = @_; return ($value > 0.0) ? "<b>$value%</b>" : "$value%"; }, "\%MEM" => sub { my($value) = @_; return "$value%"; }, "VSZ" => sub { my($value) = @_; $value =~ s/(?<=\d)(?=(\d\d\d)+$)/,/g; return "$value&nbsp;kb"; }, "RSS" => sub { my($value) = @_; $value =~ s/(?<=\d)(?=(\d\d\d)+$)/,/g; return "$value&nbsp;kb"; } ); push @return, <<EOF; <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html lang="en"> <head> <title>$ENV{SERVER_NAME}: $command</title> </head> <body> <table border="1"> <tr> EOF foreach(@header) { push @return, " <th>$_</th>\n"; } push @return, " </tr>\n"; foreach(@lines) { my @field = split(/\s+/, $_, $#header+1); push @return, " <tr>\n"; my $f=0; foreach(@field) { $_ = &{$format{$header[$f]}}($_) if(defined $format{$header[$f]}); push @return, " <td>$_</td>\n"; $f++; } push @return, " </tr>\n"; } push @return, <<EOF; </table> </body> </html> EOF return @return; }, );
Re: Server status through HTTP using CGI::Push
by meredith (Friar) on Apr 17, 2003 at 19:16 UTC
    I wrote a pair of quickie perl/tk programs meant to monitor and control named and sendmail (for the less unix-apt in tech services). I noticed that, for a reasonable refresh rate, using backquotes is a waste of cpu time. You know, forking, spawning, context switching, blah. It also makes your PIDs wrap around faster ;) You might look into modules like Proc::ProcessTable, which will avoid using ps. Tailing a file should be cake in perl, too. Uptime... not sure on that one, but I imagine it's trivial -- a posix call that returns uptime in seconds or such. Anyway, just a tip!
    ======================================
    mhoward----at----hattmoward.org