analy2.in 3.82 KB
Newer Older
1
#!/usr/bin/perl
2 3
#
# Copyright (c) 2009 University of Utah and the Flux Group.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
23
#
24 25 26 27 28 29 30 31

use Data::Dumper;
use POSIX 'strftime','mktime';

use strict;
use warnings;
no warnings 'uninitialized';

32 33 34 35
our (@to_plot);
require "@prefix@/etc/node_usage.conf";

chdir "@prefix@/data/node_usage";
36 37 38

my $TOLERANCE_INTERVAL = 1/3;

39 40
my @idxs = (0 .. (@to_plot * 2 - 1));

41 42 43 44
my %res;

sub tally ($$@) {
    my ($str, $what, @d) = @_;
45 46 47 48 49
    foreach my $i (@idxs) {
	if ($d[$i] != $d[$i]) { # ie NaN
	    $res{$what}{data}{$str}{invalid}[$i]++;
	} else {
	    $res{$what}{data}{$str}{count}[$i]++;
50 51 52 53 54 55 56
	    $res{$what}{data}{$str}{data}[$i] += $d[$i];
	}
    }
}

sub tally_mod ($$@) {
    my ($bin, $what, @d) = @_;
57
    foreach my $i (@idxs) {
58 59
	next if $d[$i] != $d[$i]; # ie NaN
	$res{$what}{data}[$bin]{count}[$i]++;
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
	$res{$what}{data}[$bin]{data}[$i] += $d[$i];
    }
}

open F, "node_usage-hourly.dat" or die;

$res{hourly_last2weeks} = {type=>'normal'};
$res{daily_last2months} = {type=>'normal'};
$res{daily} = {type=>'normal'};
$res{weekly} = {type=>'normal'};
$res{monthly} = {type=>'normal'};
$res{yearly} = {type=>'normal'};
$res{by_hour} = {type=>'mod'};
$res{by_dayofweek} = {type=>'mod'};
$res{by_hourofweek} = {type=>'mod',div=>24};
$res{by_month} = {type=>'mod'};

my @now = localtime();
my $hourly_start = mktime(0, 0, 0, $now[3]-14, $now[4], $now[5]);
my $daily_start = mktime(0, 0, 0, $now[3], $now[4]-2, $now[5]);

while (<F>) {
    chop;
    my @d = split / /;
    my $time = shift @d;
    my @time = localtime($time);
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = @time;
    #next unless $year + 1900 == 2009;
    my $wday_m = ($wday - 1) % 7;
    tally(strftime("%Y-%m-%d_%R", @time), 'hourly_last2weeks', @d)
	if ($time >= $hourly_start);
    tally(strftime("%Y-%m-%d", @time), 'daily_last2months', @d)
	if ($time >= $daily_start);
    tally(strftime("%Y-%m-%d", @time), 'daily', @d);
    tally(strftime("%Y-%m-%d", $sec,$min,$hour,$mday-$wday_m,$mon,$year), 'weekly', @d);
    tally(strftime("%Y-%m", @time), 'monthly', @d);
    tally(strftime("%Y", @time), 'yearly', @d);
    tally_mod($hour,'by_hour', @d);
    tally_mod($wday_m,'by_dayofweek', @d);
    tally_mod($wday_m*24+$hour,'by_hourofweek', @d);
    tally_mod($mon, 'by_month', @d);
}

foreach my $k (keys %res) {

    open F, ">node_usage-$k.dat";

    if ($res{$k}{type} eq 'normal') {
	foreach my $i (sort keys %{$res{$k}{data}}) {
	    my @r;
	    my $d = $res{$k}{data}{$i};
111 112 113 114 115 116
	    foreach my $j (@idxs) {
		my $invalid = $d->{invalid}[$j];
		my $count = $d->{count}[$j];
		if ($invalid / ($invalid + $count) > $TOLERANCE_INTERVAL) {
		    $r[$j] = 'NaN';
		} else {
117
		    $r[$j] = $d->{data}[$j]/$count;
118
		    die "Unexpected NaN" if $r[$j] != $r[$j];
119 120
		}
	    }
121
	    print F join(' ', "$i ", map {sprintf("%5.1f", $_)} @r),"\n" 
122 123 124 125 126 127 128
	}
    } else {
	my $div = $res{$k}{div};
	$div = 1 unless defined $res{$k}{div};
	foreach my $i (0 .. $#{$res{$k}{data}}) {
	    my @r;
	    my $d = $res{$k}{data}[$i];
129
	    foreach my $j (@idxs) {
130
		$r[$j] = $d->{data}[$j] ? $d->{data}[$j]/$d->{count}[$j] : 0;
131
	    }
132
	    print F join(' ', sprintf("%6.3f ", $i/$div), map {sprintf("%5.1f", $_)} @r),"\n" 
133 134 135
	}
    }
}