O'Reilly logo

Web Performance Tuning, 2nd Edition by Patrick Killelea

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Generating Graphs from ps Data

Now that we have all this wonderful ps data in a database, what are we going to do with it? Why, generate graphs of it on request, of course, just like we did with the rstat data. Here’s a sample CGI script that will do just that, and a sample graph generated from it. (To use the CGI script, you have to put it in your web server’s cgi-bin directory, and then hit the URL corresponding to the script.)

#!/usr/local/bin/perl

use DBI;

$ENV{ORACLE_HOME} = "/opt/ORACLE/product";

print qq|Content-type: text/html\n\n|;

#<meta http-equiv = "Pragma" Content = "no-cache">
#<meta http-equiv = "Expires" Content = "Thu, Jan 1 1970 12:00:00 GMT">

print qq|<HTML><HEAD><TITLE>generate a graph</TITLE>
</HEAD><BODY><H1>generate a graph</H1>|;

if ($ENV{'REQUEST_METHOD'} eq 'POST') {
   read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
   @pairs = split(/&/, $buffer);
   foreach $pair (@pairs) {
       ($name, $value) = split(/=/, $pair);

       $value  =~ tr/+/ /;
       $value  =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
       $contents{$name} = $value;
   }
}

$machine   = $contents{"machine"};
$args      = $contents{"args"};
$daterange = $contents{"daterange"};
$parameter = $contents{"parameter"};

if ($machine && $parameter && daterange) {

   `/bin/rm tmp/*.gif`; # possible removal of someone else's gif before they saw it

   $dbh = DBI->connect("dbi:Oracle:acsiweba", "patrick", "dbpasswd")
        or die "Can't connect to Oracle: $DBI::errstr\n";

   $sql  = "select to_char(timestamp, 'YYYY MM DD HH24 MI'), $parameter from patrick.
ps ";

   if ($daterange eq "today") {
       $sql .= "where timestamp between trunc(sysdate) and sysdate and 
machine='$machine'";
   }

   if ($daterange eq "yesterday") {
       $sql .= "where timestamp between trunc(sysdate) - 1 and trunc(sysdate) and 
machine='$machine'";
   }

   if ($daterange eq "t-7") {
       $sql .= "where timestamp between trunc(sysdate) - 7 and sysdate and 
machine='$machine'";
   }

   if ($daterange eq "t-30") {
       $sql .= "where timestamp between trunc(sysdate) - 30 and sysdate and 
machine='$machine'";
   }

   if ($daterange eq "t-365") {
       $sql .= "where timestamp between trunc(sysdate) - 365 and sysdate and 
machine='$machine'";
   }

   $sql .= " and args='$args'";

   #print "<p>start of query ", `date`;

   $sth = $dbh->prepare($sql);
   $sth->execute(  ) || print $dbh->errstr;

   ($timestamp, $item) = $sth->fetchrow_array; # get one sample row to be sure we 
have data
   if ($timestamp) {

       #print "<p>end of query ", `date`;

       $date = `date`;
       chop $date;

       open(GP, "|/usr/local/bin/gnuplot");
       print GP $gp_cmd;
       print GP qq|
           set xdata time
           set timefmt "%Y %m %d %H %M"
           set term gif
           set xlabel "graph made on $date"
           set bmargin 4
           set ylabel "$parameter"
           set output "tmp/$$.gif"
           plot '-' using 1:6 title "$args $parameter on $machine" with lines lt 2
       |;

       while(($timestamp, $item) = $sth->fetchrow_array) {
           print GP "$timestamp $item\n";
       }

       print GP "e\n";
       close(GP);

       $sth->finish(  );
       $dbh->disconnect or warn "acsiweba disconnect failed: $DBI::errstr\n";

       #print "<p>end of plotting ", `date`;
       print "<p><img src=\"tmp/$$.gif\"><p>";
       print "graph was generated from this query:<p> $sql\n";
   }
   else {
       print "Sorry, I do not have the requested data for that time range for 
$machine.";
   }
}

print qq|
<FORM
METHOD="POST" ENCTYPE="application/x-www-form-urlencoded">
<P>select a machine
<SELECT NAME="machine">
<OPTION SELECTED VALUE="mars">mars middleware
<OPTION VALUE="venus">venus middleware
<OPTION VALUE="mercury">mercury middleware
</SELECT>
</P>
<SELECT NAME="args">
<OPTION SELECTED VALUE="purchase">purchase app
<OPTION VALUE="billing">billing app
<OPTION VALUE="accounting">accounting app
</SELECT>
</P>
<P>select a parameter
<SELECT NAME="parameter">
<OPTION SELECTED VALUE="pmem">pmem
<OPTION          VALUE="pcpu">pcpu
<OPTION          VALUE="nlwp">nwlp
</SELECT>
</P>
<P>select a date range
<SELECT NAME="daterange">
<OPTION SELECTED VALUE="today">today
<OPTION VALUE="yesterday">yesterday
<OPTION VALUE="t-7">last 7 days
<OPTION VALUE="t-30">last 30 days
<OPTION VALUE="t-365">last 365 days
</SELECT>
</P>
<P>
<INPUT TYPE="submit" NAME="graph" VALUE="graph">
</P><HR><P>|;

print qq|</FORM>Questions? Write
<A HREF="mailto:p\@patrick.net">p\@patrick.net</A>
</BODY></HTML>|;

Figure 4-3 is an example graph generated from this CGI, showing a memory leak in an application, and restarts on 11/3 and 11/7.

Graph of ps data

Figure 4-3. Graph of ps data

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required