Web Server Performance Monitor


To generate Web Server statistics, click the GO button.


======================================================================== #!/usr/local/bin/perl # webhttpd.pl # Script to monitor and log number of concurrent http connections # on Web server # Written 11/10/97 RGF # Revised 9/21/99 RGF $count = 0; $count_log = ""; #+# insert count log @hits = (`ps -afe | grep httpd | grep -v grep`); foreach $entry (@hits) { $count++; } concat(COUNTFILE, "<$count_log"); print COUNTFILE "$count"; close(COUNTFILE); ======================================================================== #!/usr/local/bin/perl # Script to monitor Web server performance # Uses libwww # Written 11/7/97 RGF # Revised: 9/21/99 RGF $| = 1; $site = qq(qq(www.mysite.com)); #+# Insert your URL here $cgi_dir = qq(cgi-bin); #+# Insert path to CGI directory $log = qq(/var/home/sa/webperf.log); #+# Insert the path to webperf.log $webgraph = qq($site/$cgi_dir/webgraph.cgi); #+# Insert path to webgraph.cgi $count_file = qq(/var/home/sa/webhttpd_count); #+# Insert the path to webhttpd_count chomp($testdate = qx(date)); $count = qx(ps -afe | grep -c 'httpd.conf' | grep -v grep); $keyword = qq(my_keyword); #+# Insert a word or phrase from your index page concat(COUNTFILE, ">$count_file") || die "can't open $count_file"; print COUNTFILE "$count"; close(COUNTFILE); &main; sub main { $time0 = qx(date +%M:%S); $page = qx(perl -MLWP::Simple -e 'getprint $site' | grep $keyword); $time1 = qx(date +%M:%S); &getTime; &checkPage; &getCount; &printLog; qx($webgraph); } sub getTime { ($min0,$sec0) = split(/:/, $time0); ($min1,$sec1) = split(/:/, $time1); $mintot = $min1 - $min0; $sectot = $sec1 - $sec0; $min = abs ($mintot); $sec = abs ($sectot); } sub checkPage { if ($page) { $status = "passed"; } else { $status = "failed"; } } sub printLog { concat(LOG, ">>$log") || die "Can't open $log"; print LOG "$testdate: $min Min, $sec Sec Status: $status Connects: $connects"; close(LOG); } sub getCount { concat(COUNTFILE, $count_file) || die "Can't open $count_file"; while ($line = ) { $connects = $line; $connects = 0 unless ($connects); close(COUNTFILE); } } ======================================================================== #!/usr/local/bin/perl # Script to generate statistics from webperf.log # Written 11/10/97 Robert G. Ferrell # Revised: 11/13/97 RGF -- to do detailed statistics # 11/17/97 RGF -- Added Most Recent Excursion to Stats # 11/21/97 RGF -- Added user interface # 2/ 5/98 RGF -- Fixed $nconn undefined problem # 2/ 6/98 RGF -- Added user-configurable excursion time # 5/29/98 RGF -- Added connections/day stat # 6/ 2/98 RGF -- Added more Web use stats # 6/ 4/98 RGF -- Fixed divide-by-zero problem in calc_users # 3/15/99 RGF -- Adapted for public release # 9/21/99 RGF -- Some streamlining done ############### Turn off buffering to preserve fifo ############## $| = 1; print "Content-type: text/html\n\n"; ############### Initialize globals ############################### $n = 1; $exnum = 1; $xmax = 0; $xmin = 100; $cmax = 0; $cmin = 100; $ex = 0; $exc = 10; chop($cdate = `date`); $server = ""; #+# insert your Web server name $web_log = ""; #+# insert the path to your Webperf log $gets_log = ""; #+# insert path to your gets log $local_name = "mydomain.com"; #+# insert your local FQDN $get_index = ""; #+# insert path to index_log ############## Main subroutine out of habit ###################### &main; ########## Get user input and route accordingly ################## sub main { &get_data; } ########## Open log file ######################################## sub get_data { &print_html_header; &print_table_header; concat(LOG, $web_log) || die "Could not open webperf log"; while (defined($line = )) { ###### Use study() to speed up processing of repetitive reads ######### study ($line); #### Parse data fields in log file and assign beginning dates #### ($day,$mon,$date,$time,$tz,$year,$nmin,$min,$nsec,$sec,$status,$nstat,$connects,$nconn) = split(/ +/, $line); $graph_date = ("$date $mon $time"); if ($n == 1) { $fday = $day; $fmon = $mon; $fdate = $date; chop($fyear = $year); } ###### Check for comment lines in log file and skip them ############### if ($day =~ /^#/) { next; } ###### Check for excursion, increment, and determine last excursion #### if ($nsec > $exc) { $exnum++; $ex = 1; $lexday = $day; $lexmon = $mon; $lexdate = $date; chomp($lexyear = $year); $lextime = $time; $lexsec = $nsec; $lex_string = qq($lexday $lexmon $lexdate $lexyear $lextime, $lexsec secs); } else { $lex_string = qq(N/A); } ### Define terms for analysis ##### $xn = $nsec; if ($nconn) { $cn = $nconn; } else { $cn = 0; $nconn = 0; } $Xn = $xn / $n; $Cn = $cn / $n; $xt += $xn; $ct += $cn; $xdiffn = $xn - $Xn; $cdiffn = $cn - $Cn; $xdiffn2 = $xdiffn * $xdiffn; $cdiffn2 = $cdiffn * $cdiffn; $xdiff_t += $xdiffn2; $cdiff_t += $cdiffn2; $date_f = "$date $mon at $time"; if ($xn > $xmax) { $xmax = $xn; $xmax_date = $date_f; if ($xmax < 2) { $xmax_unit = qq(sec); } else { $xmax_unit = qq(secs); } $xmax = qq(<1) unless $xmax >= 1; } if ($xn < $xmin) { $xmin = $xn; $xmin_date = $date_f; if ($xmin < 2) { $xmin_unit = qq(sec); } else { $xmin_unit = qq(secs); } } if ($cn > $cmax) { $cmax = $cn; $cmax_date = $date_f; } if ($cn < $cmin) { $cmin = $cn; $cmin_date = $date_f; $cmin = 0 unless ($cmin); } $n++; &print_graphs; } ### Once we're through reading log, the last values are end of report period $lday = $day; $lmon = $mon; $ldate = $date; chomp($lyear = $year); $lconn = $nconn; close(LOG); &do_stats; } &print_stats; &print_html_footer; ### Calculate standard deviations and confidence intervals ############# sub do_stats { if ($xmin < 2) { $xsec = "sec"; } else { $xsec = "secs"; } $sec_int = int ($xt / $n); $sec_int = qq(<1) unless $sec_int >= 1; $sec_int_unit = qq(secs); if ($sec_int < 2) { $sec_int = qq(<1); $sec_int_unit = qq(sec); } $conn_int = int ($ct / $n); $ex_perc = ($exnum / $n) * 100; $experc_int = int ($ex_perc); &stddev; } sub stddev { $stddev_sec = int (sqrt ($xdiff_t / $n)); $stderr_sec = $stddev_sec / (sqrt ($n)); $stddev_conn = int (sqrt ($cdiff_t / $n)); $stderr_conn = $stddev_conn / (sqrt ($n)); if (($stderr_sec < 1) && ($stderr_sec > 0)) { $stderr_sec = qq(0) . "." . int ($stderr_sec * 100); } elsif ($stderr_sec == 0) { $stderr_sec = 0; } if ($stderr_conn < 1) { $stderr_conn = qq(0) . "." . int ($stderr_conn * 100); } $sig_sec = 3 * $stderr_sec; $sig_conn = 3 * $stderr_conn; } #### Generate graphical output in HTML #################################### sub print_html_header { print <<"EOP"; Web Server Performance Monitor Results

Status Report for Server $server

EOP } sub print_stats { print <<"EOP";

This report covers the period from $fday $fmon $fdate, $fyear to $lday $lmon $ldate, $lyear on server $server

Web Server Statistical Report for $cdate
Web Server Performance Statistics
Total number of observations: $n Avg time to download index.html: $sec_int secs
Avg number of concurrent HTTP connections: $conn_int Current HTTP connections: $lconn
Download times
Max: $xmax secs on $xmax_date Min: $xmin $xsec on $xmin_date
Concurrent connections
Max: $cmax on $cmax_date Min: $cmin on $cmin_date
Excursions (time to download > 10 secs)
Total: $exnum Most recent: $lexday $lexmon $lexdate $lexyear $lextime
$lexsec secs
Percentage of excursions to total observations: $experc_int\%
Standard Errors
Download time: +/- $stderr_sec Connections: +/- $stderr_conn
95% Confidence Interval for mean download time: $sec_int +/- $sig_sec secs
95% Confidence Interval for mean # of connections: $conn_int +/- $sig_conn

Website Visitor Statistics
Average HTTP requests/day: $hits_day
Average requests per connection: $req_conn
Adjusted Hits/Day (discrete visits): $hits_adj
Percentage of traffic from local hosts: $local_hits_perc%
Percentage of traffic probably originating from browser startup: $local_home_perc% ($local_home_day/day)
Percentage of external visitors entering through main page: $front_door_perc% ($front_door_day/day)
EOP } sub calc_users { $hits = qx(grep -c ' GET' $web_log); $gets_dates = qx(grep ' GET' $web_log > $gets_log); $get_index = qx(grep -i 'index." $web_log > $index_log); $local_hits = qx(grep -ic $local_name $web_log); $index_int = qx(grep -c '$local_name' $index_log); $index_ext = qx(grep -cv '$local_name' $index_log); $lineno = 1; concat(DATES, $gets_log) || die &panic_dates; while(defined($line = )) { ($user,$d1,$d2,$date_info,$rest) = split(/ /, $line, 5); $date_info =~ s/\[//; ($rdate,$remains) = split(/:/, $date_info, 2); ($rday,$rmon,$ryr) = split(/\//, $rdate); if ($lineno == 1) { $day1 = $rday; $mon1 = $rmon; $yr1 = $ryr; } else { $day2 = $rday; $mon2 = $rmon; $yr2 = $ryr; } $lineno++; } close(DATES); if (($mon1 eq $mon2) && ($yr1 == $yr2)) { $report_days = $day2 - $day1; } elsif (($yr1 == $yr2) || ($yr2 - $yr1 == 1)) { if (($mon1 eq "Apr") || ($mon1 eq "Jun") || ($mon1 = "Sep")) { $day2 += 30; $report_days = $day2 - $day1; } elsif ($mon1 eq "Feb") { if ($yr1%4 == 0) { $day2 += 29; $report_days = $day2 - $day1; } else { $day2 += 28; $report_days = $day2 - $day1; } } else { $day2 += 31; $report_days = $day2 - $day1; } } else { $date_error = "Error in log dates."; } if (defined($date_error)) { $hits_day = $date_error; } else { $hits_day = int ($hits / $report_days); $req_conn = int ($hits_day / ($conn_int * 192)); $hits_adj = int ($hits_day / $req_conn); $local_hits_perc = int (($local_hits / $hits) * 100); if ($local_hits == 0) { $local_home_perc = 0; } else { $local_home_perc = int (($index_int / $local_hits) * 100); } $usgs_home_day = int ($index_int / $report_days); $front_door_perc = int (($index_ext / $hits) * 100); $front_door_day = int ($index_ext / $report_days); if ($local_home_perc < 1) { $local_home_perc = "\< 1"; } if ($front_door_perc < 1) { $front_door_perc = "\< 1"; } } } sub print_html_footer { print <<"EOP"; EOP } sub print_table_header { print <<"EOP";

Web Server Performance and Website Visitor Statistics

EOP } sub panic_dates { print "

Can't open $gets_log!"; &print_html_footer; }