#!/usr/bin/perl -w use strict; use English; my $ECHOLOT_BASE = shift @ARGV; die ("Usage: $PROGRAM_NAME \n") if (!defined $ECHOLOT_BASE || scalar @ARGV > 0); my $HOSTNAME = `hostname`; my $INDEX = $ECHOLOT_BASE.'/results/thesaurus/index.txt'; my $STATSDIR = $ECHOLOT_BASE.'/data'; my $AUTORANGE = 'ploticus/plot-autorange.pls'; my $SAMERANGE = 'ploticus/plot-samerange.pls'; my $SAMERANGESMALL = 'ploticus/plot-samerange-small.pls'; my $DOTS_AUTORANGE = 'ploticus/plot-dots-autorange.pls'; my $DOTS_SAMERANGE = 'ploticus/plot-dots-samerange.pls'; my $DOTS_SAMERANGESMALL = 'ploticus/plot-dots-samerange-small.pls'; my $OUTDIR = 'result'; my $OUTINDEX = 'result/index.html'; my $OUTSTATS = 'result/stats.txt'; my $TMP = 'tmp'; my $NOW = time; my $GMTIME = gmtime($NOW); #my $IMG_URL = 'http://images.noreply.org/latency/'; my $IMG_URL = ''; my $VERBOSE = 0; my $PLOTICUS = 'ploticus'; my $IDENTIFY = 'identify'; opendir(DIR, $STATSDIR) or die ("Cannot open $STATSDIR: $!\n"); my @FILES = readdir(DIR); closedir(DIR); sub getsize($) { my ($fn) = @_; open (FH, "$IDENTIFY $fn|") or die ("Cannot call $IDENTIFY: $!\n"); my $l = ; close FH; unless (defined $l) { warn ("Cannot identify $fn\n"); return {x => 0, y => 0}; }; my ($x, $y) = $l =~ /(\d+)x(\d+)/; return {x => $x, y=> $y}; }; open(STATS, '>'.$OUTSTATS) or die ("Cannot open $OUTSTATS: $!\n"); print STATS "node median mean stddev\n"; my %remailers; open (INDEX, $INDEX) or die("Cannot open $INDEX: $!\n"); while () { my ($nick, $id, $address) = split (/\s+/,$_); my @address = quotemeta($address); my @files = grep {/^$address\..*\.done$/} @FILES; my @lines; for my $file (@files) { open(F, $STATSDIR.'/'.$file) or warn("Cannot open $STATSDIR/$file: $!\n"), next; push @lines, map {chomp; $_} ; close(F); }; my $count = scalar @lines; unless ($count) { warn("No data for $address\n") if ($VERBOSE); next; }; my $sum = 0; my @values = sort { $a <=> $b } map { my @tmp = split; $tmp[1] /= 60; $sum += $tmp[1]; $tmp[1]; } @lines; my $mean = $sum / $count; my $median = ($count % 2 == 0) ? ($values[$count/2 - 1] + $values[$count/2])/2 : $values[$count/2]; my @points = map { my @tmp = split; $tmp[0] = ($tmp[0]-$NOW)/(60*60*24); $tmp[1] /= 60; $tmp[0].' '.$tmp[1] } @lines; my $sum_delta = 0; for (@values) { my $tmp = $_ - $mean; $sum_delta += $tmp * $tmp }; my $stddev = sqrt( $sum_delta / $count ); open (STUBS, ">$TMP/stubs") or warn ("Cannot open $TMP/stubs: $!\n"), next; print STUBS "$mean mean\n"; print STUBS "$median median\n"; close STUBS; open (VALUES, ">$TMP/values") or warn ("Cannot open $TMP/values: $!\n"), next; print VALUES "$_\n" for @values; close VALUES; open (POINTS, ">$TMP/points") or warn ("Cannot open $TMP/points $!\n"), next; print POINTS "$_\n" for @points; close POINTS; my $autorange = $nick.'-autorange.png'; my $samerange = $nick.'-samerange.png'; my $samerangesmall = $nick.'-samerange.small.png'; system($PLOTICUS, '-o', $OUTDIR.'/'.$autorange, '-png', '-scale', '1.0,1.0', $AUTORANGE); system($PLOTICUS, '-o', $OUTDIR.'/'.$samerange, '-png', '-scale', '1.0,1.0', $SAMERANGE); system($PLOTICUS, '-o', $OUTDIR.'/'.$samerangesmall, '-png', '-scale', '1.0,1.0', $SAMERANGESMALL); my $dots_autorange = $nick.'-dots-autorange.png'; my $dots_samerange = $nick.'-dots-samerange.png'; my $dots_samerangesmall = $nick.'-dots-samerange.small.png'; system($PLOTICUS, '-o', $OUTDIR.'/'.$dots_autorange, '-png', '-scale', '1.0,1.0', $DOTS_AUTORANGE); system($PLOTICUS, '-o', $OUTDIR.'/'.$dots_samerange, '-png', '-scale', '1.0,1.0', $DOTS_SAMERANGE); system($PLOTICUS, '-o', $OUTDIR.'/'.$dots_samerangesmall, '-png', '-scale', '1.0,1.0', $DOTS_SAMERANGESMALL); $remailers{$address} = { address => $address, nick => $nick, median => $median, mean => $mean, stddev => $stddev, samerange => $samerange, autorange => $autorange, samerangesmall => $samerangesmall, dots_samerange => $dots_samerange, dots_autorange => $dots_autorange, dots_samerangesmall => $dots_samerangesmall, samerange_size => getsize($OUTDIR.'/'.$samerange), autorange_size => getsize($OUTDIR.'/'.$autorange), samerangesmall_size => getsize($OUTDIR.'/'.$samerangesmall), dots_samerange_size => getsize($OUTDIR.'/'.$dots_samerange), dots_autorange_size => getsize($OUTDIR.'/'.$dots_autorange), dots_samerangesmall_size => getsize($OUTDIR.'/'.$dots_samerangesmall), }; printf STATS "%s %6.0f %6.0f %6.0f\n", $nick, $median, $mean, $stddev; } close(INDEX); close(STATS); my $index; my $body; for my $remailer (sort { $remailers{$a}->{'nick'} cmp $remailers{$b}->{'nick'}} keys %remailers) { my $nick = $remailers{$remailer}->{'nick'}; my $address = $remailers{$remailer}->{'address'}; my $median = $remailers{$remailer}->{'median'}; my $mean = $remailers{$remailer}->{'mean'}; my $stddev = $remailers{$remailer}->{'stddev'}; my $autorange = $remailers{$remailer}->{'autorange'}; my $samerange = $remailers{$remailer}->{'samerange'}; my $samerangesmall = $remailers{$remailer}->{'samerangesmall'}; my $dots_autorange = $remailers{$remailer}->{'dots_autorange'}; my $dots_samerange = $remailers{$remailer}->{'dots_samerange'}; my $dots_samerangesmall = $remailers{$remailer}->{'dots_samerangesmall'}; my $autorange_size = $remailers{$remailer}->{'autorange_size'}; my $samerange_size = $remailers{$remailer}->{'samerange_size'}; my $samerangesmall_size = $remailers{$remailer}->{'samerangesmall_size'}; my $dots_autorange_size = $remailers{$remailer}->{'dots_autorange_size'}; my $dots_samerange_size = $remailers{$remailer}->{'dots_samerange_size'}; my $dots_samerangesmall_size = $remailers{$remailer}->{'dots_samerangesmall_size'}; $index .= "
  • $nick <$address>
  • \n"; $body .= "

    $nick <$address>

    \n

    \n"; $body .= "{'x'}\" height=\"$samerangesmall_size->{'y'}\">\n"; $body .= "{'x'}\" height=\"$dots_samerangesmall_size->{'y'}\">\n"; $body .= "
    Larger images and images with adapted scales.

    "; open (F, '>'.$OUTDIR.'/'.$nick.'.html') or die ("Cannot open $OUTDIR/$nick.html: $!\n"); print F "Latency Stats for $nick\n"; print F "

    Latency Stats for $nick

    \n"; print F "index
    \n"; print F "

    \n"; printf F "Median: %6.0f minutes
    \n", $median; printf F "Arithmetic Mean: %6.0f minutes
    \n", $mean; printf F "Standard Deviation from Mean: %6.0f minutes
    \n", $stddev; print F "\n"; print F "\n"; print F "\n"; print F "
    {'x'}\" height=\"$samerange_size->{'y'}\">". "{'x'}\" height=\"$dots_samerange_size->{'y'}\">
    {'x'}\" height=\"$autorange_size->{'y'}\">" . "{'x'}\" height=\"$dots_autorange_size->{'y'}\">
    \n"; print F "


    \nBuilt at $GMTIME on $HOSTNAME
    \n"; print F "Peter Palfrader <web\@palfrader.org>\n"; print F "\n"; } open (F, '>'.$OUTINDEX) or die ("Cannot open $OUTINDEX: $!\n"); print F "Latencies\n"; print F "

    Latency Stats

    \n"; print F "..
    \n"; #print F "
      $index
    \n"; print F "$body\n"; print F "


    \n"; print F 'Images created with Steve Grubb\'s ploticus'."\n"; print F "
    \nBuilt at $GMTIME on $HOSTNAME
    \n"; print F "Peter Palfrader <web\@palfrader.org>\n"; print F "\n"; close (F);